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 19namespace { 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 27class FontStyleSet final : public SkFontStyleSet { 28public: 29 FontStyleSet(const char* familyName) : fFamilyName(familyName) {} 30 struct TypefaceEntry { 31 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 38 int count() override { return fTypefaces.size(); } 39 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 49 SkTypeface* createTypeface(int index) override { 50 return SkRef(fTypefaces[index].fTypeface.get()); 51 } 52 53 SkTypeface* matchStyle(const SkFontStyle& pattern) override { 54 return this->matchStyleCSS3(pattern); 55 } 56 57 SkString getFamilyName() { return fFamilyName; } 58 59 std::vector<TypefaceEntry> fTypefaces; 60 SkString fFamilyName; 61}; 62 63class FontMgr final : public SkFontMgr { 64public: 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#if defined(SK_ENABLE_SVG) 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 109 int onCountFamilies() const override { return fFamilies.size(); } 110 111 void onGetFamilyName(int index, SkString* familyName) const override { 112 *familyName = fFamilies[index]->getFamilyName(); 113 } 114 115 SkFontStyleSet* onCreateStyleSet(int index) const override { 116 sk_sp<SkFontStyleSet> ref = fFamilies[index]; 117 return ref.release(); 118 } 119 120 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 143 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 149 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 160 sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override { return nullptr; } 161 sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>, 162 int ttcIndex) const override { 163 return nullptr; 164 } 165 sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>, 166 const SkFontArguments&) const override { 167 return nullptr; 168 } 169 sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override { 170 return nullptr; 171 } 172 173 sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], 174 SkFontStyle style) const override { 175 if (familyName == nullptr) { 176 return sk_sp<SkTypeface>(fDefaultFamily->matchStyle(style)); 177 } 178 sk_sp<SkTypeface> typeface = sk_sp<SkTypeface>(this->matchFamilyStyle(familyName, style)); 179 if (!typeface) { 180 typeface = fDefaultTypeface; 181 } 182 return typeface; 183 } 184 185private: 186 std::vector<sk_sp<FontStyleSet>> fFamilies; 187 sk_sp<FontStyleSet> fDefaultFamily; 188 sk_sp<SkTypeface> fDefaultTypeface; 189}; 190} // namespace 191 192namespace ToolUtils { 193sk_sp<SkFontMgr> MakePortableFontMgr() { return sk_make_sp<FontMgr>(); } 194} // namespace ToolUtils 195