void TtfFontList::LoadAll() { if(loaded) return; for(const std::string &font : GetFontFiles()) { TtfFont tf = {}; tf.fontFile = font; if(tf.LoadFromFile(fontLibrary)) l.Add(&tf); } // Sort fonts according to their actual name, not filename. std::sort(&l.elem[0], &l.elem[l.n], [](const TtfFont &a, const TtfFont &b) { return a.name < b.name; }); // Filter out fonts with the same family and style name. This is not // strictly necessarily the exact same font, but it will almost always be. TtfFont *it = std::unique(&l.elem[0], &l.elem[l.n], [](const TtfFont &a, const TtfFont &b) { return a.name == b.name; }); l.RemoveLast(&l.elem[l.n] - it); // TODO: identify fonts by their name and not filename, which may change // between OSes. loaded = true; }
void TtfFontList::PlotString(const std::string &font, const std::string &str, SBezierList *sbl, Vector origin, Vector u, Vector v) { LoadAll(); TtfFont *tf = std::find_if(&l.elem[0], &l.elem[l.n], [&](const TtfFont &tf) { return tf.FontFileBaseName() == font; }); if(!str.empty() && tf != &l.elem[l.n]) { tf->LoadFromFile(fontLibrary, /*nameOnly=*/false); tf->PlotString(str, sbl, origin, u, v); } else { // No text or no font; so draw a big X for an error marker. SBezier sb; sb = SBezier::From(origin, origin.Plus(u).Plus(v)); sbl->l.Add(&sb); sb = SBezier::From(origin.Plus(v), origin.Plus(u)); sbl->l.Add(&sb); } }