1 /* 2 * Copyright 2006 The Android Open Source Project 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 "SkFontArguments.h" 9 #include "SkFontDescriptor.h" 10 #include "SkFontHost_FreeType_common.h" 11 #include "SkFontMgr.h" 12 #include "SkFontMgr_custom.h" 13 #include "SkFontStyle.h" 14 #include "SkMakeUnique.h" 15 #include "SkRefCnt.h" 16 #include "SkStream.h" 17 #include "SkString.h" 18 #include "SkTArray.h" 19 #include "SkTemplates.h" 20 #include "SkTypeface.h" 21 #include "SkTypes.h" 22 23 #include <limits> 24 #include <memory> 25 26 class SkData; 27 28 SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch, 29 bool sysFont, const SkString familyName, int index) 30 : INHERITED(style, isFixedPitch) 31 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index) 32 { } 33 34 bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; } 35 36 void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const { 37 *familyName = fFamilyName; 38 } 39 40 void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const { 41 desc->setFamilyName(fFamilyName.c_str()); 42 desc->setStyle(this->fontStyle()); 43 *isLocal = !this->isSysFont(); 44 } 45 46 int SkTypeface_Custom::getIndex() const { return fIndex; } 47 48 49 SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {} 50 51 SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; } 52 53 54 SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData, 55 const SkFontStyle& style, bool isFixedPitch, bool sysFont, 56 const SkString familyName) 57 : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex()) 58 , fData(std::move(fontData)) 59 { } 60 61 SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const { 62 *ttcIndex = fData->getIndex(); 63 return fData->getStream()->duplicate().release(); 64 } 65 66 std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const { 67 return skstd::make_unique<SkFontData>(*fData); 68 } 69 70 71 SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont, 72 const SkString familyName, const char path[], int index) 73 : INHERITED(style, isFixedPitch, sysFont, familyName, index) 74 , fPath(path) 75 { } 76 77 SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const { 78 *ttcIndex = this->getIndex(); 79 return SkStream::MakeFromFile(fPath.c_str()).release(); 80 } 81 82 /////////////////////////////////////////////////////////////////////////////// 83 84 SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {} 85 86 void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) { 87 fStyles.emplace_back(std::move(typeface)); 88 } 89 90 int SkFontStyleSet_Custom::count() { 91 return fStyles.count(); 92 } 93 94 void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) { 95 SkASSERT(index < fStyles.count()); 96 if (style) { 97 *style = fStyles[index]->fontStyle(); 98 } 99 if (name) { 100 name->reset(); 101 } 102 } 103 104 SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) { 105 SkASSERT(index < fStyles.count()); 106 return SkRef(fStyles[index].get()); 107 } 108 109 SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) { 110 return this->matchStyleCSS3(pattern); 111 } 112 113 SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; } 114 115 116 SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) { 117 loader.loadSystemFonts(fScanner, &fFamilies); 118 119 // Try to pick a default font. 120 static const char* defaultNames[] = { 121 "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr 122 }; 123 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) { 124 sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i])); 125 if (nullptr == set) { 126 continue; 127 } 128 129 sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight, 130 SkFontStyle::kNormal_Width, 131 SkFontStyle::kUpright_Slant))); 132 if (nullptr == tf) { 133 continue; 134 } 135 136 fDefaultFamily = set.get(); 137 break; 138 } 139 if (nullptr == fDefaultFamily) { 140 fDefaultFamily = fFamilies[0].get(); 141 } 142 } 143 144 int SkFontMgr_Custom::onCountFamilies() const { 145 return fFamilies.count(); 146 } 147 148 void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const { 149 SkASSERT(index < fFamilies.count()); 150 familyName->set(fFamilies[index]->getFamilyName()); 151 } 152 153 SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const { 154 SkASSERT(index < fFamilies.count()); 155 return SkRef(fFamilies[index].get()); 156 } 157 158 SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const { 159 for (int i = 0; i < fFamilies.count(); ++i) { 160 if (fFamilies[i]->getFamilyName().equals(familyName)) { 161 return SkRef(fFamilies[i].get()); 162 } 163 } 164 return nullptr; 165 } 166 167 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[], 168 const SkFontStyle& fontStyle) const 169 { 170 sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName)); 171 return sset->matchStyle(fontStyle); 172 } 173 174 SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[], 175 const SkFontStyle&, 176 const char* bcp47[], int bcp47Count, 177 SkUnichar character) const 178 { 179 return nullptr; 180 } 181 182 SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember, 183 const SkFontStyle& fontStyle) const 184 { 185 for (int i = 0; i < fFamilies.count(); ++i) { 186 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) { 187 if (fFamilies[i]->fStyles[j].get() == familyMember) { 188 return fFamilies[i]->matchStyle(fontStyle); 189 } 190 } 191 } 192 return nullptr; 193 } 194 195 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const { 196 return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex); 197 } 198 199 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, 200 int ttcIndex) const { 201 return this->makeFromStream(std::move(stream), SkFontArguments().setCollectionIndex(ttcIndex)); 202 } 203 204 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream, 205 const SkFontArguments& args) const { 206 using Scanner = SkTypeface_FreeType::Scanner; 207 bool isFixedPitch; 208 SkFontStyle style; 209 SkString name; 210 Scanner::AxisDefinitions axisDefinitions; 211 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), 212 &name, &style, &isFixedPitch, &axisDefinitions)) 213 { 214 return nullptr; 215 } 216 217 const SkFontArguments::VariationPosition position = args.getVariationDesignPosition(); 218 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); 219 Scanner::computeAxisValues(axisDefinitions, position, axisValues, name); 220 221 auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), 222 axisValues.get(), axisDefinitions.count()); 223 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name)); 224 } 225 226 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFontData(std::unique_ptr<SkFontData> data) const { 227 bool isFixedPitch; 228 SkFontStyle style; 229 SkString name; 230 if (!fScanner.scanFont(data->getStream(), data->getIndex(), 231 &name, &style, &isFixedPitch, nullptr)) { 232 return nullptr; 233 } 234 return sk_sp<SkTypeface>(new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name)); 235 } 236 237 sk_sp<SkTypeface> SkFontMgr_Custom::onMakeFromFile(const char path[], int ttcIndex) const { 238 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path); 239 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr; 240 } 241 242 sk_sp<SkTypeface> SkFontMgr_Custom::onLegacyMakeTypeface(const char familyName[], 243 SkFontStyle style) const { 244 sk_sp<SkTypeface> tf; 245 246 if (familyName) { 247 tf.reset(this->onMatchFamilyStyle(familyName, style)); 248 } 249 250 if (nullptr == tf) { 251 tf.reset(fDefaultFamily->matchStyle(style)); 252 } 253 254 return tf; 255 } 256