From 836a9581190d992a252795750c91ce65dc3b01fb Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 11 Aug 2024 18:24:22 +0200 Subject: [PATCH] feat: add font manager with switching capabilities --- build/Build.LibSkia.cs | 25 ++++- wrapper/include/SkFontMgr_alphaskia.h | 33 ++++++ wrapper/include/alphaskia.h | 2 + wrapper/src/SkFontMgr_alphaskia.cpp | 108 ++++++++++++++++++++ wrapper/src/SkFontMgr_alphaskia_factory.cpp | 9 +- wrapper/src/alphaskia_canvas.cpp | 23 +++++ 6 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 wrapper/include/SkFontMgr_alphaskia.h create mode 100644 wrapper/src/SkFontMgr_alphaskia.cpp diff --git a/build/Build.LibSkia.cs b/build/Build.LibSkia.cs index a1cc415..3c88cd0 100644 --- a/build/Build.LibSkia.cs +++ b/build/Build.LibSkia.cs @@ -125,7 +125,7 @@ partial class Build throw new IOException("BUILD.gn of skia changed, cannot patch files"); } - var sourcesEnd = buildFileSource.IndexOf("defines = []", sourcesStart, StringComparison.Ordinal); + var sourcesEnd = buildFileSource.IndexOf("libs = []", sourcesStart, StringComparison.Ordinal); if (sourcesEnd == -1) { throw new IOException("BUILD.gn of skia changed, cannot patch files"); @@ -153,13 +153,16 @@ partial class Build newSources += " sources += [\n"; newSources += " \"include/ports/SkFontMgr_indirect.h\",\n"; newSources += " \"include/ports/SkRemotableFontMgr.h\",\n"; + newSources += " \"src/fonts/SkFontMgr_indirect.cpp\",\n"; newSources += " \"src/ports/SkFontMgr_win_dw.cpp\",\n"; + newSources += " \"src/ports/SkScalerContext_win_dw.cpp\",\n"; newSources += " \"src/ports/SkScalerContext_win_dw.h\",\n"; newSources += " \"src/ports/SkTypeface_win_dw.cpp\",\n"; newSources += " \"src/ports/SkTypeface_win_dw.h\",\n"; newSources += " ]\n"; newSources += " }\n"; newSources += " if (is_android) {\n"; + newSources += " deps += [ \"//third_party/expat\" ]\n"; newSources += " sources += [\n"; newSources += " \"src/ports/SkFontMgr_android.cpp\",\n"; newSources += " \"src/ports/SkFontMgr_android_parser.cpp\",\n"; @@ -205,8 +208,26 @@ partial class Build var emptyFactoryIndex = buildFileSource.IndexOf(emptyFactoryFile); if(emptyFactoryIndex >= 0) { + var newSources = " sources = [\n"; + newSources += " \"../../wrapper/src/SkFontMgr_alphaskia_factory.cpp\",\n"; + newSources += " \"../../wrapper/src/SkFontMgr_alphaskia.cpp\",\n"; + newSources += " ]\n"; + newSources += " defines = []"; + newSources += " if (is_win) {\n"; + newSources += " defines += [ \"ALPHASKIA_FONTMGR_WINDOWS\" ]\n"; + newSources += " }\n"; + newSources += " if (is_android) {\n"; + newSources += " defines += [ \"ALPHASKIA_FONTMGR_ANDROID\" ]\n"; + newSources += " }\n"; + newSources += " if (is_mac) {\n"; + newSources += " defines += [ \"ALPHASKIA_FONTMGR_MAC\" ]\n"; + newSources += " }\n"; + newSources += " if (is_ios) {\n"; + newSources += " defines += [ \"ALPHASKIA_FONTMGR_IOS\" ]\n"; + newSources += " }\n"; + buildFileSource = buildFileSource[..emptyFactoryIndex] - + " sources = [ \"../../wrapper/src/SkFontMgr_alphaskia_factory.cpp\" ] " + + newSources + buildFileSource[(emptyFactoryIndex + emptyFactoryFile.Length)..]; } diff --git a/wrapper/include/SkFontMgr_alphaskia.h b/wrapper/include/SkFontMgr_alphaskia.h new file mode 100644 index 0000000..9b797d1 --- /dev/null +++ b/wrapper/include/SkFontMgr_alphaskia.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../../externals/skia/include/core/SkFontMgr.h" + +class SkFontMgr_AlphaSkia : public SkFontMgr +{ +public: + explicit SkFontMgr_AlphaSkia(); + + void switch_to_operating_system_fonts(); + void switch_to_freetype_fonts(); + +protected: + int onCountFamilies() const override; + void onGetFamilyName(int index, SkString *familyName) const override; + sk_sp onCreateStyleSet(int index) const override; + sk_sp onMatchFamily(const char familyName[]) const override; + sk_sp onMatchFamilyStyle(const char familyName[], + const SkFontStyle &fontStyle) const override; + sk_sp onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &, + const char *bcp47[], int bcp47Count, + SkUnichar character) const override; + sk_sp onMakeFromData(sk_sp data, int ttcIndex) const override; + sk_sp onMakeFromStreamIndex(std::unique_ptr, int ttcIndex) const override; + sk_sp onMakeFromStreamArgs(std::unique_ptr, const SkFontArguments &) const override; + sk_sp onMakeFromFile(const char path[], int ttcIndex) const override; + sk_sp onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override; + +private: + sk_sp currentFontMgr_; + sk_sp freeTypeFontMgr_; + sk_sp operatingSystemTypeFontMgr_; +}; diff --git a/wrapper/include/alphaskia.h b/wrapper/include/alphaskia.h index 6a6bbd8..2958f02 100644 --- a/wrapper/include/alphaskia.h +++ b/wrapper/include/alphaskia.h @@ -21,6 +21,8 @@ extern "C" { AS_API int32_t alphaskia_get_color_type(); + AS_API void alphaskia_switch_to_freetype_fonts(); + AS_API void alphaskia_switch_to_operating_system_fonts(); typedef AS_API void *alphaskia_data_t; AS_API alphaskia_data_t alphaskia_data_new_copy(const uint8_t *data, uint64_t length); diff --git a/wrapper/src/SkFontMgr_alphaskia.cpp b/wrapper/src/SkFontMgr_alphaskia.cpp new file mode 100644 index 0000000..d0829f0 --- /dev/null +++ b/wrapper/src/SkFontMgr_alphaskia.cpp @@ -0,0 +1,108 @@ +#include "../include/SkFontMgr_alphaskia.h" + +#include "../../externals/skia/include/core/SkSpan.h" +#include "../../externals/skia/include/core/SkFontStyle.h" +#include "../../externals/skia/include/core/SkTypeface.h" +#include "../../externals/skia/include/core/SkStream.h" +#include "../../externals/skia/include/ports/SkFontMgr_data.h" + +#if defined(ALPHASKIA_FONTMGR_WINDOWS) +#include "../../externals/skia/include/ports/SkTypeface_win.h" +#define CREATE_OPERATING_SYSTEM_FONTMGR SkFontMgr_New_DirectWrite() +#elif defined(ALPHASKIA_FONTMGR_ANDROID) +#include "../../externals/skia/include/ports/SkFontMgr_android.h" +#define CREATE_OPERATING_SYSTEM_FONTMGR SkFontMgr_New_Android(nullptr) +#elif defined(ALPHASKIA_FONTMGR_MAC) +#include "../../externals/skia/include/ports/SkFontMgr_mac_ct.h" +#define CREATE_OPERATING_SYSTEM_FONTMGR SkFontMgr_New_CoreText(nullptr) +#elif defined(ALPHASKIA_FONTMGR_IOS) +#include "../../externals/skia/include/ports/SkFontMgr_mac_ct.h" +#define CREATE_OPERATING_SYSTEM_FONTMGR SkFontMgr_New_CoreText(nullptr) +#else +#error "Unsupported operating system - extend font mgr" +#endif + +SkFontMgr_AlphaSkia::SkFontMgr_AlphaSkia() +{ + operatingSystemTypeFontMgr_ = CREATE_OPERATING_SYSTEM_FONTMGR; + currentFontMgr_ = operatingSystemTypeFontMgr_; +} + +void SkFontMgr_AlphaSkia::switch_to_operating_system_fonts() +{ + currentFontMgr_ = operatingSystemTypeFontMgr_; +} + +void SkFontMgr_AlphaSkia::switch_to_freetype_fonts() +{ + if (!freeTypeFontMgr_) + { + freeTypeFontMgr_ = SkFontMgr_New_Custom_Data(SkSpan>(nullptr, 0)); + } + currentFontMgr_ = freeTypeFontMgr_; +} + +int SkFontMgr_AlphaSkia::onCountFamilies() const +{ + return currentFontMgr_->countFamilies(); +} + +void SkFontMgr_AlphaSkia::onGetFamilyName(int index, SkString *familyName) const +{ + currentFontMgr_->getFamilyName(index, familyName); +} +sk_sp SkFontMgr_AlphaSkia::onCreateStyleSet(int index) const +{ + return currentFontMgr_->createStyleSet(index); +} + +sk_sp SkFontMgr_AlphaSkia::onMatchFamily(const char familyName[]) const +{ + return currentFontMgr_->matchFamily(familyName); +} + +sk_sp SkFontMgr_AlphaSkia::onMatchFamilyStyle(const char familyName[], + const SkFontStyle &fontStyle) const +{ + return currentFontMgr_->matchFamilyStyle(familyName, fontStyle); +} + +sk_sp SkFontMgr_AlphaSkia::onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &style, + const char *bcp47[], int bcp47Count, + SkUnichar character) const +{ + return currentFontMgr_->matchFamilyStyleCharacter(familyName, style, bcp47, bcp47Count, character); +} + +sk_sp SkFontMgr_AlphaSkia::onMakeFromData(sk_sp data, int ttcIndex) const +{ + return currentFontMgr_->makeFromData(data, ttcIndex); +} + +sk_sp SkFontMgr_AlphaSkia::onMakeFromStreamIndex(std::unique_ptr stream, int ttcIndex) const +{ + if (stream == nullptr) + { + return nullptr; + } + return currentFontMgr_->makeFromStream(std::move(stream), ttcIndex); +} + +sk_sp SkFontMgr_AlphaSkia::onMakeFromStreamArgs(std::unique_ptr stream, const SkFontArguments &args) const +{ + if (stream == nullptr) + { + return nullptr; + } + return currentFontMgr_->makeFromStream(std::move(stream), args); +} + +sk_sp SkFontMgr_AlphaSkia::onMakeFromFile(const char path[], int ttcIndex) const +{ + return currentFontMgr_->makeFromFile(path, ttcIndex); +} + +sk_sp SkFontMgr_AlphaSkia::onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const +{ + return currentFontMgr_->legacyMakeTypeface(familyName, style); +} \ No newline at end of file diff --git a/wrapper/src/SkFontMgr_alphaskia_factory.cpp b/wrapper/src/SkFontMgr_alphaskia_factory.cpp index a137b83..dc02a1f 100644 --- a/wrapper/src/SkFontMgr_alphaskia_factory.cpp +++ b/wrapper/src/SkFontMgr_alphaskia_factory.cpp @@ -1,7 +1,6 @@ -#include "../../externals/skia/include/core/SkFontMgr.h" -#include "../../externals/skia/include/ports/SkTypeface_win.h" +#include "../include/SkFontMgr_alphaskia.h" -sk_sp SkFontMgr::Factory() { - // TODO: functions for dynamic changing - return SkFontMgr_New_DirectWrite(); +sk_sp SkFontMgr::Factory() +{ + return sk_make_sp(); } diff --git a/wrapper/src/alphaskia_canvas.cpp b/wrapper/src/alphaskia_canvas.cpp index 39c5f74..3d20efc 100644 --- a/wrapper/src/alphaskia_canvas.cpp +++ b/wrapper/src/alphaskia_canvas.cpp @@ -1,4 +1,7 @@ #include "../include/AlphaSkiaCanvas.h" +#include "../include/SkFontMgr_alphaskia.h" + +#include "../../externals/skia/include/core/SkFontMgr.h" // C - API extern "C" @@ -15,6 +18,26 @@ extern "C" delete internal; } + AS_API void alphaskia_switch_to_freetype_fonts() + { + sk_sp fm = SkFontMgr::RefDefault(); + SkFontMgr_AlphaSkia *afm = dynamic_cast(fm.get()); + if (afm != nullptr) + { + afm->switch_to_freetype_fonts(); + } + } + + AS_API void alphaskia_switch_to_operating_system_fonts() + { + sk_sp fm = SkFontMgr::RefDefault(); + SkFontMgr_AlphaSkia *afm = dynamic_cast(fm.get()); + if (afm != nullptr) + { + afm->switch_to_operating_system_fonts(); + } + } + AS_API int32_t alphaskia_get_color_type() { return kN32_SkColorType;