Perform font matching from placefile

This commit is contained in:
Dan Paulat 2023-09-23 00:44:35 -05:00
parent 7edd512ff7
commit d1a478ad12
4 changed files with 106 additions and 3 deletions

View file

@ -51,8 +51,10 @@ public:
void ReadPlacefileSettings();
void WritePlacefileSettings();
static void
LoadFontResources(const std::shared_ptr<gr::Placefile>& placefile);
static std::vector<std::shared_ptr<boost::gil::rgba8_image_t>>
LoadResources(const std::shared_ptr<gr::Placefile>& placefile);
LoadImageResources(const std::shared_ptr<gr::Placefile>& placefile);
boost::asio::thread_pool threadPool_ {1u};
@ -587,7 +589,8 @@ void PlacefileManager::Impl::PlacefileRecord::Update()
if (updatedPlacefile != nullptr)
{
// Load placefile resources
auto newImages = Impl::LoadResources(updatedPlacefile);
Impl::LoadFontResources(updatedPlacefile);
auto newImages = Impl::LoadImageResources(updatedPlacefile);
// Check the name matches, in case the name updated
if (name_ == name)
@ -684,8 +687,31 @@ std::shared_ptr<PlacefileManager> PlacefileManager::Instance()
return placefileManager;
}
void PlacefileManager::Impl::LoadFontResources(
const std::shared_ptr<gr::Placefile>& placefile)
{
auto fonts = placefile->fonts();
for (auto& font : fonts)
{
units::font_size::pixels<double> size {font.second->pixels_};
std::vector<std::string> styles {};
if (font.second->IsBold())
{
styles.push_back("bold");
}
if (font.second->IsItalic())
{
styles.push_back("italic");
}
ResourceManager::LoadFontResource(font.second->face_, styles, size);
}
}
std::vector<std::shared_ptr<boost::gil::rgba8_image_t>>
PlacefileManager::Impl::LoadResources(
PlacefileManager::Impl::LoadImageResources(
const std::shared_ptr<gr::Placefile>& placefile)
{
const auto iconFiles = placefile->icon_files();

View file

@ -34,6 +34,8 @@ static void LoadFcApplicationFont(const std::string& fontFilename);
static void LoadFonts();
static void LoadTextures();
static const std::string kFcTrueType_ {"TrueType"};
static const std::vector<std::pair<types::Font, std::string>> fontNames_ {
{types::Font::din1451alt, ":/res/fonts/din1451alt.ttf"},
{types::Font::din1451alt_g, ":/res/fonts/din1451alt_g.ttf"},
@ -44,6 +46,9 @@ static std::string fontCachePath_ {};
static std::unordered_map<types::Font, int> fontIds_ {};
static std::unordered_map<types::Font, std::shared_ptr<util::Font>> fonts_ {};
static FcFontSet* fcFontSet_ {nullptr};
static FcObjectSet* fcObjectSet_ {nullptr};
void Initialize()
{
config::CountyDatabase::Initialize();
@ -80,6 +85,72 @@ std::shared_ptr<util::Font> Font(types::Font font)
return nullptr;
}
void LoadFontResource(const std::string& family,
const std::vector<std::string>& styles,
units::font_size::points<double> size)
{
const std::string styleString = fmt::format("{}", fmt::join(styles, " "));
const std::string fontString =
fmt::format("{}-{}:{}", family, size.value(), styleString);
logger_->debug("LoadFontResource: {}", fontString);
// Build fontconfig pattern
FcPattern* pattern = FcPatternCreate();
FcPatternAddString(
pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(family.c_str()));
FcPatternAddDouble(pattern, FC_SIZE, size.value());
FcPatternAddString(pattern,
FC_FONTFORMAT,
reinterpret_cast<const FcChar8*>(kFcTrueType_.c_str()));
if (!styles.empty())
{
FcPatternAddString(pattern,
FC_STYLE,
reinterpret_cast<const FcChar8*>(styleString.c_str()));
}
// Perform font pattern match substitution
FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
// Find matching font
FcResult result;
FcPattern* match = FcFontMatch(nullptr, pattern, &result);
std::string fontFile {};
if (match != nullptr)
{
FcChar8* fcFamily;
FcChar8* fcStyle;
FcChar8* fcFile;
// Match was found, get properties
if (FcPatternGetString(match, FC_FAMILY, 0, &fcFamily) == FcResultMatch &&
FcPatternGetString(match, FC_STYLE, 0, &fcStyle) == FcResultMatch &&
FcPatternGetString(match, FC_FILE, 0, &fcFile) == FcResultMatch)
{
fontFile = reinterpret_cast<char*>(fcFile);
logger_->debug("Found matching font: {}:{} ({})",
reinterpret_cast<char*>(fcFamily),
reinterpret_cast<char*>(fcStyle),
fontFile);
}
}
if (fontFile.empty())
{
logger_->warn("Could not find matching font: {}", fontString);
}
// Cleanup
FcPatternDestroy(match);
FcPatternDestroy(pattern);
}
std::shared_ptr<boost::gil::rgba8_image_t>
LoadImageResource(const std::string& urlString)
{

View file

@ -22,6 +22,9 @@ void Shutdown();
int FontId(types::Font font);
std::shared_ptr<util::Font> Font(types::Font font);
void LoadFontResource(const std::string& family,
const std::vector<std::string>& styles,
units::font_size::points<double> size);
std::shared_ptr<boost::gil::rgba8_image_t>
LoadImageResource(const std::string& urlString);
std::vector<std::shared_ptr<boost::gil::rgba8_image_t>>

View file

@ -67,6 +67,9 @@ public:
std::size_t pixels_ {};
std::int32_t flags_ {};
std::string face_ {};
bool IsBold() { return flags_ & 1; }
bool IsItalic() { return flags_ & 2; }
};
struct DrawItem