FontSupport::FontMatch FontSupport::matchFont(const WFont& f) const { for (MatchCache::iterator i = cache_.begin(); i != cache_.end(); ++i) { if (i->font == f) { cache_.splice(cache_.begin(), cache_, i); // implement LRU return FontMatch(i->match, i->desc); } } PANGO_LOCK; enabledFontFormats = enabledFontFormats_; PangoFontDescription *desc = createFontDescription(f); PangoFont *match = pango_font_map_load_font(pangoFontMap, context_, desc); pango_context_set_font_description(context_, desc); // for layoutText() if (cache_.back().match) { g_object_unref(cache_.back().match); pango_font_description_free(cache_.back().desc); } cache_.pop_back(); cache_.push_front(Matched(f, match, desc)); return FontMatch(match, desc); }
FontSupport::FontMatch FontSupport::matchFont(const WFont& f) const { if (wtFont_ == f) return FontMatch(matchFont_); wtFont_ = f; PANGO_LOCK; PangoFontDescription *desc = createFontDescription(f); if (matchFont_) g_object_unref(matchFont_); matchFont_ = pango_font_map_load_font(pangoFontMap, context_, desc); pango_font_description_free(desc); return FontMatch(matchFont_); }
void FontSupport::matchFont(const WFont& font, const std::vector<std::string>& fontNames, const std::string& path, FontMatch& match) const { if (boost::ends_with(path, ".ttf") || boost::ends_with(path, ".ttc")) { std::string name = Utils::lowerCase(FileUtils::leaf(path)); name = name.substr(0, name.length() - 4); Utils::replace(name, ' ', std::string()); std::vector<const char*> weightVariants, styleVariants; if (font.weight() == WFont::Bold) { weightVariants.push_back("bold"); weightVariants.push_back("bf"); } else { weightVariants.push_back(""); } switch (font.style()) { case WFont::NormalStyle: styleVariants.push_back("regular"); styleVariants.push_back(""); break; case WFont::Italic: styleVariants.push_back("italic"); styleVariants.push_back("oblique"); break; case WFont::Oblique: styleVariants.push_back("oblique"); break; } for (unsigned i = 0; i < fontNames.size(); ++i) { double q = 1.0 - 0.1 * i; if (q <= match.quality()) return; for (unsigned w = 0; w < weightVariants.size(); ++w) for (unsigned s = 0; s < styleVariants.size(); ++s) { std::string fn = fontNames[i] + weightVariants[w] + styleVariants[s]; if (fn == name) { match = FontMatch(path, q); return; } } } } }
FontSupport::FontMatch FontSupport::matchFont(const WFont& font, const std::string& directory, bool recursive) const { if (!FileUtils::exists(directory) || !FileUtils::isDirectory(directory)) { LOG_ERROR("cannot read directory '" << directory << "'"); return FontMatch(); } std::vector<std::string> fontNames; std::string families = font.specificFamilies().toUTF8(); boost::split(fontNames, families, boost::is_any_of(",")); for (unsigned i = 0; i < fontNames.size(); ++i) { std::string s = Utils::lowerCase(fontNames[i]); // UTF-8 ! boost::trim_if(s, boost::is_any_of("\"'")); s = Utils::replace(s, ' ', std::string()); fontNames[i] = s; } switch (font.genericFamily()) { case WFont::Serif: fontNames.push_back("times"); fontNames.push_back("timesnewroman"); break; case WFont::SansSerif: fontNames.push_back("helvetica"); fontNames.push_back("arialunicode"); fontNames.push_back("arial"); fontNames.push_back("verdana"); break; case WFont::Cursive: fontNames.push_back("zapfchancery"); break; case WFont::Fantasy: fontNames.push_back("western"); break; case WFont::Monospace: fontNames.push_back("courier"); fontNames.push_back("mscouriernew"); break; default: ; } FontMatch match; matchFont(font, fontNames, directory, recursive, match); return match; }