• 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 "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