1 // Copyright 2019 Google LLC.
2 #ifndef FontCollection_DEFINED
3 #define FontCollection_DEFINED
4 
5 #include <memory>
6 #include <mutex>
7 #include <optional>
8 #include <set>
9 #include <shared_mutex>
10 #include <unordered_map>
11 #include "include/core/SkFontMgr.h"
12 #include "include/core/SkRefCnt.h"
13 #include "modules/skparagraph/include/FontArguments.h"
14 #include "modules/skparagraph/include/ParagraphCache.h"
15 #include "modules/skparagraph/include/TextStyle.h"
16 #include "include/private/SkTHash.h"
17 #include "drawing.h"
18 
19 namespace skia {
20 namespace textlayout {
21 
22 class TextStyle;
23 class Paragraph;
24 class FontCollection : public SkRefCnt {
25 public:
26     FontCollection();
27 
28     size_t getFontManagersCount() const;
29 
30 #ifndef USE_SKIA_TXT
31     void setAssetFontManager(sk_sp<SkFontMgr> fontManager);
32     void setDynamicFontManager(sk_sp<SkFontMgr> fontManager);
33     void setTestFontManager(sk_sp<SkFontMgr> fontManager);
34     void setDefaultFontManager(sk_sp<SkFontMgr> fontManager);
35     void setDefaultFontManager(sk_sp<SkFontMgr> fontManager, const char defaultFamilyName[]);
36     void setDefaultFontManager(sk_sp<SkFontMgr> fontManager, const std::vector<SkString>& defaultFamilyNames);
37 
getFallbackManager() const38     sk_sp<SkFontMgr> getFallbackManager() const
39     {
40         std::shared_lock<std::shared_mutex> readLock(mutex_);
41         return fDefaultFontManager;
42     }
43 
44     std::vector<sk_sp<SkTypeface>> findTypefaces(const std::vector<SkString>& familyNames, SkFontStyle fontStyle);
45     std::vector<sk_sp<SkTypeface>> findTypefaces(const std::vector<SkString>& familyNames, SkFontStyle fontStyle, const std::optional<FontArguments>& fontArgs);
46 
47     sk_sp<SkTypeface> defaultFallback(SkUnichar unicode, SkFontStyle fontStyle, const SkString& locale);
48     sk_sp<SkTypeface> defaultFallback();
49 #else
50     void setAssetFontManager(std::shared_ptr<RSFontMgr> fontManager);
51     void setDynamicFontManager(std::shared_ptr<RSFontMgr> fontManager);
52     void setTestFontManager(std::shared_ptr<RSFontMgr> fontManager);
53     void setDefaultFontManager(std::shared_ptr<RSFontMgr> fontManager);
54     void setDefaultFontManager(std::shared_ptr<RSFontMgr> fontManager, const char defaultFamilyName[]);
55     void setDefaultFontManager(std::shared_ptr<RSFontMgr> fontManager, const std::vector<SkString>& defaultFamilyNames);
56 
getFallbackManager() const57     std::shared_ptr<RSFontMgr> getFallbackManager() const
58     {
59         std::shared_lock<std::shared_mutex> readLock(mutex_);
60         return fDefaultFontManager;
61     }
62 
63     std::vector<std::shared_ptr<RSTypeface>> findTypefaces(
64         const std::vector<SkString>& familyNames, RSFontStyle fontStyle);
65     std::vector<std::shared_ptr<RSTypeface>> findTypefaces(
66         const std::vector<SkString>& familyNames, RSFontStyle fontStyle, const std::optional<FontArguments>& fontArgs);
67 
68     std::shared_ptr<RSTypeface> defaultFallback(SkUnichar unicode, RSFontStyle fontStyle, const SkString& locale);
69     std::shared_ptr<RSTypeface> defaultFallback();
70 #endif
71 
72 #ifndef USE_SKIA_TXT
73     sk_sp<SkTypeface> CloneTypeface(sk_sp<SkTypeface> typeface,
74         const std::optional<FontArguments>& fontArgs);
75 #else
76     std::shared_ptr<RSTypeface> CloneTypeface(std::shared_ptr<RSTypeface> typeface,
77         const std::optional<FontArguments>& fontArgs);
78 #endif
79 
80     void disableFontFallback();
81     void enableFontFallback();
fontFallbackEnabled()82     bool fontFallbackEnabled()
83     {
84         std::shared_lock<std::shared_mutex> readLock(mutex_);
85         return fEnableFontFallback;
86     }
87 
getParagraphCache()88     ParagraphCache* getParagraphCache()
89     {
90         std::shared_lock<std::shared_mutex> readLock(mutex_);
91         return &fParagraphCache;
92     }
93 
94     void clearCaches();
95 
96 #ifdef OHOS_SUPPORT
97     // set fIsAdpaterTextHeightEnabled with once_flag.
SetAdapterTextHeightEnabled(bool adapterTextHeightEnabled)98     static void SetAdapterTextHeightEnabled(bool adapterTextHeightEnabled)
99     {
100         static std::once_flag flag;
101         std::call_once(flag, [adapterTextHeightEnabled]() {
102             fIsAdpaterTextHeightEnabled = adapterTextHeightEnabled;
103         });
104     }
105 
IsAdapterTextHeightEnabled()106     static bool IsAdapterTextHeightEnabled()
107     {
108         return fIsAdpaterTextHeightEnabled;
109     }
110 #endif
111 private:
112 #ifndef USE_SKIA_TXT
113     std::vector<sk_sp<SkFontMgr>> getFontManagerOrder() const;
114 
115     sk_sp<SkTypeface> matchTypeface(const SkString& familyName, SkFontStyle fontStyle);
116 #else
117     std::vector<std::shared_ptr<RSFontMgr>> getFontManagerOrder() const;
118 
119     std::shared_ptr<RSTypeface> matchTypeface(const SkString& familyName, RSFontStyle fontStyle);
120 #endif
121 
122     struct FamilyKey {
123 #ifndef USE_SKIA_TXT
FamilyKeyskia::textlayout::FontCollection::FamilyKey124         FamilyKey(const std::vector<SkString>& familyNames, SkFontStyle style, const std::optional<FontArguments>& args)
125                 : fFamilyNames(familyNames), fFontStyle(style), fFontArguments(args) {}
126 #else
127         FamilyKey(
128             const std::vector<SkString>& familyNames, RSFontStyle style, const std::optional<FontArguments>& args)
129                 : fFamilyNames(familyNames), fFontStyle(style), fFontArguments(args) {}
130 #endif
131 
FamilyKeyskia::textlayout::FontCollection::FamilyKey132         FamilyKey() {}
133 
134         std::vector<SkString> fFamilyNames;
135 #ifndef USE_SKIA_TXT
136         SkFontStyle fFontStyle;
137 #else
138         RSFontStyle fFontStyle;
139 #endif
140         std::optional<FontArguments> fFontArguments;
141 
142         bool operator==(const FamilyKey& other) const;
143 
144         struct Hasher {
145             size_t operator()(const FamilyKey& key) const;
146         };
147     };
148 #ifdef OHOS_SUPPORT
149     static bool fIsAdpaterTextHeightEnabled;
150 #endif
151 
152     bool fEnableFontFallback;
153 #ifndef USE_SKIA_TXT
154     SkTHashMap<FamilyKey, std::vector<sk_sp<SkTypeface>>, FamilyKey::Hasher> fTypefaces;
155     sk_sp<SkFontMgr> fDefaultFontManager;
156     sk_sp<SkFontMgr> fAssetFontManager;
157     sk_sp<SkFontMgr> fDynamicFontManager;
158     sk_sp<SkFontMgr> fTestFontManager;
159 #else
160     std::unordered_map<FamilyKey, std::vector<std::shared_ptr<RSTypeface>>, FamilyKey::Hasher> fTypefaces;
161     std::shared_ptr<RSFontMgr> fDefaultFontManager;
162     std::shared_ptr<RSFontMgr> fAssetFontManager;
163     std::shared_ptr<RSFontMgr> fDynamicFontManager;
164     std::shared_ptr<RSFontMgr> fTestFontManager;
165 #endif
166     std::mutex fMutex;
167     std::vector<SkString> fDefaultFamilyNames;
168     ParagraphCache fParagraphCache;
169     mutable std::shared_mutex mutex_;
170 };
171 }  // namespace textlayout
172 }  // namespace skia
173 
174 #endif  // FontCollection_DEFINED
175