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 * 2021.9.9 SkFontMgr on previewer of ohos. 7 * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. 8 */ 9 10 #ifndef SkFontMgr_preview_DEFINED 11 #define SkFontMgr_preview_DEFINED 12 13 #include "include/core/SkFontMgr.h" 14 #include "include/core/SkData.h" 15 #include "include/core/SkFontStyle.h" 16 #include "include/core/SkRefCnt.h" 17 #include "include/core/SkStream.h" 18 #include "include/core/SkString.h" 19 #include "include/core/SkTypeface.h" 20 #include "src/core/SkFontDescriptor.h" 21 #include "src/core/SkOSFile.h" 22 #include "src/ports/SkFontHost_FreeType_common.h" 23 #include "src/ports/SkFontMgr_config_parser.h" 24 #include "SkTypeface_FreeType.h" 25 #include "src/ports/SkFontScanner_FreeType_priv.h" 26 #include "include/private/base/SkTArray.h" 27 #include "include/private/base/SkTDArray.h" 28 #include "include/private/base/SkFixed.h" 29 #include "include/private/base/SkTemplates.h" 30 31 class SkData; 32 33 class SkTypeface_Preview : public SkTypeface_FreeType { 34 public: SkTypeface_Preview(const SkFontStyle & style,bool isFixedPitch,const SkString & familyName)35 SkTypeface_Preview(const SkFontStyle& style, 36 bool isFixedPitch, 37 const SkString& familyName) 38 : INHERITED(style, isFixedPitch) 39 , fFamilyName(familyName) 40 { } 41 42 ~SkTypeface_Preview() override = default; 43 44 protected: onGetFamilyName(SkString * familyName)45 void onGetFamilyName(SkString* familyName) const override 46 { 47 *familyName = fFamilyName; 48 } 49 50 SkString fFamilyName; 51 52 private: 53 typedef SkTypeface_FreeType INHERITED; 54 }; 55 56 class SkTypeface_PreviewSystem : public SkTypeface_Preview { 57 public: SkTypeface_PreviewSystem(const SkString & pathName,int index,const SkFixed * axes,int axesCount,const SkFontStyle & style,bool isFixedPitch,const SkString & familyName,const skia_private::TArray<SkLanguage,true> & lang,FontVariant variantStyle)58 SkTypeface_PreviewSystem(const SkString& pathName, 59 int index, 60 const SkFixed* axes, int axesCount, 61 const SkFontStyle& style, 62 bool isFixedPitch, 63 const SkString& familyName, 64 const skia_private::TArray<SkLanguage, true>& lang, 65 FontVariant variantStyle) 66 : INHERITED(style, isFixedPitch, familyName) 67 , fPathName(pathName) 68 , fIndex(index) 69 , fAxes(axes, axesCount) 70 , fLang(lang) 71 , fVariantStyle(variantStyle) 72 , fFile(nullptr) 73 { } 74 75 ~SkTypeface_PreviewSystem() override = default; 76 makeStream()77 std::unique_ptr<SkStreamAsset> makeStream() const 78 { 79 if (fFile) { 80 sk_sp<SkData> data(SkData::MakeFromFILE(fFile)); 81 return data ? std::make_unique<SkMemoryStream>(std::move(data)) : nullptr; 82 } 83 return SkStream::MakeFromFile(fPathName.c_str()); 84 } 85 onGetFontDescriptor(SkFontDescriptor * desc,bool * serialize)86 virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override 87 { 88 SkASSERT(desc); 89 SkASSERT(serialize); 90 desc->setFamilyName(fFamilyName.c_str()); 91 desc->setStyle(this->fontStyle()); 92 *serialize = false; 93 } 94 onOpenStream(int * ttcIndex)95 std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override 96 { 97 *ttcIndex = fIndex; 98 return this->makeStream(); 99 } 100 onMakeFontData()101 std::unique_ptr<SkFontData> onMakeFontData() const override 102 { 103 return std::make_unique<SkFontData>(this->makeStream(), fIndex, 0, fAxes.begin(), fAxes.size(), nullptr, 0); 104 } 105 onMakeClone(const SkFontArguments & args)106 sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override 107 { 108 SkFontStyle style = this->fontStyle(); 109 std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style); 110 if (!data) { 111 return nullptr; 112 } 113 return sk_make_sp<SkTypeface_PreviewSystem>(fPathName, 114 fIndex, 115 data->getAxis(), 116 data->getAxisCount(), 117 this->fontStyle(), 118 this->isFixedPitch(), 119 fFamilyName, 120 fLang, 121 fVariantStyle); 122 } 123 124 const SkString fPathName; 125 int fIndex; 126 const skia_private::STArray<4, SkFixed, true> fAxes; 127 const skia_private::STArray<4, SkLanguage, true> fLang; 128 const FontVariant fVariantStyle; 129 SkAutoTCallVProc<FILE, sk_fclose> fFile; 130 131 typedef SkTypeface_Preview INHERITED; 132 }; 133 134 class SkTypeface_PreviewStream : public SkTypeface_Preview { 135 public: SkTypeface_PreviewStream(std::unique_ptr<SkFontData> data,const SkFontStyle & style,bool isFixedPitch,const SkString & familyName)136 SkTypeface_PreviewStream(std::unique_ptr<SkFontData> data, 137 const SkFontStyle& style, 138 bool isFixedPitch, 139 const SkString& familyName) 140 : INHERITED(style, isFixedPitch, familyName) 141 , fData(std::move(data)) 142 { } 143 144 ~SkTypeface_PreviewStream() override = default; 145 onGetFontDescriptor(SkFontDescriptor * desc,bool * serialize)146 virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override 147 { 148 SkASSERT(desc); 149 SkASSERT(serialize); 150 desc->setFamilyName(fFamilyName.c_str()); 151 *serialize = true; 152 } 153 onOpenStream(int * ttcIndex)154 std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override 155 { 156 *ttcIndex = fData->getIndex(); 157 return fData->getStream()->duplicate(); 158 } 159 onMakeFontData()160 std::unique_ptr<SkFontData> onMakeFontData() const override 161 { 162 return std::make_unique<SkFontData>(*fData); 163 } 164 onMakeClone(const SkFontArguments & args)165 sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override 166 { 167 SkFontStyle style = this->fontStyle(); 168 std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style); 169 if (!data) { 170 return nullptr; 171 } 172 return sk_make_sp<SkTypeface_PreviewStream>(std::move(data), this->fontStyle(), this->isFixedPitch(), fFamilyName); 173 } 174 175 private: 176 const std::unique_ptr<const SkFontData> fData; 177 typedef SkTypeface_Preview INHERITED; 178 }; 179 180 class SkFontStyleSet_Preview : public SkFontStyleSet { 181 typedef SkFontScanner_FreeType Scanner; 182 183 public: SkFontStyleSet_Preview(const FontFamily & family,const Scanner & scanner)184 explicit SkFontStyleSet_Preview(const FontFamily& family, const Scanner& scanner) 185 { 186 const SkString* cannonicalFamilyName = nullptr; 187 if (family.fNames.size() > 0) { 188 cannonicalFamilyName = &family.fNames[0]; 189 } 190 fFallbackFor = family.fFallbackFor; 191 192 // TODO? make this lazy 193 for (int i = 0; i < family.fFonts.size(); ++i) { 194 const FontFileInfo& fontFile = family.fFonts[i]; 195 196 SkString pathName(family.fBasePath); 197 pathName.append(fontFile.fFileName); 198 199 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(pathName.c_str()); 200 if (!stream) { 201 SkDEBUGF("Requested font file %s does not exist or cannot be opened.\n", pathName.c_str()); 202 continue; 203 } 204 205 const int ttcIndex = fontFile.fIndex; 206 SkString familyName; 207 SkFontStyle style; 208 bool isFixedWidth = true; 209 Scanner::AxisDefinitions axisDefinitions; 210 211 if (!scanner.scanFont(stream.get(), ttcIndex, 212 &familyName, &style, &isFixedWidth, &axisDefinitions)) { 213 SkDEBUGF("Requested font file %s exists, but is not a valid font.\n", 214 pathName.c_str()); 215 continue; 216 } 217 218 int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight(); 219 SkFontStyle::Slant slant = style.slant(); 220 switch (fontFile.fStyle) { 221 case FontFileInfo::Style::kAuto: 222 slant = style.slant(); 223 break; 224 case FontFileInfo::Style::kNormal: 225 slant = SkFontStyle::kUpright_Slant; 226 break; 227 case FontFileInfo::Style::kItalic: 228 slant = SkFontStyle::kItalic_Slant; 229 break; 230 default: 231 SkASSERT(false); 232 break; 233 } 234 style = SkFontStyle(weight, style.width(), slant); 235 236 uint32_t variant = family.fVariant; 237 if (kDefault_FontVariant == variant) { 238 variant = kCompact_FontVariant | kElegant_FontVariant; 239 } 240 241 // The first specified family name overrides the family name found in the font. 242 // TODO: SkTypeface_PreviewSystem::onCreateFamilyNameIterator should return 243 // all of the specified family names in addition to the names found in the font. 244 if (cannonicalFamilyName != nullptr) { 245 familyName = *cannonicalFamilyName; 246 } 247 248 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.size()); 249 SkFontScanner::VariationPosition current; 250 const SkFontArguments::VariationPosition currentPos{current.data(), current.size()}; 251 SkFontArguments::VariationPosition position = { 252 fontFile.fVariationDesignPosition.begin(), 253 fontFile.fVariationDesignPosition.size() 254 }; 255 Scanner::computeAxisValues(axisDefinitions, currentPos, position, axisValues, familyName, &style); 256 257 fStyles.push_back().reset(new SkTypeface_PreviewSystem(pathName, ttcIndex, axisValues.get(), 258 axisDefinitions.size(), style, isFixedWidth, 259 familyName, family.fLanguages, variant)); 260 } 261 } 262 263 ~SkFontStyleSet_Preview() override = default; 264 count()265 int count() override 266 { 267 return fStyles.size(); 268 } 269 getStyle(int index,SkFontStyle * style,SkString * name)270 void getStyle(int index, SkFontStyle* style, SkString* name) override 271 { 272 if (index < 0 || fStyles.size() <= index) { 273 return; 274 } 275 if (style) { 276 *style = fStyles[index]->fontStyle(); 277 } 278 if (name) { 279 name->reset(); 280 } 281 } 282 createTypeface(int index)283 sk_sp<SkTypeface> createTypeface(int index) override 284 { 285 if (index < 0 || fStyles.size() <= index) { 286 return nullptr; 287 } 288 return sk_sp<SkTypeface>(SkRef(fStyles[index].get())); 289 } 290 matchStyle(const SkFontStyle & pattern)291 sk_sp<SkTypeface> matchStyle(const SkFontStyle& pattern) override 292 { 293 return static_cast<sk_sp<SkTypeface>>(this->matchStyleCSS3(pattern)); 294 } 295 296 private: 297 skia_private::TArray<sk_sp<SkTypeface_PreviewSystem>> fStyles; 298 SkString fFallbackFor; 299 300 friend struct NameToFamily; 301 friend class SkFontMgr_Preview; 302 303 typedef SkFontStyleSet INHERITED; 304 }; 305 306 /** A single family can have many names, but our API assumes unique names. 307 * Map names to the back end so that all names for a given family refer to the same 308 * (non-replicated) set of typefaces. 309 * SkTDict<> doesn't let us do index-based lookup, so we write our own mapping. 310 */ 311 struct NameToFamily { 312 SkString name; 313 SkFontStyleSet_Preview* styleSet; 314 }; 315 316 SK_API sk_sp<SkFontMgr> SkFontMgr_New_Preview(); 317 318 class SkFontMgr_Preview : public SkFontMgr { 319 public: 320 SkFontMgr_Preview(); 321 ~SkFontMgr_Preview() override = default; 322 323 protected: 324 int onCountFamilies() const override; 325 void onGetFamilyName(int index, SkString* familyName) const override; 326 sk_sp<SkFontStyleSet> onCreateStyleSet(int index) const override; 327 sk_sp<SkFontStyleSet> onMatchFamily(const char familyName[]) const override; 328 virtual sk_sp<SkTypeface> onMatchFamilyStyle(const char familyName[], 329 const SkFontStyle& style) const override; 330 virtual sk_sp<SkTypeface> onMatchFaceStyle(const SkTypeface* typeface, 331 const SkFontStyle& style) const override; 332 333 static sk_sp<SkTypeface_PreviewSystem> find_family_style_character( 334 const SkString& familyName, 335 const skia_private::TArray<NameToFamily, true>& fallbackNameToFamilyMap, 336 const SkFontStyle& style, bool elegant, 337 const SkString& langTag, SkUnichar character); 338 339 virtual sk_sp<SkTypeface> onMatchFamilyStyleCharacter(const char familyName[], 340 const SkFontStyle& style, 341 const char* bcp47[], 342 int bcp47Count, 343 SkUnichar character) const override; 344 sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override; 345 sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override; 346 sk_sp<SkTypeface> makeTypeface(std::unique_ptr<SkStreamAsset> stream, 347 const SkFontArguments& args, const char path[]) const; 348 sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, int ttcIndex) const override; 349 sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream, 350 const SkFontArguments& args) const override; 351 sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle style) const override; 352 353 private: 354 void buildNameToFamilyMap(SkTDArray<FontFamily*> families); 355 void findDefaultStyleSet(); 356 void addFamily(FontFamily& family, int familyIndex); 357 358 SkFontScanner_FreeType fScanner; 359 360 sk_sp<SkFontStyleSet> fDefaultStyleSet; 361 skia_private::TArray<sk_sp<SkFontStyleSet_Preview>> fStyleSets; 362 skia_private::TArray<NameToFamily, true> fNameToFamilyMap; 363 skia_private::TArray<NameToFamily, true> fFallbackNameToFamilyMap; 364 365 typedef SkFontMgr INHERITED; 366 }; 367 368 #endif // SkFontMgr_preview_DEFINED