1 /*
2  * Copyright 2017 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 #include "src/core/SkFontDescriptor.h"
9 #include "tools/ToolUtils.h"
10 #include "tools/fonts/TestFontMgr.h"
11 #include "tools/fonts/TestTypeface.h"
12 
13 #ifdef SK_XML
14 #include "tools/fonts/TestSVGTypeface.h"
15 #endif
16 
17 #include <vector>
18 
19 namespace {
20 
21 #include "test_font_monospace.inc"
22 #include "test_font_sans_serif.inc"
23 #include "test_font_serif.inc"
24 
25 #include "test_font_index.inc"
26 
27 class FontStyleSet final : public SkFontStyleSet {
28 public:
FontStyleSet(const char * familyName)29     FontStyleSet(const char* familyName) : fFamilyName(familyName) {}
30     struct TypefaceEntry {
TypefaceEntry__anon516282170111::FontStyleSet::TypefaceEntry31         TypefaceEntry(sk_sp<SkTypeface> typeface, SkFontStyle style, const char* styleName)
32                 : fTypeface(std::move(typeface)), fStyle(style), fStyleName(styleName) {}
33         sk_sp<SkTypeface> fTypeface;
34         SkFontStyle       fStyle;
35         const char*       fStyleName;
36     };
37 
count()38     int count() override { return fTypefaces.size(); }
39 
getStyle(int index,SkFontStyle * style,SkString * name)40     void getStyle(int index, SkFontStyle* style, SkString* name) override {
41         if (style) {
42             *style = fTypefaces[index].fStyle;
43         }
44         if (name) {
45             *name = fTypefaces[index].fStyleName;
46         }
47     }
48 
createTypeface(int index)49     SkTypeface* createTypeface(int index) override {
50         return SkRef(fTypefaces[index].fTypeface.get());
51     }
52 
matchStyle(const SkFontStyle & pattern)53     SkTypeface* matchStyle(const SkFontStyle& pattern) override {
54         return this->matchStyleCSS3(pattern);
55     }
56 
getFamilyName()57     SkString getFamilyName() { return fFamilyName; }
58 
59     std::vector<TypefaceEntry> fTypefaces;
60     SkString                   fFamilyName;
61 };
62 
63 class FontMgr final : public SkFontMgr {
64 public:
FontMgr()65     FontMgr() {
66         for (const auto& sub : gSubFonts) {
67             sk_sp<TestTypeface> typeface =
68                     sk_make_sp<TestTypeface>(sk_make_sp<SkTestFont>(sub.fFont), sub.fStyle);
69             bool defaultFamily = false;
70             if (&sub - gSubFonts == gDefaultFontIndex) {
71                 defaultFamily    = true;
72                 fDefaultTypeface = typeface;
73             }
74             bool found = false;
75             for (const auto& family : fFamilies) {
76                 if (family->getFamilyName().equals(sub.fFamilyName)) {
77                     family->fTypefaces.emplace_back(
78                             std::move(typeface), sub.fStyle, sub.fStyleName);
79                     found = true;
80                     if (defaultFamily) {
81                         fDefaultFamily = family;
82                     }
83                     break;
84                 }
85             }
86             if (!found) {
87                 fFamilies.emplace_back(sk_make_sp<FontStyleSet>(sub.fFamilyName));
88                 fFamilies.back()->fTypefaces.emplace_back(
89                         // NOLINTNEXTLINE(bugprone-use-after-move)
90                         std::move(typeface),
91                         sub.fStyle,
92                         sub.fStyleName);
93                 if (defaultFamily) {
94                     fDefaultFamily = fFamilies.back();
95                 }
96             }
97         }
98 #ifdef SK_XML
99         fFamilies.emplace_back(sk_make_sp<FontStyleSet>("Emoji"));
100         fFamilies.back()->fTypefaces.emplace_back(
101                 TestSVGTypeface::Default(), SkFontStyle::Normal(), "Normal");
102 
103         fFamilies.emplace_back(sk_make_sp<FontStyleSet>("Planet"));
104         fFamilies.back()->fTypefaces.emplace_back(
105                 TestSVGTypeface::Planets(), SkFontStyle::Normal(), "Normal");
106 #endif
107     }
108 
onCountFamilies() const109     int onCountFamilies() const override { return fFamilies.size(); }
110 
onGetFamilyName(int index,SkString * familyName) const111     void onGetFamilyName(int index, SkString* familyName) const override {
112         *familyName = fFamilies[index]->getFamilyName();
113     }
114 
onCreateStyleSet(int index) const115     SkFontStyleSet* onCreateStyleSet(int index) const override {
116         sk_sp<SkFontStyleSet> ref = fFamilies[index];
117         return ref.release();
118     }
119 
onMatchFamily(const char familyName[]) const120     SkFontStyleSet* onMatchFamily(const char familyName[]) const override {
121         if (familyName) {
122             if (strstr(familyName, "ono")) {
123                 return this->createStyleSet(0);
124             }
125             if (strstr(familyName, "ans")) {
126                 return this->createStyleSet(1);
127             }
128             if (strstr(familyName, "erif")) {
129                 return this->createStyleSet(2);
130             }
131 #ifdef SK_XML
132             if (strstr(familyName, "oji")) {
133                 return this->createStyleSet(6);
134             }
135             if (strstr(familyName, "Planet")) {
136                 return this->createStyleSet(7);
137             }
138 #endif
139         }
140         return nullptr;
141     }
142 
onMatchFamilyStyle(const char familyName[],const SkFontStyle & style) const143     SkTypeface* onMatchFamilyStyle(const char         familyName[],
144                                    const SkFontStyle& style) const override {
145         sk_sp<SkFontStyleSet> styleSet(this->matchFamily(familyName));
146         return styleSet->matchStyle(style);
147     }
148 
onMatchFamilyStyleCharacter(const char familyName[],const SkFontStyle & style,const char * bcp47[],int bcp47Count,SkUnichar character) const149     SkTypeface* onMatchFamilyStyleCharacter(const char         familyName[],
150                                             const SkFontStyle& style,
151                                             const char*        bcp47[],
152                                             int                bcp47Count,
153                                             SkUnichar          character) const override {
154         (void)bcp47;
155         (void)bcp47Count;
156         (void)character;
157         return this->matchFamilyStyle(familyName, style);
158     }
159 
onMatchFaceStyle(const SkTypeface * tf,const SkFontStyle & style) const160     SkTypeface* onMatchFaceStyle(const SkTypeface* tf, const SkFontStyle& style) const override {
161         SkString familyName;
162         tf->getFamilyName(&familyName);
163         return this->matchFamilyStyle(familyName.c_str(), style);
164     }
165 
onMakeFromData(sk_sp<SkData>,int ttcIndex) const166     sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override { return nullptr; }
onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,int ttcIndex) const167     sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
168                                             int ttcIndex) const override {
169         return nullptr;
170     }
onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,const SkFontArguments &) const171     sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
172                                            const SkFontArguments&) const override {
173         return nullptr;
174     }
onMakeFromFontData(std::unique_ptr<SkFontData>) const175     sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData>) const override {
176         return nullptr;
177     }
onMakeFromFile(const char path[],int ttcIndex) const178     sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
179         return nullptr;
180     }
181 
onLegacyMakeTypeface(const char familyName[],SkFontStyle style) const182     sk_sp<SkTypeface> onLegacyMakeTypeface(const char  familyName[],
183                                            SkFontStyle style) const override {
184         if (familyName == nullptr) {
185             return sk_sp<SkTypeface>(fDefaultFamily->matchStyle(style));
186         }
187         sk_sp<SkTypeface> typeface = sk_sp<SkTypeface>(this->matchFamilyStyle(familyName, style));
188         if (!typeface) {
189             typeface = fDefaultTypeface;
190         }
191         return typeface;
192     }
193 
194 private:
195     std::vector<sk_sp<FontStyleSet>> fFamilies;
196     sk_sp<FontStyleSet>              fDefaultFamily;
197     sk_sp<SkTypeface>                fDefaultTypeface;
198 };
199 }  // namespace
200 
201 namespace ToolUtils {
MakePortableFontMgr()202 sk_sp<SkFontMgr> MakePortableFontMgr() { return sk_make_sp<FontMgr>(); }
203 }  // namespace ToolUtils
204