Add a warning in the fontconfig font collector when the chosen font does not have glyphs for some of the characters used in that font

Originally committed to SVN as r6417.
This commit is contained in:
Thomas Goyne 2012-02-01 04:17:33 +00:00
parent 98b51e2c23
commit db7924d646
6 changed files with 36 additions and 21 deletions

View File

@ -47,17 +47,11 @@ void FontCollector::ProcessDialogueLine(AssDialogue *line) {
if (line->Comment) return;
line->ParseASSTags();
bool text = false;
StyleInfo style = styles[line->Style];
StyleInfo initial = style;
for (size_t i = 0; i < line->Blocks.size(); ++i) {
if (AssDialogueBlockOverride *ovr = dynamic_cast<AssDialogueBlockOverride *>(line->Blocks[i])) {
if (text) {
used_styles.insert(style);
text = false;
}
for (size_t j = 0; j < ovr->Tags.size(); ++j) {
AssOverrideTag *tag = ovr->Tags[j];
wxString name = tag->Name;
@ -75,26 +69,29 @@ void FontCollector::ProcessDialogueLine(AssDialogue *line) {
}
}
else if (AssDialogueBlockPlain *txt = dynamic_cast<AssDialogueBlockPlain *>(line->Blocks[i])) {
text = text || !txt->GetText().empty();
wxString text = txt->GetText();
if (text.size()) {
std::set<wxUniChar>& chars = used_styles[style];
for (size_t i = 0; i < text.size(); ++i)
chars.insert(text[i]);
}
}
// Do nothing with drawing blocks
}
if (text)
used_styles.insert(style);
line->ClearBlocks();
}
void FontCollector::ProcessChunk(StyleInfo const& style) {
std::vector<wxString> paths = lister.GetFontPaths(style.facename, style.bold, style.italic);
void FontCollector::ProcessChunk(std::pair<StyleInfo, std::set<wxUniChar> > const& style) {
std::vector<wxString> paths = lister.GetFontPaths(style.first.facename, style.first.bold, style.first.italic, style.second);
if (paths.empty()) {
status_callback(wxString::Format("Could not find font '%s'\n", style.facename), 2);
status_callback(wxString::Format("Could not find font '%s'\n", style.first.facename), 2);
++missing;
}
else {
for (size_t i = 0; i < paths.size(); ++i) {
if (results.insert(paths[i]).second)
status_callback(wxString::Format("Found '%s' at '%s'\n", style.facename, paths[i]), 0);
status_callback(wxString::Format("Found '%s' at '%s'\n", style.first.facename, paths[i]), 0);
}
}
}

View File

@ -46,8 +46,9 @@ public:
/// @param facename Name of font face
/// @param bold ASS font weight
/// @param italic Italic?
/// @param characters Characters in this style
/// @return Path to the matching font file(s), or empty if not found
virtual std::vector<wxString> GetFontPaths(wxString const& facename, int bold, bool italic) = 0;
virtual std::vector<wxString> GetFontPaths(wxString const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) = 0;
};
/// @class FontCollector
@ -65,8 +66,8 @@ class FontCollector {
/// The actual lister to use to get font paths
FontFileLister &lister;
/// A set of each combination of styles used in the file
std::set<StyleInfo> used_styles;
/// The set of all glyphs used in the file
std::map<StyleInfo, std::set<wxUniChar> > used_styles;
/// Style name -> ASS style definition
std::map<wxString, StyleInfo> styles;
/// Paths to found required font files
@ -77,7 +78,7 @@ class FontCollector {
/// Gather all of the unique styles with text on a line
void ProcessDialogueLine(AssDialogue *line);
/// Get the font for a single style
void ProcessChunk(StyleInfo const& style);
void ProcessChunk(std::pair<StyleInfo, std::set<wxUniChar> > const& style);
public:
/// Constructor

View File

@ -71,6 +71,7 @@ namespace {
FontConfigFontFileLister::FontConfigFontFileLister(FontCollectorStatusCallback cb)
: config(FcInitLoadConfig(), FcConfigDestroy)
, cb(cb)
{
cb(_("Updating font cache\n"), 0);
FcConfigBuildFonts(config);
@ -112,7 +113,7 @@ FcFontSet *FontConfigFontFileLister::MatchFullname(const char *family, int weigh
return result;
}
std::vector<wxString> FontConfigFontFileLister::GetFontPaths(wxString const& facename, int bold, bool italic) {
std::vector<wxString> FontConfigFontFileLister::GetFontPaths(wxString const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) {
std::vector<wxString> ret;
std::string family = STD_STR(facename);
@ -187,6 +188,21 @@ std::vector<wxString> FontConfigFontFileLister::GetFontPaths(wxString const& fac
if(FcPatternGetString(rpat, FC_FILE, 0, &file) != FcResultMatch)
return ret;
wxString missing;
FcCharSet *charset;
if (FcPatternGetCharSet(rpat, FC_CHARSET, 0, &charset) == FcResultMatch) {
for (std::set<wxUniChar>::const_iterator it = characters.begin(); it != characters.end(); ++it) {
if (!FcCharSetHasChar(charset, *it))
missing += *it;
}
}
if (missing.size() > 50)
cb(wxString::Format(_("'%s' is missing %d glyphs used.\n"), facename, (int)missing.size()), 2);
else if (missing.size() > 0)
cb(wxString::Format(_("'%s' is missing the following glyphs used: %s\n"), facename, missing), 2);
ret.push_back((const char *)file);
return ret;
}

View File

@ -42,6 +42,7 @@ class FontConfigFontFileLister : public FontFileLister {
};
scoped<FcConfig*> config;
FontCollectorStatusCallback cb;
/// @brief Case-insensitive match ASS/SSA font family against full name. (also known as "name for humans")
/// @param family font fullname
@ -54,7 +55,7 @@ public:
/// @param cb Callback for status logging
FontConfigFontFileLister(FontCollectorStatusCallback cb);
std::vector<wxString> GetFontPaths(wxString const& facename, int bold, bool italic);
std::vector<wxString> GetFontPaths(wxString const& facename, int bold, bool italic, std::set<wxUniChar> const& characters);
};
#endif

View File

@ -171,7 +171,7 @@ void FreetypeFontFileLister::AddFont(wxString const& filename, wxString const& f
AddFont(filename, "*" + family);
}
std::vector<wxString> FreetypeFontFileLister::GetFontPaths(wxString const& facename, int, bool) {
std::vector<wxString> FreetypeFontFileLister::GetFontPaths(wxString const& facename, int, bool, std::set<wxUniChar> const&) {
std::vector<wxString> ret;
ret.insert(ret.end(), font_files[facename].begin(), font_files[facename].end());
if (ret.empty())

View File

@ -57,7 +57,7 @@ public:
/// @param cb Callback for status logging
FreetypeFontFileLister(FontCollectorStatusCallback cb);
std::vector<wxString> GetFontPaths(wxString const& facename, int, bool);
std::vector<wxString> GetFontPaths(wxString const& facename, int, bool, std::set<wxUniChar> const&);
};
#endif