1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkFontMgr_ohos_DEFINED 9 #define SkFontMgr_ohos_DEFINED 10 11 #include <algorithm> 12 #include <map> 13 #include <mutex> 14 #include <string> 15 #include <vector> 16 17 #include "include/core/SkFontMgr.h" 18 #include "include/core/SkFontStyle.h" 19 #include "include/core/SkRefCnt.h" 20 #include "include/core/SkStream.h" 21 #include "include/core/SkString.h" 22 #include "include/core/SkTypeface.h" 23 #include "include/private/SkTArray.h" 24 25 class SkFontMgr; 26 27 enum FontVariants { 28 kNone_FontVariant = 0, 29 kCompact_FontVariant = 1, 30 kElegant_FontVariant = 2, 31 kLast_FontVariant = kElegant_FontVariant, 32 }; 33 typedef uint32_t FontVariant; 34 35 struct FontVariationAxis { 36 std::string tag; 37 float value; 38 }; 39 40 struct FontFamilyItem { 41 SkTypeface* typeface; 42 std::string lang; 43 int weight; 44 int index; 45 int variant; 46 std::vector<FontVariationAxis> variationAxes; 47 int hwFontFamilyType; 48 }; 49 50 struct FamilyAliasObj { 51 std::string toName; 52 int weight; 53 }; 54 55 class SkTypeface_OHOS : public SkWeakRefCnt { 56 public: SkTypeface_OHOS(SkTypeface * typeface,const std::string & familyName,const std::string & lang,FontVariant variantStyle,const std::vector<FontVariationAxis> & variationAxes,int fontWeight,int hwFontFamilyType)57 SkTypeface_OHOS(SkTypeface* typeface, 58 const std::string& familyName, 59 const std::string& lang, 60 FontVariant variantStyle, 61 const std::vector<FontVariationAxis>& variationAxes, 62 int fontWeight, 63 int hwFontFamilyType) 64 : fTypeface(typeface) 65 , fLang(lang) 66 , fVariantStyle(variantStyle) 67 , fFamilyName(familyName.c_str()) 68 , variationAxes(variationAxes) 69 , fontWeight(fontWeight) 70 , hwFontFamilyType(hwFontFamilyType) 71 { } 72 73 ~SkTypeface_OHOS() override = default; 74 getFamilyName()75 const SkString& getFamilyName() const { 76 return fFamilyName; 77 } 78 getFontVariant()79 FontVariant getFontVariant() const { 80 return fVariantStyle; 81 } 82 getFontVariationAxes()83 const std::vector<FontVariationAxis>& getFontVariationAxes() const { 84 return variationAxes; 85 } 86 getWghtValue()87 float getWghtValue() const { 88 for (auto axis : variationAxes) { 89 if (axis.tag == "wght") { 90 return axis.value; 91 } 92 } 93 return 0.0f; 94 } 95 getFontWeight()96 int getFontWeight() const { 97 return fontWeight; 98 } 99 getLangTag()100 const std::string getLangTag() const { 101 return fLang; 102 } 103 getHwFontFamilyType()104 int getHwFontFamilyType() const { 105 return hwFontFamilyType; 106 } 107 108 protected: 109 SkTypeface* fTypeface = nullptr; 110 std::string fLang; 111 const FontVariant fVariantStyle = kNone_FontVariant; 112 SkString fFamilyName; 113 std::vector<FontVariationAxis> variationAxes; 114 int fontWeight = 400; // default font weight is 400. 115 int hwFontFamilyType = 0; 116 }; 117 118 class SkLanguage { 119 public: SkLanguage()120 SkLanguage() { } SkLanguage(const SkString & tag)121 SkLanguage(const SkString& tag) : fTag(tag) { } SkLanguage(const char * tag)122 SkLanguage(const char* tag) : fTag(tag) { } SkLanguage(const char * tag,size_t len)123 SkLanguage(const char* tag, size_t len) : fTag(tag, len) { } SkLanguage(const SkLanguage & b)124 SkLanguage(const SkLanguage& b) : fTag(b.fTag) { } 125 ~SkLanguage() = default; 126 127 /** Gets a BCP 47 language identifier for this SkLanguage. 128 @return a BCP 47 language identifier representing this language 129 */ getTag()130 const SkString& getTag() const { return fTag; } 131 132 /** Performs BCP 47 fallback to return an SkLanguage one step more general. 133 @return an SkLanguage one step more general 134 */ getParent()135 SkLanguage getParent() const { 136 SkASSERT(!fTag.isEmpty()); 137 const char* tag = fTag.c_str(); 138 139 // strip off the rightmost "-.*" 140 const char* parentTagEnd = strrchr(tag, '-'); 141 if (parentTagEnd == nullptr) { 142 return SkLanguage(); 143 } 144 size_t parentTagLen = parentTagEnd - tag; 145 return SkLanguage(tag, parentTagLen); 146 } 147 148 bool operator==(const SkLanguage& b) const { 149 return fTag == b.fTag; 150 } 151 bool operator!=(const SkLanguage& b) const { 152 return fTag != b.fTag; 153 } 154 SkLanguage& operator=(const SkLanguage& b) { 155 fTag = b.fTag; 156 return *this; 157 } 158 159 private: 160 //! BCP 47 language identifier 161 SkString fTag; 162 }; 163 164 class SkFontStyleSet_OHOS : public SkFontStyleSet { 165 public: 166 SkFontStyleSet_OHOS(const std::vector<FontFamilyItem>& items, bool fallback = false) { 167 for (size_t i = 0; i < items.size(); ++i) { 168 const auto& item = items[i]; 169 auto typeface = item.typeface; 170 int fontWeight = item.weight; 171 fStyles.push_back().reset(SkRef(typeface)); 172 SkString skFamilyName; 173 typeface->getFamilyName(&skFamilyName); 174 std::string familyName(skFamilyName.c_str()); 175 std::transform(familyName.begin(), familyName.end(), familyName.begin(), 176 [](unsigned char c) -> unsigned char { return std::tolower(c); }); 177 std::vector<FontVariationAxis> variationAxis; 178 if (item.variationAxes.size() > 0) { 179 for (size_t index = 0; index < item.variationAxes.size(); ++index) { 180 auto variationAxes = item.variationAxes[index]; 181 variationAxis.push_back({ .tag = variationAxes.tag, .value = variationAxes.value }); 182 } 183 } 184 fStylesHost.push_back().reset(new SkTypeface_OHOS( 185 item.typeface, familyName, item.lang, item.variant, 186 variationAxis, fontWeight, item.hwFontFamilyType)); 187 } 188 } 189 190 ~SkFontStyleSet_OHOS() override = default; 191 count()192 int count() override { 193 return fStyles.count(); 194 } 195 getStyle(int index,SkFontStyle * style,SkString * name)196 void getStyle(int index, SkFontStyle* style, SkString* name) override { 197 if (index < 0 || fStyles.count() <= index) { 198 return; 199 } 200 if (style) { 201 *style = fStyles[index]->fontStyle(); 202 } 203 if (name) { 204 name->reset(); 205 } 206 } 207 createTypeface(int index)208 SkTypeface* createTypeface(int index) override { 209 if (index < 0 || fStyles.count() <= index) { 210 return nullptr; 211 } 212 return SkRef(fStyles[index].get()); 213 } 214 matchStyle(const SkFontStyle & pattern)215 SkTypeface* matchStyle(const SkFontStyle& pattern) override { 216 return static_cast<SkTypeface*>(matchStyleCSS3(pattern)); 217 } 218 haveVariant(FontVariant variant)219 bool haveVariant(FontVariant variant) { 220 for (int i = 0; i < fStylesHost.count(); ++i) { 221 if (fStylesHost[i]->getFontVariant() == variant) { 222 return true; 223 } 224 } 225 return false; 226 } 227 getWghtValue(int index)228 float getWghtValue(int index) { 229 if (index < 0 || fStylesHost.count() <= index) { 230 return 0.0f; 231 } 232 return fStylesHost[index]->getWghtValue(); 233 } 234 getFontWeight(int index)235 int getFontWeight(int index) { 236 if (index < 0 || fStylesHost.count() <= index) { 237 return 400; 238 } 239 return fStylesHost[index]->getFontWeight(); 240 } 241 matchLanguage(const SkString & lang)242 bool matchLanguage(const SkString& lang) { 243 for (int i = 0; i < fStylesHost.count(); ++i) { 244 SkString langTag(fStylesHost[i]->getLangTag().c_str()); 245 if (langTag.startsWith(lang.c_str())) { 246 return true; 247 } 248 } 249 return false; 250 } 251 getHwFontFamilyType()252 int getHwFontFamilyType() { 253 if (fStylesHost.count() <= 0) { 254 return 0; 255 } 256 return fStylesHost[0]->getHwFontFamilyType(); 257 } 258 259 private: 260 SkTArray<sk_sp<SkTypeface>> fStyles; 261 SkTArray<sk_sp<SkTypeface_OHOS>> fStylesHost; 262 SkString fFallbackFor; 263 264 friend struct NameToFamily; 265 friend class SkFontMgr_OHOS; 266 267 typedef SkFontStyleSet INHERITED; 268 }; 269 270 struct NameToFamily { 271 SkString name; 272 SkFontStyleSet_OHOS* styleSet; 273 }; 274 275 SK_API sk_sp<SkFontMgr> SkFontMgr_New_OHOS(); 276 277 class SkFontMgr_OHOS : public SkFontMgr { 278 public: 279 using BuildFamilyMapCallback = std::function<void(SkTArray<NameToFamily, true>&, 280 SkTArray<NameToFamily, true>&, 281 SkTArray<sk_sp<SkFontStyleSet_OHOS>>&, 282 std::map<std::string, FamilyAliasObj>&)>; 283 284 SkFontMgr_OHOS(); 285 ~SkFontMgr_OHOS() override = default; 286 287 SkString onMatchFamilyStyleCharacterOHOS(const char familyName[], 288 const SkFontStyle& style, 289 const char* bcp47[], 290 int bcp47Count, 291 SkUnichar character); 292 293 SkString onMatchFamilyStyleCharacterHwFont(const char familyName[], 294 const SkFontStyle& style, 295 const char* bcp47[], 296 int bcp47Count, 297 SkUnichar character); 298 setBuildFamilyMapCallback(BuildFamilyMapCallback && callback)299 static void setBuildFamilyMapCallback(BuildFamilyMapCallback&& callback) { 300 buildFamilyMapCallback = std::move(callback); 301 } 302 303 protected: 304 int onCountFamilies() const override; 305 void onGetFamilyName(int index, SkString* familyName) const override; 306 SkFontStyleSet* onCreateStyleSet(int index) const override; 307 SkFontStyleSet* onMatchFamily(const char familyName[]) const override; 308 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], 309 const SkFontStyle& style) const override; 310 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* typeface, 311 const SkFontStyle& style) const override; 312 313 static sk_sp<SkTypeface> find_family_style_character( 314 const SkString& familyName, 315 const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap, 316 const SkFontStyle& style, bool elegant, 317 const SkString& langTag, SkUnichar character); 318 319 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], 320 const SkFontStyle& style, 321 const char* bcp47[], 322 int bcp47Count, 323 SkUnichar character) const override; 324 sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override; 325 sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override; 326 sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, 327 int ttcIndex) const override; 328 sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream, 329 const SkFontArguments& args) const override; 330 sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData> data) const override; 331 sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override; 332 333 private: 334 void buildNameToFamilyMap(); 335 void findDefaultStyleSet(); 336 static BuildFamilyMapCallback buildFamilyMapCallback; 337 SkString find_family_style_character_ohos( 338 const SkString& familyName, 339 const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap, 340 const SkFontStyle& style, bool elegant, 341 const SkString& langTag, SkUnichar character); 342 SkString find_family_style_character_hwfont( 343 const SkString& familyName, 344 const SkTArray<NameToFamily, true>& fallbackNameToFamilyMap, 345 const SkFontStyle& style, bool elegant, 346 const SkString& langTag, SkUnichar character); 347 void addToCache(const NameToFamily* item); 348 SkString findFromCache(const SkString& familyName, const SkFontStyle& style, bool elegant, 349 const SkString& langTag, SkUnichar character); 350 351 void addToHwFontCache(const NameToFamily* item); 352 SkString findFromHwFontCache(const SkString& familyName, const SkFontStyle& style, bool elegant, 353 const SkString& langTag, SkUnichar character); 354 355 SkTArray<sk_sp<SkFontStyleSet_OHOS>> fStyleSets; 356 sk_sp<SkFontStyleSet> fDefaultStyleSet; 357 358 std::mutex mutexCache; 359 SkTArray<const NameToFamily*, true> familyMapCache; 360 SkTArray<const NameToFamily*, true> hwFontFamilyMapCache; 361 SkTArray<NameToFamily, true> fNameToFamilyMap; 362 SkTArray<NameToFamily, true> fFallbackNameToFamilyMap; 363 std::map<std::string, FamilyAliasObj> fAliasMap; 364 365 typedef SkFontMgr INHERITED; 366 }; 367 368 #endif // SkFontMgr_ohos_DEFINED 369