version 2.8
importtools.cc
1 #include "importtools.hh"
2 #include <limits>
3 
4 namespace mcufont {
5 
6 void eliminate_duplicates(std::vector<DataFile::glyphentry_t> &glyphtable)
7 {
8  for (size_t i = 0; i + 1 < glyphtable.size(); i++)
9  {
10  for (size_t j = i + 1; j < glyphtable.size(); j++)
11  {
12  if (glyphtable.at(i).data == glyphtable.at(j).data &&
13  glyphtable.at(i).width == glyphtable.at(j).width)
14  {
15  for (int c : glyphtable.at(j).chars)
16  glyphtable.at(i).chars.push_back(c);
17 
18  glyphtable.erase(glyphtable.begin() + j);
19  j--;
20  }
21  }
22  }
23 }
24 
25 struct bbox_t
26 {
27  int left;
28  int top;
29  int right;
30  int bottom;
31 
32  bbox_t()
33  {
34  left = std::numeric_limits<int>::max();
35  top = std::numeric_limits<int>::max();
36  right = std::numeric_limits<int>::min();
37  bottom = std::numeric_limits<int>::min();
38  }
39 
40  void update(int x, int y)
41  {
42  if (x < left) left = x;
43  if (x > right) right = x;
44  if (y < top) top = y;
45  if (y > bottom) bottom = y;
46  }
47 };
48 
49 void crop_glyphs(std::vector<DataFile::glyphentry_t> &glyphtable,
50  DataFile::fontinfo_t &fontinfo)
51 {
52  // Find out the maximum bounding box
53  bbox_t bbox;
54  for (DataFile::glyphentry_t &glyph : glyphtable)
55  {
56  if (glyph.data.size() == 0)
57  continue; // Dummy glyph
58 
59  for (int y = 0; y < fontinfo.max_height; y++)
60  {
61  for (int x = 0; x < fontinfo.max_width; x++)
62  {
63  if (glyph.data.at(y * fontinfo.max_width + x))
64  bbox.update(x, y);
65  }
66  }
67  }
68 
69  if (bbox.right < bbox.left)
70  return; // There were no glyphs
71 
72  // Crop the glyphs to that
73  size_t old_w = fontinfo.max_width;
74  size_t new_w = bbox.right - bbox.left + 1;
75  size_t new_h = bbox.bottom - bbox.top + 1;
76  for (DataFile::glyphentry_t &glyph : glyphtable)
77  {
78  if (glyph.data.size() == 0)
79  continue; // Dummy glyph
80 
81  DataFile::pixels_t old = glyph.data;
82  glyph.data.clear();
83 
84  for (size_t y = 0; y < new_h; y++)
85  {
86  for (size_t x = 0; x < new_w; x++)
87  {
88  size_t old_x = bbox.left + x;
89  size_t old_y = bbox.top + y;
90  size_t old_pos = old_w * old_y + old_x;
91  glyph.data.push_back(old.at(old_pos));
92  }
93  }
94  }
95 
96  fontinfo.max_width = new_w;
97  fontinfo.max_height = new_h;
98  fontinfo.baseline_x -= bbox.left;
99  fontinfo.baseline_y -= bbox.top;
100 }
101 
102 void detect_flags(const std::vector<DataFile::glyphentry_t> &glyphtable,
103  DataFile::fontinfo_t &fontinfo)
104 {
105  if (!glyphtable.size())
106  return;
107 
108  // Check if all glyphs have equal width
109  int width = glyphtable[0].width;
110  bool is_monospace = true;
111  for (const DataFile::glyphentry_t &g : glyphtable)
112  {
113  if (g.width != width)
114  {
115  is_monospace = false;
116  break;
117  }
118  }
119 
120  if (is_monospace)
121  fontinfo.flags |= DataFile::FLAG_MONOSPACE;
122 
123  // Check if all glyphs contain only 0 or 15 alpha
124  bool is_bw = true;
125  for (const DataFile::glyphentry_t &g : glyphtable)
126  {
127  for (uint8_t pixel : g.data)
128  {
129  if (pixel != 0 && pixel != 15)
130  {
131  is_bw = false;
132  break;
133  }
134  }
135  if (!is_bw) break;
136  }
137 
138  if (is_bw)
139  fontinfo.flags |= DataFile::FLAG_BW;
140 }
141 
142 
143 }