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(); 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 SkTypeface* SkFontMgr_Custom::onCreateFromData(SkData* data, int ttcIndex) const { 196 return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex); 197 } 198 199 SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const { 200 return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex)); 201 } 202 203 SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s, 204 const SkFontArguments& args) const 205 { 206 using Scanner = SkTypeface_FreeType::Scanner; 207 std::unique_ptr<SkStreamAsset> stream(s); 208 bool isFixedPitch; 209 SkFontStyle style; 210 SkString name; 211 Scanner::AxisDefinitions axisDefinitions; 212 if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), 213 &name, &style, &isFixedPitch, &axisDefinitions)) 214 { 215 return nullptr; 216 } 217 218 const SkFontArguments::VariationPosition position = args.getVariationDesignPosition(); 219 SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); 220 Scanner::computeAxisValues(axisDefinitions, position, axisValues, name); 221 222 auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), 223 axisValues.get(), axisDefinitions.count()); 224 return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name); 225 } 226 227 SkTypeface* SkFontMgr_Custom::onCreateFromFontData(std::unique_ptr<SkFontData> data) const { 228 bool isFixedPitch; 229 SkFontStyle style; 230 SkString name; 231 if (!fScanner.scanFont(data->getStream(), data->getIndex(), 232 &name, &style, &isFixedPitch, nullptr)) 233 { 234 return nullptr; 235 } 236 return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name); 237 } 238 239 SkTypeface* SkFontMgr_Custom::onCreateFromFile(const char path[], int ttcIndex) const { 240 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path); 241 return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr; 242 } 243 244 SkTypeface* SkFontMgr_Custom::onLegacyCreateTypeface(const char familyName[], 245 SkFontStyle style) const 246 { 247 SkTypeface* tf = nullptr; 248 249 if (familyName) { 250 tf = this->onMatchFamilyStyle(familyName, style); 251 } 252 253 if (nullptr == tf) { 254 tf = fDefaultFamily->matchStyle(style); 255 } 256 257 return tf; 258 } 259