diff --git a/build/BUILD.gn b/build/BUILD.gn index 68a563901152f137ed951b095daa7d4f875b26cf..521d8a4f6a5476b583bcc2a5de3462adf97b1c63 100644 --- a/build/BUILD.gn +++ b/build/BUILD.gn @@ -28,8 +28,13 @@ config("flutter_config") { "$flutter_root", "$flutter_root/engine", "$flutter_root/engine/flutter", - "$flutter_root/engine/flutter/third_party/txt/src", ] + + if (use_new_skia) { + include_dirs += [ "$flutter_root/txt/src" ] + } else { + include_dirs += [ "$flutter_root/engine/flutter/third_party/txt/src" ] + } cflags = [ "-fvisibility=hidden", diff --git a/build/libtxt/BUILD.gn b/build/libtxt/BUILD.gn index cc0240c6e364c740e2c54163967cc01a751d7c28..cb7a3cfa63f93f3da9c4a2ddc573e5b3bb162d62 100644 --- a/build/libtxt/BUILD.gn +++ b/build/libtxt/BUILD.gn @@ -23,6 +23,12 @@ config("thirdparty_lib_txt_config") { ] } +if (use_new_skia) { + txt_root = "$flutter_root/txt" +} else { + txt_root = "$flutter_root/engine/flutter/third_party/txt" +} + template("thirdparty_lib_txt") { forward_variables_from(invoker, "*") @@ -42,60 +48,74 @@ template("thirdparty_lib_txt") { } sources = [ - "$flutter_root/engine/flutter/third_party/txt/src/log/log.cc", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/CmapCoverage.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/Emoji.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/FontCollection.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/FontFamily.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/FontLanguage.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/FontLanguageListCache.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/FontUtils.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/GraphemeBreak.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/HbFontCache.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/Hyphenator.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/Layout.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/LayoutUtils.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/LineBreaker.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/Measurement.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/MinikinFont.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/MinikinInternal.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/SparseBitSet.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/minikin/WordBreaker.cpp", - "$flutter_root/engine/flutter/third_party/txt/src/txt/asset_font_manager.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/font_asset_provider.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/font_collection.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/font_features.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/font_skia.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/paint_record.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/paragraph_builder.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/paragraph_builder_txt.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/paragraph_style.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/paragraph_txt.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/placeholder_run.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/styled_runs.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/test_font_manager.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/text_decoration.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/text_shadow.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/text_style.cc", - "$flutter_root/engine/flutter/third_party/txt/src/txt/typeface_font_asset_provider.cc", - "$flutter_root/engine/flutter/third_party/txt/src/utils/JenkinsHash.cpp", + "$txt_root/src/log/log.cc", + "$txt_root/src/minikin/CmapCoverage.cpp", + "$txt_root/src/minikin/Emoji.cpp", + "$txt_root/src/minikin/FontCollection.cpp", + "$txt_root/src/minikin/FontFamily.cpp", + "$txt_root/src/minikin/FontLanguage.cpp", + "$txt_root/src/minikin/FontLanguageListCache.cpp", + "$txt_root/src/minikin/FontUtils.cpp", + "$txt_root/src/minikin/GraphemeBreak.cpp", + "$txt_root/src/minikin/HbFontCache.cpp", + "$txt_root/src/minikin/Hyphenator.cpp", + "$txt_root/src/minikin/Layout.cpp", + "$txt_root/src/minikin/LayoutUtils.cpp", + "$txt_root/src/minikin/LineBreaker.cpp", + "$txt_root/src/minikin/Measurement.cpp", + "$txt_root/src/minikin/MinikinFont.cpp", + "$txt_root/src/minikin/MinikinInternal.cpp", + "$txt_root/src/minikin/SparseBitSet.cpp", + "$txt_root/src/minikin/WordBreaker.cpp", + "$txt_root/src/txt/asset_font_manager.cc", + "$txt_root/src/txt/font_asset_provider.cc", + "$txt_root/src/txt/font_collection.cc", + "$txt_root/src/txt/font_features.cc", + "$txt_root/src/txt/font_skia.cc", + "$txt_root/src/txt/paint_record.cc", + "$txt_root/src/txt/paragraph_builder.cc", + "$txt_root/src/txt/paragraph_builder_txt.cc", + "$txt_root/src/txt/paragraph_style.cc", + "$txt_root/src/txt/paragraph_txt.cc", + "$txt_root/src/txt/placeholder_run.cc", + "$txt_root/src/txt/styled_runs.cc", + "$txt_root/src/txt/test_font_manager.cc", + "$txt_root/src/txt/text_decoration.cc", + "$txt_root/src/txt/text_shadow.cc", + "$txt_root/src/txt/text_style.cc", + "$txt_root/src/txt/typeface_font_asset_provider.cc", + "$txt_root/src/utils/JenkinsHash.cpp", ] - deps = [ - "$ace_flutter_engine_root:flutter_engine_fml_$platform", - "$ace_flutter_engine_root/icu:ace_libicu_$platform", - "$ace_flutter_engine_root/skia:ace_skia_$platform", - ] + if (use_new_skia) { + deps = [ + "$ace_flutter_engine_root:flutter_engine_fml_$platform", + "$ace_flutter_engine_root/icu:ace_libicu_$platform", + "//third_party/skia:skia", + "$ace_flutter_engine_root/harfbuzz:ace_libharfbuzz_$platform", + ] + include_dirs = [ + "$flutter_root/txt/src", + "//third_party/skia/third_party/externals/harfbuzz/src", + "//", + ] + } else { + deps = [ + "$ace_flutter_engine_root:flutter_engine_fml_$platform", + "$ace_flutter_engine_root/icu:ace_libicu_$platform", + "$ace_flutter_engine_root/skia:ace_skia_$platform", + ] + } if (platform == "ohos") { if (defined(oem_commercial_build) && oem_commercial_build) { - sources += [ "$flutter_root/engine/flutter/third_party/txt/src/txt/platform_android.cc" ] + sources += [ "$txt_root/src/txt/platform_android.cc" ] } else { - sources += [ "$flutter_root/engine/flutter/third_party/txt/src/txt/platform_ohos.cc" ] + sources += [ "$txt_root/src/txt/platform_ohos.cc" ] } } else if (platform == "windows") { sources += - [ "$flutter_root/engine/flutter/third_party/txt/src/txt/platform.cc" ] + [ "$txt_root/src/txt/platform.cc" ] if (use_mingw_win) { defines += [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_WIN" ] } @@ -103,7 +123,7 @@ template("thirdparty_lib_txt") { } else if (platform == "mac" || platform == "ios") { cflags = [ "-DNS_FORMAT_ARGUMENT(A)=" ] sources += [ - "$flutter_root/engine/flutter/third_party/txt/src/txt/platform_mac.mm", + "$txt_root/src/txt/platform_mac.mm", ] deps += [ "$ace_flutter_engine_root/harfbuzz:ace_libharfbuzz_$platform" ] if (use_mac) { @@ -125,9 +145,9 @@ template("thirdparty_lib_txt") { } } } else if (platform == "android") { - sources += [ "$flutter_root/engine/flutter/third_party/txt/src/txt/platform_android.cc" ] + sources += [ "$txt_root/src/txt/platform_android.cc" ] } else if (platform == "linux") { - sources += [ "$flutter_root/engine/flutter/third_party/txt/src/txt/platform_linux.cc" ] + sources += [ "$txt_root/src/txt/platform_linux.cc" ] if (use_linux) { defines += [ "SK_BUILD_FONT_MGR_FOR_PREVIEW_LINUX" ] } diff --git a/build/skia/BUILD.gn b/build/skia/BUILD.gn index 05749ec99168fde81acfa458760d83c2665b5470..1790ed8c0afe1bfa91b5d9f56a8751409a5d8939 100644 --- a/build/skia/BUILD.gn +++ b/build/skia/BUILD.gn @@ -214,6 +214,10 @@ if (!is_cross_platform_build) { "$ace_flutter_engine_root/libwebp:ace_libwebp", ] + if (defined(use_new_skia) && use_new_skia) { + deps -= [ ":make_third_party_skia_include_dir" ] + } + if (defined(disable_gpu) && disable_gpu) { deps -= [ ":ace_gpu_$platform" ] } else { diff --git a/build/skia/ohos/BUILD.gn b/build/skia/ohos/BUILD.gn index 0349d4bbdd0dcffc6416dabb7f793a0c3a31a5a8..6729cf36b6c3c6d8b37c0fa1a9260a12fb4b6b3a 100644 --- a/build/skia/ohos/BUILD.gn +++ b/build/skia/ohos/BUILD.gn @@ -54,6 +54,10 @@ ohos_shared_library("skia_ohos") { "$rosen_flutter_engine_root/icu:rosen_libicu_ohos", ] + if (defined(use_new_skia) && use_new_skia) { + deps -= [ "$ace_flutter_engine_root/skia:make_third_party_skia_include_dir" ] + } + if (ace_enable_gpu) { deps += [ ":gpu_ohos" ] } diff --git a/txt/src/minikin/FontCollection.cpp b/txt/src/minikin/FontCollection.cpp index 91d1ac295cdc108ffdf98da04a93729188f7f120..1b18d896c52f3e99c32463bac99b28358944b0e6 100644 --- a/txt/src/minikin/FontCollection.cpp +++ b/txt/src/minikin/FontCollection.cpp @@ -304,17 +304,44 @@ const std::shared_ptr& FontCollection::getFamilyForChar( uint32_t vs, uint32_t langListId, int variant) const { + // First find font in hw theme. + for (size_t k = 0; k < mFamilies.size(); k++) { + if (NULL == mFamilies[k]) { + continue; + } + if (mFamilies[k]->getHwFontFamilyType() > 0) { + if(mFamilies[k] ->getCoverage().get(ch)) { + return mFamilies[k]; + } + } + } + + if (mFallbackFontProvider) { + const std::shared_ptr& fallback = + mFallbackFontProvider->matchFallbackFontFromHwFont(ch, + GetFontLocale(langListId)); + if (fallback) { + return fallback; + } + } + if (ch >= mMaxChar) { // libtxt: check if the fallback font provider can match this character if (mFallbackFontProvider) { const std::shared_ptr& fallback = - findFallbackFont(ch, vs, langListId); + findFallbackFont(ch, vs, langListId); if (fallback) { return fallback; } } return mFamilies[0]; } + // 0x1000 to 0x109f is range of Burmese, force ch to 0x1000 or 0x1050 to match Z-encoding and U-encoding of Burmese. + if (ch >= 0x1000 && ch <= 0x109f) { + const uint32_t ZAWGYI_START_CODE = 0x1000; + const uint32_t UNICODE_START_CODE = 0x1050; + ch = mIsZawgyiMyanmar ? ZAWGYI_START_CODE : UNICODE_START_CODE; // 0x1050 is exist in U-encoding of Burmese only. + } Range range = mRanges[ch >> kLogCharsPerPage]; diff --git a/txt/src/minikin/FontCollection.h b/txt/src/minikin/FontCollection.h index 85ca1f4b866191c96d15f6312cc7754ec67c3f09..822bf46cadeace9457b3e87898a17ff6a8e0dbfc 100644 --- a/txt/src/minikin/FontCollection.h +++ b/txt/src/minikin/FontCollection.h @@ -43,6 +43,9 @@ class FontCollection { virtual const std::shared_ptr& matchFallbackFont( uint32_t ch, std::string locale) = 0; + virtual const std::shared_ptr& matchFallbackFontFromHwFont( + uint32_t ch, + std::string locale) = 0; }; struct Run { @@ -80,6 +83,10 @@ class FontCollection { mFallbackFontProvider = std::move(ffp); } + void SetIsZawgyiMyanmar(bool isZawgyiMyanmar) { + mIsZawgyiMyanmar = isZawgyiMyanmar; + } + private: static const int kLogCharsPerPage = 8; static const int kPageMask = (1 << kLogCharsPerPage) - 1; @@ -159,6 +166,7 @@ class FontCollection { // was constructed. mutable std::map>> mCachedFallbackFamilies; + bool mIsZawgyiMyanmar = false; }; } // namespace minikin diff --git a/txt/src/minikin/FontFamily.cpp b/txt/src/minikin/FontFamily.cpp index cf5a623c5613258a8ef2b40cf90c484a42075ed8..9ecffc22575c67ec54339f735f39853a95ba1371 100644 --- a/txt/src/minikin/FontFamily.cpp +++ b/txt/src/minikin/FontFamily.cpp @@ -124,6 +124,14 @@ bool FontFamily::analyzeStyle(const std::shared_ptr& typeface, italic); } +int FontFamily::getHwFontFamilyType() { + return mHwFontFamilyType; +} + +void FontFamily::setHwFontFamilyType(int HwFontFamilyType) { + mHwFontFamilyType = HwFontFamilyType; +} + // Compute a matching metric between two styles - 0 is an exact match static int computeMatch(FontStyle style1, FontStyle style2) { if (style1 == style2) diff --git a/txt/src/minikin/FontFamily.h b/txt/src/minikin/FontFamily.h index aac7a0d62bd12ae5a344a553bd11e0d08fbfaf1c..aedb92cf7d9419353ccef960ec01a1369da79302 100644 --- a/txt/src/minikin/FontFamily.h +++ b/txt/src/minikin/FontFamily.h @@ -173,6 +173,9 @@ class FontFamily { std::shared_ptr createFamilyWithVariation( const std::vector& variations) const; + int getHwFontFamilyType(); + void setHwFontFamilyType(int type); + private: void computeCoverage(); @@ -183,6 +186,7 @@ class FontFamily { SparseBitSet mCoverage; bool mHasVSTable; + int mHwFontFamilyType = 0; // Forbid copying and assignment. FontFamily(const FontFamily&) = delete; diff --git a/txt/src/txt/font_collection.cc b/txt/src/txt/font_collection.cc index 7c0e4e483054c5f5d5a4a222af0e130ef5e42363..8663fd4f2bbba8cbe88f8fb18b6a3f0dd64ce724 100644 --- a/txt/src/txt/font_collection.cc +++ b/txt/src/txt/font_collection.cc @@ -24,6 +24,9 @@ #include #include #include +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) +#include "third_party/skia/src/ports/SkFontMgr_ohos.h" +#endif #include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" #include "font_skia.h" @@ -77,6 +80,20 @@ class TxtFallbackFontProvider } } + virtual const std::shared_ptr& matchFallbackFontFromHwFont( + uint32_t ch, + std::string locale) { +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) + std::shared_ptr fc = font_collection_.lock(); + if (fc) { + return fc->MatchFallbackFontFromHwFont(ch, locale); + } else { + return g_null_family; + } +#endif + return g_null_family; + } + private: std::weak_ptr font_collection_; }; @@ -98,10 +115,12 @@ size_t FontCollection::GetFontManagersCount() const { } void FontCollection::SetupDefaultFontManager() { + std::lock_guard lock(fontManagerMutex_); default_font_manager_ = GetDefaultFontManager(); } void FontCollection::SetDefaultFontManager(sk_sp font_manager) { + std::lock_guard lock(fontManagerMutex_); default_font_manager_ = font_manager; #if FLUTTER_ENABLE_SKSHAPER @@ -133,6 +152,11 @@ void FontCollection::SetTestFontManager(sk_sp font_manager) { #endif } +sk_sp FontCollection::GetDefaultFontManagerSafely() const { + std::lock_guard lock(fontManagerMutex_); + return default_font_manager_; +} + // Return the available font managers in the order they should be queried. std::vector> FontCollection::GetFontManagerOrder() const { std::vector> order; @@ -142,8 +166,9 @@ std::vector> FontCollection::GetFontManagerOrder() const { order.push_back(asset_font_manager_); if (test_font_manager_) order.push_back(test_font_manager_); - if (default_font_manager_) - order.push_back(default_font_manager_); + auto defaultFontManager = GetDefaultFontManagerSafely(); + if (defaultFontManager) + order.push_back(defaultFontManager); return order; } @@ -161,11 +186,17 @@ std::shared_ptr FontCollection::GetMinikinFontCollectionForFamilies( const std::vector& font_families, const std::string& locale) { +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) + return GetMinikinFontCollectionForFamiliesWithVariation(font_families, locale); +#endif // Look inside the font collections cache first. FamilyKey family_key(font_families, locale); - auto cached = font_collections_cache_.find(family_key); - if (cached != font_collections_cache_.end()) { - return cached->second; + { + std::lock_guard lock(mutex_); + auto cached = font_collections_cache_.find(family_key); + if (cached != font_collections_cache_.end()) { + return cached->second; + } } std::vector> minikin_families; @@ -193,10 +224,12 @@ FontCollection::GetMinikinFontCollectionForFamilies( } // Default font family also not found. We fail to get a FontCollection. if (minikin_families.empty()) { + std::lock_guard lock(mutex_); font_collections_cache_[family_key] = nullptr; return nullptr; } if (enable_font_fallback_) { + std::lock_guard lock(mutex_); for (const std::string& fallback_family : fallback_fonts_for_locale_[locale]) { auto it = fallback_fonts_.find(fallback_family); @@ -317,16 +350,25 @@ std::shared_ptr FontCollection::CreateMinikinFontFamily( const std::shared_ptr& FontCollection::MatchFallbackFont( uint32_t ch, std::string locale) { +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) + return MatchFallbackFontWithVariation(ch, locale); +#endif // Check if the ch's matched font has been cached. We cache the results of // this method as repeated matchFamilyStyleCharacter calls can become // extremely laggy when typing a large number of complex emojis. - auto lookup = fallback_match_cache_.find(ch); - if (lookup != fallback_match_cache_.end()) { - return *lookup->second; + { + std::lock_guard lock(mutex_); + auto lookup = fallback_match_cache_.find(ch); + if (lookup != fallback_match_cache_.end()) { + return *lookup->second; + } } const std::shared_ptr* match = &DoMatchFallbackFont(ch, locale); - fallback_match_cache_.insert(std::make_pair(ch, match)); + { + std::lock_guard lock(mutex_); + fallback_match_cache_.insert(std::make_pair(ch, match)); + } return *match; } @@ -345,12 +387,13 @@ const std::shared_ptr& FontCollection::DoMatchFallbackFont( SkString sk_family_name; typeface->getFamilyName(&sk_family_name); std::string family_name(sk_family_name.c_str()); - - if (std::find(fallback_fonts_for_locale_[locale].begin(), - fallback_fonts_for_locale_[locale].end(), - family_name) == fallback_fonts_for_locale_[locale].end()) - fallback_fonts_for_locale_[locale].push_back(family_name); - + { + std::lock_guard lock(mutex_); + if (std::find(fallback_fonts_for_locale_[locale].begin(), + fallback_fonts_for_locale_[locale].end(), + family_name) == fallback_fonts_for_locale_[locale].end()) + fallback_fonts_for_locale_[locale].push_back(family_name); + } return GetFallbackFontFamily(manager, family_name); } return g_null_family; @@ -360,9 +403,12 @@ const std::shared_ptr& FontCollection::GetFallbackFontFamily(const sk_sp& manager, const std::string& family_name) { TRACE_EVENT0("flutter", "FontCollection::GetFallbackFontFamily"); - auto fallback_it = fallback_fonts_.find(family_name); - if (fallback_it != fallback_fonts_.end()) { - return fallback_it->second; + { + std::lock_guard lock(mutex_); + auto fallback_it = fallback_fonts_.find(family_name); + if (fallback_it != fallback_fonts_.end()) { + return fallback_it->second; + } } std::shared_ptr minikin_family = @@ -370,17 +416,18 @@ FontCollection::GetFallbackFontFamily(const sk_sp& manager, if (!minikin_family) return g_null_family; + std::lock_guard lock(mutex_); auto insert_it = - fallback_fonts_.insert(std::make_pair(family_name, minikin_family)); + fallback_fonts_.insert(std::make_pair(family_name, minikin_family)); // Clear the cache to force creation of new font collections that will // include this fallback font. font_collections_cache_.clear(); - return insert_it.first->second; } void FontCollection::ClearFontFamilyCache() { + std::lock_guard lock(mutex_); font_collections_cache_.clear(); #if FLUTTER_ENABLE_SKSHAPER @@ -390,6 +437,409 @@ void FontCollection::ClearFontFamilyCache() { #endif } +void FontCollection::VaryFontCollectionWithFontWeightScale(float font_weight_scale) { + if (font_weight_scale > 0.0f && font_weight_scale != font_weight_scale_) { + decltype(fallback_fonts_) fallback_fonts; + std::lock_guard lock(mutex_); + font_weight_scale_ = font_weight_scale; + varied_fonts_.clear(); + fallback_fonts = std::move(fallback_fonts_); + fallback_match_cache_.clear(); + fallback_fonts_for_locale_.clear(); + } +} + +void FontCollection::LoadSystemFont() { +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) + { + decltype(fallback_fonts_) fallback_fonts; + std::lock_guard lock(mutex_); + varied_fonts_.clear(); + fallback_fonts = std::move(fallback_fonts_); + fallback_match_cache_.clear(); + fallback_fonts_for_locale_.clear(); + } + + SetupDefaultFontManager(); + +#endif +} + +void FontCollection::SetIsZawgyiMyanmar(bool is_zawgyi_myanmar) { + if (is_zawgyi_myanmar_ == is_zawgyi_myanmar) { + return; + } + is_zawgyi_myanmar_ = is_zawgyi_myanmar; + LoadSystemFont(); +} + +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) +// Return the available font managers in the order they should be queried with +// type. +std::vector, txt::FontManagerType>> +FontCollection::GetFontManagerOrderWithType() const { + std::vector, txt::FontManagerType>> order; + if (dynamic_font_manager_) + order.push_back( + std::make_pair(dynamic_font_manager_, txt::FontManagerType::DYNAMIC)); + if (asset_font_manager_) + order.push_back( + std::make_pair(asset_font_manager_, txt::FontManagerType::ASSET)); + if (test_font_manager_) + order.push_back( + std::make_pair(test_font_manager_, txt::FontManagerType::TEST)); + auto defaultFontManager = GetDefaultFontManagerSafely(); + if (defaultFontManager) + order.push_back( + std::make_pair(defaultFontManager, GetDefaultFontManagerType())); + return order; +} + +std::shared_ptr +FontCollection::GetMinikinFontCollectionForFamiliesWithVariation( + const std::vector& font_families, + const std::string& locale) { + // Look inside the font collections cache first. + FamilyKey family_key(font_families, locale); + { + std::lock_guard lock(mutex_); + auto iter = std::find(varied_fonts_.begin(), varied_fonts_.end(), family_key); + if (iter != varied_fonts_.end()) { + auto cached = font_collections_cache_.find(family_key); + if (cached != font_collections_cache_.end()) { + return cached->second; + } + varied_fonts_.erase(iter); + } + } + + std::vector> minikin_families; + // Search for all user provided font families. + for (size_t fallback_index = 0; fallback_index < font_families.size(); + fallback_index++) { + std::shared_ptr minikin_family = + FindFontFamilyInManagersWithType(font_families[fallback_index]); + if (minikin_family != nullptr) { + minikin_families.push_back(minikin_family); + } + } + // Search for default font family if no user font families were found. + if (minikin_families.empty()) { + const auto default_font_family = GetDefaultFontFamily(); + std::shared_ptr minikin_family = + FindFontFamilyInManagersWithType(default_font_family); + if (minikin_family != nullptr) { + minikin_families.push_back(minikin_family); + } + } + // Default font family also not found. We fail to get a FontCollection. + if (minikin_families.empty()) { + std::shared_ptr tmp_font_collection; + std::lock_guard lock(mutex_); + std::swap(font_collections_cache_[family_key], tmp_font_collection); + return nullptr; + } + if (enable_font_fallback_) { + std::lock_guard lock(mutex_); + for (std::string fallback_family : fallback_fonts_for_locale_[locale]) { + auto it = fallback_fonts_.find(fallback_family); + if (it != fallback_fonts_.end()) { + minikin_families.push_back(it->second); + } + } + } + // Create the minikin font collection. + auto font_collection = + std::make_shared(std::move(minikin_families)); + font_collection->SetIsZawgyiMyanmar(is_zawgyi_myanmar_); + + if (enable_font_fallback_) { + font_collection->set_fallback_font_provider( + std::make_unique(shared_from_this())); + } + + { + std::shared_ptr tmp_font_collection = + font_collection; + std::lock_guard lock(mutex_); + // Cache the font collection for future queries. + std::swap(font_collections_cache_[family_key], tmp_font_collection); + varied_fonts_.emplace_back(family_key); + } + + return font_collection; +} + +std::shared_ptr +FontCollection::FindFontFamilyInManagersWithType( + const std::string& family_name) { + TRACE_EVENT0("flutter", "FontCollection::FindFontFamilyInManagersWithType"); + // Search for the font family in each font manager. + for (std::pair, FontManagerType>& managerPair : + GetFontManagerOrderWithType()) { + std::shared_ptr minikin_family; + if (managerPair.second == FontManagerType::DEFAULT_OHOS) { + minikin_family = + CreateMinikinFontFamilyForOHOS(managerPair.first, family_name); + } else { + minikin_family = + CreateMinikinFontFamilyExceptOHOS(managerPair.first, family_name); + } + if (!minikin_family) + continue; + return minikin_family; + } + return nullptr; +} + +std::shared_ptr +FontCollection::CreateMinikinFontFamilyForOHOS( + const sk_sp& manager, + const std::string& family_name) { + TRACE_EVENT1("flutter", "FontCollection::CreateMinikinFontFamilyForOHOS", + "family_name", family_name.c_str()); + sk_sp font_style_set( + manager->matchFamily(family_name.c_str())); + if (font_style_set == nullptr || font_style_set->count() == 0) { + return nullptr; + } + + auto font_style_set_ohos = + reinterpret_cast(font_style_set.get()); + if (font_style_set_ohos == nullptr) { + return CreateMinikinFontFamilyExceptOHOS(manager, family_name); + } + + std::vector> skia_typefaces; + for (int i = 0; i < font_style_set_ohos->count(); ++i) { + TRACE_EVENT0("flutter", "CreateSkiaTypeface"); + sk_sp skia_typeface( + sk_sp(font_style_set_ohos->createTypeface(i))); + float wghtValue = font_style_set_ohos->getWghtValue(i); + if (wghtValue <= 0.0f) { + wghtValue = font_style_set_ohos->getFontWeight(i); + } + VaryTypeface(skia_typeface, wghtValue); + if (skia_typeface != nullptr) { + skia_typefaces.emplace_back(std::move(skia_typeface)); + } + } + + int index = 0; + std::vector minikin_fonts; + for (const sk_sp& skia_typeface : skia_typefaces) { + // Create the minikin font from the skia typeface. + // Divide by 100 because the weights are given as "100", "200", etc. + minikin_fonts.emplace_back( + std::make_shared(skia_typeface), + minikin::FontStyle{font_style_set_ohos->getFontWeight(index++) / 100, + skia_typeface->isItalic()}); + } + + return std::make_shared(std::move(minikin_fonts)); +} + +std::shared_ptr +FontCollection::CreateMinikinFontFamilyExceptOHOS( + const sk_sp& manager, + const std::string& family_name) { + TRACE_EVENT1("flutter", + "FontCollection::CreateMinikinFontFamilyExceptOHOS", + "family_name", family_name.c_str()); + sk_sp font_style_set( + manager->matchFamily(family_name.c_str())); + if (font_style_set == nullptr || font_style_set->count() == 0) { + return nullptr; + } + + std::vector> skia_typefaces; + for (int i = 0; i < font_style_set->count(); ++i) { + TRACE_EVENT0("flutter", "CreateSkiaTypeface"); + sk_sp skia_typeface( + sk_sp(font_style_set->createTypeface(i))); + VaryTypeface(skia_typeface, skia_typeface->fontStyle().weight()); + if (skia_typeface != nullptr) { + skia_typefaces.emplace_back(std::move(skia_typeface)); + } + } + + std::sort(skia_typefaces.begin(), skia_typefaces.end(), + [](const sk_sp& a, const sk_sp& b) { + SkFontStyle a_style = a->fontStyle(); + SkFontStyle b_style = b->fontStyle(); + return (a_style.weight() != b_style.weight()) + ? a_style.weight() < b_style.weight() + : a_style.slant() < b_style.slant(); + }); + + std::vector minikin_fonts; + for (const sk_sp& skia_typeface : skia_typefaces) { + // Create the minikin font from the skia typeface. + // Divide by 100 because the weights are given as "100", "200", etc. + minikin_fonts.emplace_back( + std::make_shared(skia_typeface), + minikin::FontStyle{skia_typeface->fontStyle().weight() / 100, + skia_typeface->isItalic()}); + } + + return std::make_shared(std::move(minikin_fonts)); +} + +void FontCollection::VaryTypeface(sk_sp& typeface, float wght) { + if (font_weight_scale_ <= 0.0f) { + return; + } + // Value of wght is between 0.0f and 1000.0f, and must be greater than 0.0f, + // default value is 400.0f. + if (wght <= 0.0) { + wght = 400.0f; + } + float wghtValue = std::min(wght * font_weight_scale_, 1000.0f); + SkFontArguments params; + int ttcIndex; + std::unique_ptr stream(typeface->openStream(&ttcIndex)); + params.setCollectionIndex(ttcIndex); + std::vector variations = { + {minikin::MinikinFont::MakeTag('w', 'g', 'h', 't'), wghtValue}}; + std::vector skAxes; + skAxes.resize(variations.size()); + for (size_t i = 0; i < variations.size(); i++) { + skAxes[i].fTag = variations[i].axisTag; + skAxes[i].fStyleValue = variations[i].value; + } + params.setAxes(skAxes.data(), skAxes.size()); + sk_sp fm(SkFontMgr::RefDefault()); + typeface = fm->makeFromStream(std::move(stream), params); +} + +const std::shared_ptr& +FontCollection::MatchFallbackFontWithVariation(uint32_t ch, + std::string locale) { + { + std::lock_guard lock(mutex_); + auto lookup = fallback_match_cache_.find(ch); + if (lookup != fallback_match_cache_.end()) { + return *lookup->second; + } + } + const std::shared_ptr* match = + &DoMatchFallbackFontWithVariation(ch, locale); + { + std::lock_guard lock(mutex_); + fallback_match_cache_.insert(std::make_pair(ch, match)); + } + return *match; +} + +const std::shared_ptr& +FontCollection::DoMatchFallbackFontWithVariation(uint32_t ch, + std::string locale) { + for (const std::pair, FontManagerType>& managerPair : + GetFontManagerOrderWithType()) { + std::vector bcp47; + if (!locale.empty()) + bcp47.push_back(locale.c_str()); + + if (managerPair.second == FontManagerType::DEFAULT_OHOS) { + auto ohosManager = reinterpret_cast(managerPair.first.get()); + if (ohosManager == nullptr) + continue; + + SkString sk_family_name = ohosManager->onMatchFamilyStyleCharacterOHOS( + 0, SkFontStyle(), bcp47.data(), bcp47.size(), ch); + if(sk_family_name.isEmpty()) + continue; + + return GetFallbackFontFamilyForOHOS(managerPair.first, std::string(sk_family_name.c_str())); + } else { + sk_sp typeface(managerPair.first->matchFamilyStyleCharacter( + 0, SkFontStyle(), bcp47.data(), bcp47.size(), ch)); + if (!typeface) + continue; + + SkString sk_family_name; + typeface->getFamilyName(&sk_family_name); + std::string family_name(sk_family_name.c_str()); + + { + std::lock_guard lock(mutex_); + fallback_fonts_for_locale_[locale].insert(family_name); + } + + return GetFallbackFontFamily(managerPair.first, family_name); + } + } + return g_null_family; +} + +const std::shared_ptr& +FontCollection::GetFallbackFontFamilyForOHOS( + const sk_sp& manager, + const std::string& family_name) { + TRACE_EVENT0("flutter", "FontCollection::GetFallbackFontFamily"); + { + std::lock_guard lock(mutex_); + auto fallback_it = fallback_fonts_.find(family_name); + if (fallback_it != fallback_fonts_.end()) { + return fallback_it->second; + } + } + + std::shared_ptr minikin_family = + CreateMinikinFontFamilyForOHOS(manager, family_name); + if (!minikin_family) { + minikin_family = CreateMinikinFontFamilyExceptOHOS(manager, family_name); + } + if (!minikin_family) + return g_null_family; + + { + decltype(font_collections_cache_) font_collections_cache; + std::lock_guard lock(mutex_); + auto insert_it = + fallback_fonts_.insert(std::make_pair(family_name, minikin_family)); + + // Clear the cache to force creation of new font collections that will + // include this fallback font. + std::swap(font_collections_cache_, font_collections_cache); + + return insert_it.first->second; + } +} + +const std::shared_ptr& FontCollection::MatchFallbackFontFromHwFont( + uint32_t ch, + std::string locale) { + const std::shared_ptr* match = + &DoMatchFallbackFontFromHwFont(ch, locale); + return *match; +} + +const std::shared_ptr& +FontCollection::DoMatchFallbackFontFromHwFont(uint32_t ch, + std::string locale) { + for (const std::pair, FontManagerType>& managerPair : + GetFontManagerOrderWithType()) { + std::vector bcp47; + if (!locale.empty()) + bcp47.push_back(locale.c_str()); + + if (managerPair.second == FontManagerType::DEFAULT_OHOS) { + auto ohosManager = reinterpret_cast(managerPair.first.get()); + if (ohosManager == nullptr) + continue; + + SkString sk_family_name = ohosManager->onMatchFamilyStyleCharacterHwFont( + 0, SkFontStyle(), bcp47.data(), bcp47.size(), ch); + if(sk_family_name.isEmpty()) + continue; + + return GetFallbackFontFamilyForOHOS(managerPair.first, std::string(sk_family_name.c_str())); + } + } + return g_null_family; +} +#endif #if FLUTTER_ENABLE_SKSHAPER sk_sp @@ -401,7 +851,7 @@ FontCollection::CreateSktFontCollection() { for (const std::string& family : GetDefaultFontFamilies()) { default_font_families.emplace_back(family); } - skt_collection_->setDefaultFontManager(default_font_manager_, + skt_collection_->setDefaultFontManager(GetDefaultFontManagerSafely(), default_font_families); skt_collection_->setAssetFontManager(asset_font_manager_); skt_collection_->setDynamicFontManager(dynamic_font_manager_); diff --git a/txt/src/txt/font_collection.h b/txt/src/txt/font_collection.h index 315734c74d3daa612eb93dc5a7a2724ed4f796aa..e6f890c9e7c9d78c80fb537c92a777d1bf59f1e7 100644 --- a/txt/src/txt/font_collection.h +++ b/txt/src/txt/font_collection.h @@ -18,6 +18,7 @@ #define LIB_TXT_SRC_FONT_COLLECTION_H_ #include +#include #include #include #include @@ -29,6 +30,7 @@ #include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "txt/asset_font_manager.h" +#include "txt/platform.h" #include "txt/text_style.h" #if FLUTTER_ENABLE_SKSHAPER @@ -68,6 +70,13 @@ class FontCollection : public std::enable_shared_from_this { // Remove all entries in the font family cache. void ClearFontFamilyCache(); + // Vary font collection with font weight scale. + void VaryFontCollectionWithFontWeightScale(float font_weight_scale); + + void LoadSystemFont(); + + void SetIsZawgyiMyanmar(bool is_zawgyi_myanmar); + #if FLUTTER_ENABLE_SKSHAPER // Construct a Skia text layout FontCollection based on this collection. @@ -75,6 +84,12 @@ class FontCollection : public std::enable_shared_from_this { #endif // FLUTTER_ENABLE_SKSHAPER +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) + const std::shared_ptr& MatchFallbackFontFromHwFont( + uint32_t ch, + std::string locale); +#endif + private: struct FamilyKey { FamilyKey(const std::vector& families, const std::string& loc); @@ -107,6 +122,12 @@ class FontCollection : public std::enable_shared_from_this { std::unordered_map> fallback_fonts_for_locale_; bool enable_font_fallback_; + bool is_zawgyi_myanmar_ = false; // whether encoding of Burmese is zawgyi, not unicode. + float font_weight_scale_ = 1.0f; + std::vector varied_fonts_; + + std::mutex mutex_; + mutable std::mutex fontManagerMutex_; #if FLUTTER_ENABLE_SKSHAPER // An equivalent font collection usable by the Skia text shaper library. @@ -137,6 +158,51 @@ class FontCollection : public std::enable_shared_from_this { const sk_sp& manager, const std::string& family_name); + sk_sp GetDefaultFontManagerSafely() const; + +#if defined(OHOS_PLATFORM) && !defined(OHOS_STANDARD_SYSTEM) + std::shared_ptr + GetMinikinFontCollectionForFamiliesWithVariation( + const std::vector& font_families, + const std::string& locale); + + std::vector, txt::FontManagerType>> + GetFontManagerOrderWithType() const; + + std::shared_ptr FindFontFamilyInManagersWithType( + const std::string& family_name); + + std::shared_ptr CreateMinikinFontFamilyForOHOS( + const sk_sp& manager, + const std::string& family_name); + + std::shared_ptr CreateMinikinFontFamilyExceptOHOS( + const sk_sp& manager, + const std::string& family_name); + + void VaryTypeface(sk_sp& typeface, float wght); + + // Provides a FontFamily that contains glyphs for ch. This caches previously + // matched fonts. Also see FontCollection::DoMatchFallbackFontWithVariation. + const std::shared_ptr& MatchFallbackFontWithVariation( + uint32_t ch, + std::string locale); + + // Performs the actual work of MatchFallbackFont. The result is cached in + // fallback_match_cache_. + const std::shared_ptr& DoMatchFallbackFontWithVariation( + uint32_t ch, + std::string locale); + + const std::shared_ptr& GetFallbackFontFamilyForOHOS( + const sk_sp& manager, + const std::string& family_name); + + const std::shared_ptr& DoMatchFallbackFontFromHwFont( + uint32_t ch, + std::string locale); +#endif + FML_DISALLOW_COPY_AND_ASSIGN(FontCollection); }; diff --git a/txt/src/txt/platform.cc b/txt/src/txt/platform.cc index c60731b3758b5a544b0a53ec83950ea0598da09f..2f03e908a8ad4ebcef9c78bfe0cc1374d9999f2e 100644 --- a/txt/src/txt/platform.cc +++ b/txt/src/txt/platform.cc @@ -14,4 +14,8 @@ sk_sp GetDefaultFontManager() { return SkFontMgr::RefDefault(); } +FontManagerType GetDefaultFontManagerType() { + return FontManagerType::DEFAULT_OHOS; +} + } // namespace txt diff --git a/txt/src/txt/platform.h b/txt/src/txt/platform.h index cffe9280ea5c92a585f993745ae085349499913c..eeab6d0f99e67af0f66e3a9ea517f8a0444050dd 100644 --- a/txt/src/txt/platform.h +++ b/txt/src/txt/platform.h @@ -13,10 +13,21 @@ namespace txt { +enum FontManagerType { + DYNAMIC = 0, + ASSET = 1, + TEST = 2, + DEFAULT_OHOS = 3, + DEFAULT_ANDROID = 4, + NONE = 5, +}; + std::vector GetDefaultFontFamilies(); sk_sp GetDefaultFontManager(); +FontManagerType GetDefaultFontManagerType(); + } // namespace txt #endif // TXT_PLATFORM_H_ diff --git a/txt/src/txt/platform_linux.cc b/txt/src/txt/platform_linux.cc index 9e13898d49e7ad39a3d6b85bc0ba99cc7b165d46..d671fef20133ded9898960b2d4445722e928e4b9 100644 --- a/txt/src/txt/platform_linux.cc +++ b/txt/src/txt/platform_linux.cc @@ -4,6 +4,11 @@ #include "txt/platform.h" +#if defined(SK_BUILD_FONT_MGR_FOR_PREVIEW_LINUX) +#include "include/core/SkFontMgr.h" + +#endif + #ifdef FLUTTER_USE_FONTCONFIG #include "third_party/skia/include/ports/SkFontMgr_fontconfig.h" #else @@ -12,13 +17,27 @@ namespace txt { +#if defined(SK_BUILD_FONT_MGR_FOR_PREVIEW_LINUX) +std::vector GetDefaultFontFamilies() +{ + if (SkFontMgr::runtimeOS == "OHOS") { + return {"HarmonyOS-Sans"}; + } + if (SkFontMgr::runtimeOS == "OHOS_Container") { + return {"sans-serif"}; + } + return {"Ubuntu", "Cantarell", "DejaVu Sans", "Liberation Sans", "Arial"};; +} +#else std::vector GetDefaultFontFamilies() { return {"Ubuntu", "Cantarell", "DejaVu Sans", "Liberation Sans", "Arial"}; -} - -sk_sp GetDefaultFontManager() { -#ifdef FLUTTER_USE_FONTCONFIG - return SkFontMgr_New_FontConfig(nullptr); +#endif +sk_sp GetDefaultFontManager() +{ +#ifdef SK_BUILD_FONT_MGR_FOR_PREVIEW_LINUX + return SkFontMgr::RefDefault(); +#elif FLUTTER_USE_FONTCONFIG + return SkFontMgr_New_FontConfig(nullptr); #else return SkFontMgr_New_Custom_Directory("/usr/share/fonts/"); #endif diff --git a/txt/src/txt/platform_mac.mm b/txt/src/txt/platform_mac.mm index 794a22cadb77127ebbe4905a625c80b8c2415bfa..0a0c697ff6c3153f352310bfc9f36c0ca7d82923 100644 --- a/txt/src/txt/platform_mac.mm +++ b/txt/src/txt/platform_mac.mm @@ -15,8 +15,21 @@ #define FONT_CLASS NSFont #endif // TARGET_OS_EMBEDDED +#if defined(SK_BUILD_FONT_MGR_FOR_PREVIEW_MAC) +#include "include/core/SkFontMgr.h" +#endif + namespace txt { +#if defined(SK_BUILD_FONT_MGR_FOR_PREVIEW_MAC) +std::vector GetDefaultFontFamilies() { + if (SkFontMgr::runtimeOS == "OHOS") { + return {"HarmonyOS-Sans"}; + } + if (SkFontMgr::runtimeOS == "OHOS_Container") { + return {"sans-serif"}; + } +#else std::vector GetDefaultFontFamilies() { if (fml::IsPlatformVersionAtLeast(9)) { return {[FONT_CLASS systemFontOfSize:14].familyName.UTF8String}; @@ -24,7 +37,7 @@ std::vector GetDefaultFontFamilies() { return {"Helvetica"}; } } - +#endif sk_sp GetDefaultFontManager() { return SkFontMgr::RefDefault(); } diff --git a/txt/src/txt/platform_ohos.cc b/txt/src/txt/platform_ohos.cc new file mode 100644 index 0000000000000000000000000000000000000000..8136966d307431f0e2523a777975111e4e807cc0 --- /dev/null +++ b/txt/src/txt/platform_ohos.cc @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// 2021.2.10 Framework adapted on ACE. +// Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +#include "txt/platform.h" + +#ifndef OHOS_STANDARD_SYSTEM +#include "third_party/skia/src/ports/SkFontMgr_ohos.h" +#endif + +namespace txt { + +std::vector GetDefaultFontFamilies() { +#ifdef OHOS_STANDARD_SYSTEM + return {"HarmonyOS-Sans"}; +#else + return "sans-serif"; +#endif +} + +sk_sp GetDefaultFontManager() { +#ifdef OHOS_STANDARD_SYSTEM + return SkFontMgr::RefDefault(); +#else + return SkFontMgr_New_OHOS(); +#endif +} + +FontManagerType GetDefaultFontManagerType() { + return FontManagerType::DEFAULT_OHOS; +} + +} // namespace txt