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