diff options
Diffstat (limited to 'tools/mcufontencoder/src/importtools.cc')
-rw-r--r-- | tools/mcufontencoder/src/importtools.cc | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/tools/mcufontencoder/src/importtools.cc b/tools/mcufontencoder/src/importtools.cc new file mode 100644 index 00000000..c219c207 --- /dev/null +++ b/tools/mcufontencoder/src/importtools.cc @@ -0,0 +1,134 @@ +#include "importtools.hh" +#include <limits> + +namespace mcufont { + +void eliminate_duplicates(std::vector<DataFile::glyphentry_t> &glyphtable) +{ + for (size_t i = 0; i + 1 < glyphtable.size(); i++) + { + for (size_t j = i + 1; j < glyphtable.size(); j++) + { + if (glyphtable.at(i).data == glyphtable.at(j).data && + glyphtable.at(i).width == glyphtable.at(j).width) + { + for (int c : glyphtable.at(j).chars) + glyphtable.at(i).chars.push_back(c); + + glyphtable.erase(glyphtable.begin() + j); + j--; + } + } + } +} + +struct bbox_t +{ + int left; + int top; + int right; + int bottom; + + bbox_t() + { + left = std::numeric_limits<int>::max(); + top = std::numeric_limits<int>::max(); + right = std::numeric_limits<int>::min(); + bottom = std::numeric_limits<int>::min(); + } + + void update(int x, int y) + { + if (x < left) left = x; + if (x > right) right = x; + if (y < top) top = y; + if (y > bottom) bottom = y; + } +}; + +void crop_glyphs(std::vector<DataFile::glyphentry_t> &glyphtable, + DataFile::fontinfo_t &fontinfo) +{ + // Find out the maximum bounding box + bbox_t bbox; + for (DataFile::glyphentry_t &glyph : glyphtable) + { + for (int y = 0; y < fontinfo.max_height; y++) + { + for (int x = 0; x < fontinfo.max_width; x++) + { + if (glyph.data.at(y * fontinfo.max_width + x)) + bbox.update(x, y); + } + } + } + + // Crop the glyphs to that + size_t old_w = fontinfo.max_width; + size_t new_w = bbox.right - bbox.left + 1; + size_t new_h = bbox.bottom - bbox.top + 1; + for (DataFile::glyphentry_t &glyph : glyphtable) + { + DataFile::pixels_t old = glyph.data; + glyph.data.clear(); + + for (size_t y = 0; y < new_h; y++) + { + for (size_t x = 0; x < new_w; x++) + { + size_t old_x = bbox.left + x; + size_t old_y = bbox.top + y; + size_t old_pos = old_w * old_y + old_x; + glyph.data.push_back(old.at(old_pos)); + } + } + } + + fontinfo.max_width = new_w; + fontinfo.max_height = new_h; + fontinfo.baseline_x -= bbox.left; + fontinfo.baseline_y -= bbox.top; +} + +void detect_flags(const std::vector<DataFile::glyphentry_t> &glyphtable, + DataFile::fontinfo_t &fontinfo) +{ + if (!glyphtable.size()) + return; + + // Check if all glyphs have equal width + int width = glyphtable[0].width; + bool is_monospace = true; + for (const DataFile::glyphentry_t &g : glyphtable) + { + if (g.width != width) + { + is_monospace = false; + break; + } + } + + if (is_monospace) + fontinfo.flags |= DataFile::FLAG_MONOSPACE; + + // Check if all glyphs contain only 0 or 15 alpha + bool is_bw = true; + for (const DataFile::glyphentry_t &g : glyphtable) + { + for (uint8_t pixel : g.data) + { + if (pixel != 0 && pixel != 15) + { + is_bw = false; + break; + } + } + if (!is_bw) break; + } + + if (is_bw) + fontinfo.flags |= DataFile::FLAG_BW; +} + + +} |