143 lines
3.6 KiB
C++
143 lines
3.6 KiB
C++
#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)
|
|
{
|
|
if (glyph.data.size() == 0)
|
|
continue; // Dummy glyph
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bbox.right < bbox.left)
|
|
return; // There were no glyphs
|
|
|
|
// 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)
|
|
{
|
|
if (glyph.data.size() == 0)
|
|
continue; // Dummy glyph
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
}
|