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