2025-07-06 20:43:53 +03:00
|
|
|
#include "FontData.hpp"
|
|
|
|
|
#include <include/ports/SkFontMgr_empty.h>
|
|
|
|
|
#include <include/core/SkFontMetrics.h>
|
|
|
|
|
#include <include/core/SkTextBlob.h>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
2025-11-18 22:06:37 +03:00
|
|
|
#ifdef __EMSCRIPTEN__
|
|
|
|
|
#include <include/ports/SkFontMgr_directory.h>
|
2025-11-21 22:26:58 -08:00
|
|
|
#elif __APPLE__
|
|
|
|
|
#include <include/ports/SkFontMgr_mac_ct.h>
|
|
|
|
|
#include <ApplicationServices/ApplicationServices.h>
|
2025-11-18 22:06:37 +03:00
|
|
|
#elif _WIN32
|
2025-11-19 08:53:49 +03:00
|
|
|
#include <include/ports/SkTypeface_win.h>
|
2025-11-19 15:07:01 +03:00
|
|
|
#include "WindowsFontData/CustomFontSetManager.h"
|
|
|
|
|
DWriteCustomFontSets::CustomFontSetManager fontSetManagerWindows;
|
2025-11-18 22:06:37 +03:00
|
|
|
#else
|
2025-10-12 18:24:59 +03:00
|
|
|
#include <include/ports/SkFontMgr_fontconfig.h>
|
|
|
|
|
#include <include/ports/SkFontScanner_FreeType.h>
|
2025-11-18 22:06:37 +03:00
|
|
|
#include <include/ports/SkFontMgr_directory.h>
|
2025-10-12 18:24:59 +03:00
|
|
|
#endif
|
|
|
|
|
|
2025-11-15 14:05:05 +03:00
|
|
|
#include <src/base/SkUTF.h>
|
2025-11-19 15:07:01 +03:00
|
|
|
#include <filesystem>
|
2025-11-15 14:05:05 +03:00
|
|
|
|
2025-10-12 18:24:59 +03:00
|
|
|
FontData::FontData()
|
2025-07-06 20:43:53 +03:00
|
|
|
{
|
2025-11-19 15:07:01 +03:00
|
|
|
|
2025-10-12 18:24:59 +03:00
|
|
|
#ifdef __EMSCRIPTEN__
|
2025-11-18 22:06:37 +03:00
|
|
|
defaultFontMgr = SkFontMgr_New_Custom_Directory("data/fonts");
|
2025-11-21 22:26:58 -08:00
|
|
|
#elif __APPLE__
|
|
|
|
|
for(const auto& dirEntry : std::filesystem::recursive_directory_iterator("data/fonts")) {
|
|
|
|
|
if(dirEntry.is_regular_file()) {
|
|
|
|
|
std::string urlStr = std::string(std::filesystem::canonical(dirEntry.path()).string());
|
|
|
|
|
CFURLRef fontURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(urlStr.c_str()), urlStr.size(), false);
|
|
|
|
|
CTFontManagerRegisterFontsForURL(fontURL, CTFontManagerScope::kCTFontManagerScopeProcess, nullptr);
|
|
|
|
|
CFRelease(fontURL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
defaultFontMgr = SkFontMgr_New_CoreText(nullptr);
|
2025-11-18 22:06:37 +03:00
|
|
|
#elif _WIN32
|
2025-11-19 08:53:49 +03:00
|
|
|
localFontMgr = SkFontMgr_New_DirectWrite();
|
2025-11-19 15:07:01 +03:00
|
|
|
std::vector<std::wstring> fontPaths;
|
2025-11-21 22:26:58 -08:00
|
|
|
for(const auto& dirEntry : std::filesystem::recursive_directory_iterator(std::filesystem::path(L"data\\fonts"))) {
|
|
|
|
|
if(dirEntry.is_regular_file())
|
|
|
|
|
fontPaths.emplace_back(dirEntry.path().wstring());
|
|
|
|
|
}
|
2025-11-19 15:07:01 +03:00
|
|
|
fontSetManagerWindows.CreateFontSetUsingLocalFontFiles(fontPaths);
|
|
|
|
|
fontSetManagerWindows.CreateFontCollectionFromFontSet();
|
|
|
|
|
|
|
|
|
|
IDWriteFactory* fac = fontSetManagerWindows.IDWriteFactory5_IsAvailable() ? fontSetManagerWindows.m_dwriteFactory5.Get() : fontSetManagerWindows.m_dwriteFactory3.Get();
|
|
|
|
|
defaultFontMgr = SkFontMgr_New_DirectWrite(fac, fontSetManagerWindows.m_customFontCollection.Get());
|
2025-10-12 18:24:59 +03:00
|
|
|
#else
|
2025-11-18 18:15:50 +03:00
|
|
|
localFontMgr = SkFontMgr_New_FontConfig(nullptr, SkFontScanner_Make_FreeType());
|
2025-11-18 22:06:37 +03:00
|
|
|
defaultFontMgr = SkFontMgr_New_Custom_Directory("data/fonts");
|
2025-10-12 18:24:59 +03:00
|
|
|
#endif
|
2025-11-11 19:52:45 +03:00
|
|
|
|
|
|
|
|
map["Roboto"] = defaultFontMgr->makeFromFile("data/fonts/Roboto-variable.ttf");
|
|
|
|
|
|
2025-10-15 16:33:24 +03:00
|
|
|
collection = sk_make_sp<skia::textlayout::FontCollection>();
|
2025-11-15 14:05:05 +03:00
|
|
|
collection->setDefaultFontManager(defaultFontMgr, std::vector<SkString>{SkString{"Roboto"}, SkString{"Noto Emoji"}, SkString{"Noto Kufi Arabic"}});
|
2025-11-21 22:26:58 -08:00
|
|
|
if(localFontMgr)
|
|
|
|
|
collection->setDynamicFontManager(localFontMgr);
|
2025-11-15 14:05:05 +03:00
|
|
|
std::string s = "🙂";
|
|
|
|
|
const char* sPtr = s.data();
|
|
|
|
|
SkFontStyle defaultStyle;
|
|
|
|
|
SkString defaultLocale("en");
|
|
|
|
|
auto defaultEmojiFallback = collection->defaultEmojiFallback(SkUTF::NextUTF8(&sPtr, s.c_str() + s.length()), defaultStyle, defaultLocale);
|
|
|
|
|
fallbackOnEmoji = !defaultEmojiFallback;
|
2025-07-06 20:43:53 +03:00
|
|
|
}
|
|
|
|
|
|
2025-11-16 10:42:01 +03:00
|
|
|
const std::vector<SkString>& FontData::get_default_font_families() const {
|
2025-11-15 14:05:05 +03:00
|
|
|
static std::vector<SkString> defaultFontFamilies;
|
|
|
|
|
if(defaultFontFamilies.empty()) {
|
|
|
|
|
defaultFontFamilies.emplace_back("Roboto");
|
|
|
|
|
if(fallbackOnEmoji)
|
|
|
|
|
defaultFontFamilies.emplace_back("Noto Emoji");
|
|
|
|
|
defaultFontFamilies.emplace_back("Noto Kufi Arabic");
|
|
|
|
|
}
|
|
|
|
|
return defaultFontFamilies;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-16 10:42:01 +03:00
|
|
|
void FontData::push_default_font_families(std::vector<SkString>& fontFamilies) const {
|
2025-11-15 14:05:05 +03:00
|
|
|
fontFamilies.emplace_back("Roboto");
|
|
|
|
|
if(fallbackOnEmoji)
|
|
|
|
|
fontFamilies.emplace_back("Noto Emoji");
|
|
|
|
|
fontFamilies.emplace_back("Noto Kufi Arabic");
|
|
|
|
|
}
|
2025-11-16 10:42:01 +03:00
|
|
|
|
|
|
|
|
FontData::~FontData() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Vector2f get_str_font_bounds(const SkFont& font, const std::string& str) {
|
|
|
|
|
SkFontMetrics metrics;
|
|
|
|
|
font.getMetrics(&metrics);
|
|
|
|
|
float nextText = font.measureText(str.data(), str.length(), SkTextEncoding::kUTF8, nullptr);
|
|
|
|
|
return Vector2f{nextText, - metrics.fAscent + metrics.fDescent};
|
|
|
|
|
}
|