Remove some cruft from the fonts collector
This commit is contained in:
parent
e924db1fda
commit
dd70da35d4
7 changed files with 108 additions and 143 deletions
|
@ -157,7 +157,6 @@
|
|||
<ClInclude Include="$(SrcDir)ffmpegsource_common.h" />
|
||||
<ClInclude Include="$(SrcDir)fft.h" />
|
||||
<ClInclude Include="$(SrcDir)font_file_lister.h" />
|
||||
<ClInclude Include="$(SrcDir)font_file_lister_fontconfig.h" />
|
||||
<ClInclude Include="$(SrcDir)frame_main.h" />
|
||||
<ClInclude Include="$(SrcDir)gl_text.h" />
|
||||
<ClInclude Include="$(SrcDir)gl_wrap.h" />
|
||||
|
|
|
@ -225,9 +225,6 @@
|
|||
<ClInclude Include="$(SrcDir)font_file_lister.h">
|
||||
<Filter>Features\Font collector</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(SrcDir)font_file_lister_fontconfig.h">
|
||||
<Filter>Features\Font collector</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(SrcDir)dialog_detached_video.h">
|
||||
<Filter>Video\UI</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1117,4 +1114,4 @@
|
|||
<ResourceCompile Include="$(SrcDir)res\res.rc" />
|
||||
<ResourceCompile Include="$(SrcDir)res\strings.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#include "font_file_lister.h"
|
||||
#include "font_file_lister_fontconfig.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "dialog_manager.h"
|
||||
|
@ -91,8 +90,7 @@ void FontsCollectorThread(AssFile *subs, agi::fs::path const& destination, FcMod
|
|||
collector->AddPendingEvent(event);
|
||||
};
|
||||
|
||||
FontConfigFontFileLister lister(AppendText);
|
||||
auto paths = FontCollector(AppendText, lister).GetFontPaths(subs);
|
||||
auto paths = FontCollector(AppendText).GetFontPaths(subs);
|
||||
if (paths.empty()) {
|
||||
collector->AddPendingEvent(wxThreadEvent(EVT_COLLECTION_DONE));
|
||||
return;
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
/// @file font_file_lister.cpp
|
||||
/// @brief Base-class for font collector implementations
|
||||
/// @ingroup font_collector
|
||||
///
|
||||
|
||||
#include "font_file_lister.h"
|
||||
|
||||
#include "ass_dialogue.h"
|
||||
|
@ -36,31 +31,31 @@
|
|||
#include <wx/intl.h>
|
||||
|
||||
namespace {
|
||||
wxString format_missing(wxString const& str) {
|
||||
wxString printable;
|
||||
wxString unprintable;
|
||||
for (wxUniChar c : str) {
|
||||
if (!u_isUWhiteSpace(c.GetValue()))
|
||||
printable += c;
|
||||
else {
|
||||
unprintable += fmt_wx("\n - U+%04X ", c.GetValue());
|
||||
UErrorCode ec;
|
||||
char buf[1024];
|
||||
auto len = u_charName(c.GetValue(), U_EXTENDED_CHAR_NAME, buf, sizeof buf, &ec);
|
||||
if (len != 0 && U_SUCCESS(ec))
|
||||
unprintable += to_wx(buf);
|
||||
if (c.GetValue() == 0xA0)
|
||||
unprintable += " (\\h)";
|
||||
}
|
||||
wxString format_missing(wxString const& str) {
|
||||
wxString printable;
|
||||
wxString unprintable;
|
||||
for (wxUniChar c : str) {
|
||||
if (!u_isUWhiteSpace(c.GetValue()))
|
||||
printable += c;
|
||||
else {
|
||||
unprintable += fmt_wx("\n - U+%04X ", c.GetValue());
|
||||
UErrorCode ec;
|
||||
char buf[1024];
|
||||
auto len = u_charName(c.GetValue(), U_EXTENDED_CHAR_NAME, buf, sizeof buf, &ec);
|
||||
if (len != 0 && U_SUCCESS(ec))
|
||||
unprintable += to_wx(buf);
|
||||
if (c.GetValue() == 0xA0)
|
||||
unprintable += " (\\h)";
|
||||
}
|
||||
|
||||
return printable + unprintable;
|
||||
}
|
||||
|
||||
return printable + unprintable;
|
||||
}
|
||||
}
|
||||
|
||||
FontCollector::FontCollector(FontCollectorStatusCallback status_callback, FontFileLister &lister)
|
||||
FontCollector::FontCollector(FontCollectorStatusCallback status_callback)
|
||||
: status_callback(std::move(status_callback))
|
||||
, lister(lister)
|
||||
, lister(this->status_callback)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -80,50 +75,66 @@ void FontCollector::ProcessDialogueLine(const AssDialogue *line, int index) {
|
|||
bool overriden = false;
|
||||
|
||||
for (auto& block : line->ParseTags()) {
|
||||
if (AssDialogueBlockOverride *ovr = dynamic_cast<AssDialogueBlockOverride *>(block.get())) {
|
||||
if (auto ovr = dynamic_cast<AssDialogueBlockOverride *>(block.get())) {
|
||||
for (auto const& tag : ovr->Tags) {
|
||||
std::string const& name = tag.Name;
|
||||
|
||||
if (name == "\\r") {
|
||||
if (tag.Name == "\\r") {
|
||||
style = styles[tag.Params[0].Get(line->Style.get())];
|
||||
overriden = false;
|
||||
}
|
||||
else if (name == "\\b") {
|
||||
else if (tag.Name == "\\b") {
|
||||
style.bold = tag.Params[0].Get(initial.bold);
|
||||
overriden = true;
|
||||
}
|
||||
else if (name == "\\i") {
|
||||
else if (tag.Name == "\\i") {
|
||||
style.italic = tag.Params[0].Get(initial.italic);
|
||||
overriden = true;
|
||||
}
|
||||
else if (name == "\\fn") {
|
||||
else if (tag.Name == "\\fn") {
|
||||
style.facename = tag.Params[0].Get(initial.facename);
|
||||
overriden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (AssDialogueBlockPlain *txt = dynamic_cast<AssDialogueBlockPlain *>(block.get())) {
|
||||
wxString text(to_wx(txt->GetText()));
|
||||
else if (auto txt = dynamic_cast<AssDialogueBlockPlain *>(block.get())) {
|
||||
auto text = txt->GetText();
|
||||
|
||||
if (text.empty())
|
||||
continue;
|
||||
|
||||
if (overriden)
|
||||
used_styles[style].lines.insert(index);
|
||||
std::set<wxUniChar>& chars = used_styles[style].chars;
|
||||
for (auto it = text.begin(); it != text.end(); ++it) {
|
||||
wxUniChar cur = *it;
|
||||
if (cur == L'\\' && it + 1 != text.end()) {
|
||||
wxUniChar next = *++it;
|
||||
if (next == 'N' || next == 'n')
|
||||
continue;
|
||||
if (next == 'h')
|
||||
cur = 0xA0;
|
||||
else
|
||||
--it;
|
||||
}
|
||||
chars.insert(cur);
|
||||
auto& usage = used_styles[style];
|
||||
|
||||
if (overriden) {
|
||||
auto& lines = usage.lines;
|
||||
if (lines.empty() || lines.back() != index)
|
||||
lines.push_back(index);
|
||||
}
|
||||
|
||||
auto& chars = usage.chars;
|
||||
auto size = static_cast<int>(text.size());
|
||||
for (int i = 0; i < size; ) {
|
||||
if (text[i] == '\\' && i + 1 < size) {
|
||||
char next = text[++i];
|
||||
if (next == 'N' || next == 'n') {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (next == 'h') {
|
||||
++i;
|
||||
chars.push_back(0xA0);
|
||||
continue;
|
||||
}
|
||||
|
||||
chars.push_back('\\');
|
||||
continue;
|
||||
}
|
||||
|
||||
UChar32 c;
|
||||
U8_NEXT(&text[0], i, size, c);
|
||||
chars.push_back(c);
|
||||
}
|
||||
|
||||
sort(begin(chars), end(chars));
|
||||
chars.erase(unique(chars.begin(), chars.end()), chars.end());
|
||||
}
|
||||
// Do nothing with drawing and comment blocks
|
||||
}
|
||||
|
@ -132,7 +143,7 @@ void FontCollector::ProcessDialogueLine(const AssDialogue *line, int index) {
|
|||
void FontCollector::ProcessChunk(std::pair<StyleInfo, UsageData> const& style) {
|
||||
if (style.second.chars.empty()) return;
|
||||
|
||||
FontFileLister::CollectionResult res = lister.GetFontPaths(style.first.facename, style.first.bold, style.first.italic, style.second.chars);
|
||||
auto res = lister.GetFontPaths(style.first.facename, style.first.bold, style.first.italic, style.second.chars);
|
||||
|
||||
if (res.paths.empty()) {
|
||||
status_callback(fmt_tl("Could not find font '%s'\n", style.first.facename), 2);
|
||||
|
@ -141,8 +152,11 @@ void FontCollector::ProcessChunk(std::pair<StyleInfo, UsageData> const& style) {
|
|||
}
|
||||
else {
|
||||
for (auto& elem : res.paths) {
|
||||
if (results.insert(elem).second)
|
||||
status_callback(fmt_tl("Found '%s' at '%s'\n", style.first.facename, elem.make_preferred()), 0);
|
||||
elem.make_preferred();
|
||||
if (std::find(begin(results), end(results), elem) == end(results)) {
|
||||
status_callback(fmt_tl("Found '%s' at '%s'\n", style.first.facename, elem), 0);
|
||||
results.push_back(elem);
|
||||
}
|
||||
}
|
||||
|
||||
if (res.fake_bold)
|
||||
|
@ -190,7 +204,7 @@ std::vector<agi::fs::path> FontCollector::GetFontPaths(const AssFile *file) {
|
|||
info.facename = style.font;
|
||||
info.bold = style.bold;
|
||||
info.italic = style.italic;
|
||||
used_styles[info].styles.insert(style.name);
|
||||
used_styles[info].styles.push_back(style.name);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
|
|
|
@ -14,19 +14,12 @@
|
|||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
/// @file font_file_lister.h
|
||||
/// @see font_file_lister.cpp
|
||||
/// @ingroup font_collector
|
||||
///
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libaegisub/fs_fwd.h>
|
||||
#include <libaegisub/scoped_ptr.h>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -37,18 +30,33 @@ class AssFile;
|
|||
|
||||
typedef std::function<void (wxString, int)> FontCollectorStatusCallback;
|
||||
|
||||
/// @class FontFileLister
|
||||
/// @brief Font lister interface
|
||||
class FontFileLister {
|
||||
struct CollectionResult {
|
||||
/// Characters which could not be found in any font files
|
||||
wxString missing;
|
||||
/// Paths to the file(s) containing the requested font
|
||||
std::vector<agi::fs::path> paths;
|
||||
bool fake_bold = false;
|
||||
bool fake_italic = false;
|
||||
};
|
||||
|
||||
typedef struct _FcConfig FcConfig;
|
||||
typedef struct _FcFontSet FcFontSet;
|
||||
|
||||
/// @class FontConfigFontFileLister
|
||||
/// @brief fontconfig powered font lister
|
||||
class FontConfigFontFileLister {
|
||||
agi::scoped_holder<FcConfig*> config;
|
||||
|
||||
/// @brief Case-insensitive match ASS/SSA font family against full name. (also known as "name for humans")
|
||||
/// @param family font fullname
|
||||
/// @param bold weight attribute
|
||||
/// @param italic italic attribute
|
||||
/// @return font set
|
||||
FcFontSet *MatchFullname(const char *family, int weight, int slant);
|
||||
public:
|
||||
struct CollectionResult {
|
||||
/// Characters which could not be found in any font files
|
||||
wxString missing;
|
||||
/// Paths to the file(s) containing the requested font
|
||||
std::vector<agi::fs::path> paths;
|
||||
bool fake_bold = false;
|
||||
bool fake_italic = false;
|
||||
};
|
||||
/// Constructor
|
||||
/// @param cb Callback for status logging
|
||||
FontConfigFontFileLister(FontCollectorStatusCallback &cb);
|
||||
|
||||
/// @brief Get the path to the font with the given styles
|
||||
/// @param facename Name of font face
|
||||
|
@ -56,7 +64,7 @@ public:
|
|||
/// @param italic Italic?
|
||||
/// @param characters Characters in this style
|
||||
/// @return Path to the matching font file(s), or empty if not found
|
||||
virtual CollectionResult GetFontPaths(std::string const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) = 0;
|
||||
CollectionResult GetFontPaths(std::string const& facename, int bold, bool italic, std::vector<int> const& characters);
|
||||
};
|
||||
|
||||
/// @class FontCollector
|
||||
|
@ -72,22 +80,22 @@ class FontCollector {
|
|||
|
||||
/// Data about where each style is used
|
||||
struct UsageData {
|
||||
std::set<wxUniChar> chars; ///< Characters used in this style which glyphs will be needed for
|
||||
std::set<int> lines; ///< Lines on which this style is used via overrides
|
||||
std::set<std::string> styles; ///< ASS styles which use this style
|
||||
std::vector<int> chars; ///< Characters used in this style which glyphs will be needed for
|
||||
std::vector<int> lines; ///< Lines on which this style is used via overrides
|
||||
std::vector<std::string> styles; ///< ASS styles which use this style
|
||||
};
|
||||
|
||||
/// Message callback provider by caller
|
||||
FontCollectorStatusCallback status_callback;
|
||||
/// The actual lister to use to get font paths
|
||||
FontFileLister &lister;
|
||||
|
||||
FontConfigFontFileLister lister;
|
||||
|
||||
/// The set of all glyphs used in the file
|
||||
std::map<StyleInfo, UsageData> used_styles;
|
||||
/// Style name -> ASS style definition
|
||||
std::map<std::string, StyleInfo> styles;
|
||||
/// Paths to found required font files
|
||||
std::set<agi::fs::path> results;
|
||||
std::vector<agi::fs::path> results;
|
||||
/// Number of fonts which could not be found
|
||||
int missing = 0;
|
||||
/// Number of fonts which were found, but did not contain all used glyphs
|
||||
|
@ -106,7 +114,7 @@ public:
|
|||
/// Constructor
|
||||
/// @param status_callback Function to pass status updates to
|
||||
/// @param lister The actual font file lister
|
||||
FontCollector(FontCollectorStatusCallback status_callback, FontFileLister &lister);
|
||||
FontCollector(FontCollectorStatusCallback status_callback);
|
||||
|
||||
/// @brief Get a list of the locations of all font files used in the file
|
||||
/// @param file Lines in the subtitle file to check
|
||||
|
|
|
@ -14,12 +14,7 @@
|
|||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
/// @file font_file_lister_fontconfig.cpp
|
||||
/// @brief Font Config-based font collector
|
||||
/// @ingroup font_collector
|
||||
///
|
||||
|
||||
#include "font_file_lister_fontconfig.h"
|
||||
#include "font_file_lister.h"
|
||||
|
||||
#include <libaegisub/log.h>
|
||||
|
||||
|
@ -74,14 +69,14 @@ void find_font(FcFontSet *src, FcFontSet *dst, std::string const& family) {
|
|||
|
||||
}
|
||||
|
||||
FontConfigFontFileLister::FontConfigFontFileLister(FontCollectorStatusCallback cb)
|
||||
FontConfigFontFileLister::FontConfigFontFileLister(FontCollectorStatusCallback &cb)
|
||||
: config(init_fontconfig(), FcConfigDestroy)
|
||||
{
|
||||
cb(_("Updating font cache\n"), 0);
|
||||
FcConfigBuildFonts(config);
|
||||
}
|
||||
|
||||
FontFileLister::CollectionResult FontConfigFontFileLister::GetFontPaths(std::string const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) {
|
||||
CollectionResult FontConfigFontFileLister::GetFontPaths(std::string const& facename, int bold, bool italic, std::vector<int> const& characters) {
|
||||
CollectionResult ret;
|
||||
|
||||
std::string family = facename[0] == '@' ? facename.substr(1) : facename;
|
||||
|
@ -124,7 +119,7 @@ FontFileLister::CollectionResult FontConfigFontFileLister::GetFontPaths(std::str
|
|||
|
||||
FcCharSet *charset;
|
||||
if (FcPatternGetCharSet(match, FC_CHARSET, 0, &charset) == FcResultMatch) {
|
||||
for (wxUniChar chr : characters) {
|
||||
for (int chr : characters) {
|
||||
if (!FcCharSetHasChar(charset, chr))
|
||||
ret.missing += chr;
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
/// @file font_file_lister_fontconfig.h
|
||||
/// @see font_file_lister_fontconfig.cpp
|
||||
/// @ingroup font_collector
|
||||
///
|
||||
|
||||
#include "font_file_lister.h"
|
||||
|
||||
#include <libaegisub/scoped_ptr.h>
|
||||
|
||||
typedef struct _FcConfig FcConfig;
|
||||
typedef struct _FcFontSet FcFontSet;
|
||||
|
||||
/// @class FontConfigFontFileLister
|
||||
/// @brief fontconfig powered font lister
|
||||
class FontConfigFontFileLister final : public FontFileLister {
|
||||
agi::scoped_holder<FcConfig*> config;
|
||||
|
||||
/// @brief Case-insensitive match ASS/SSA font family against full name. (also known as "name for humans")
|
||||
/// @param family font fullname
|
||||
/// @param bold weight attribute
|
||||
/// @param italic italic attribute
|
||||
/// @return font set
|
||||
FcFontSet *MatchFullname(const char *family, int weight, int slant);
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param cb Callback for status logging
|
||||
FontConfigFontFileLister(FontCollectorStatusCallback cb);
|
||||
|
||||
CollectionResult GetFontPaths(std::string const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) override;
|
||||
};
|
Loading…
Reference in a new issue