1 /* 2 * Copyright 2011 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 "SkAdvancedTypefaceMetrics.h" 9 #include "SkEndian.h" 10 #include "SkFontDescriptor.h" 11 #include "SkFontMgr.h" 12 #include "SkMakeUnique.h" 13 #include "SkMutex.h" 14 #include "SkOTTable_OS_2.h" 15 #include "SkOnce.h" 16 #include "SkStream.h" 17 #include "SkTypeface.h" 18 #include "SkTypefaceCache.h" 19 20 SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch) 21 : fUniqueID(SkTypefaceCache::NewFontID()), fStyle(style), fIsFixedPitch(isFixedPitch) { } 22 23 SkTypeface::~SkTypeface() { } 24 25 #ifdef SK_WHITELIST_SERIALIZED_TYPEFACES 26 extern void WhitelistSerializeTypeface(const SkTypeface*, SkWStream* ); 27 #define SK_TYPEFACE_DELEGATE WhitelistSerializeTypeface 28 #else 29 #define SK_TYPEFACE_DELEGATE nullptr 30 #endif 31 32 sk_sp<SkTypeface> (*gCreateTypefaceDelegate)(const char[], SkFontStyle) = nullptr; 33 34 void (*gSerializeTypefaceDelegate)(const SkTypeface*, SkWStream* ) = SK_TYPEFACE_DELEGATE; 35 sk_sp<SkTypeface> (*gDeserializeTypefaceDelegate)(SkStream* ) = nullptr; 36 37 /////////////////////////////////////////////////////////////////////////////// 38 39 namespace { 40 41 class SkEmptyTypeface : public SkTypeface { 42 public: 43 static SkEmptyTypeface* Create() { return new SkEmptyTypeface; } 44 protected: 45 SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { } 46 47 SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; } 48 SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, 49 const SkDescriptor*) const override { 50 return nullptr; 51 } 52 void onFilterRec(SkScalerContextRec*) const override { } 53 std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override { 54 return nullptr; 55 } 56 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { } 57 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, 58 uint16_t glyphs[], int glyphCount) const override { 59 if (glyphs && glyphCount > 0) { 60 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); 61 } 62 return 0; 63 } 64 int onCountGlyphs() const override { return 0; } 65 int onGetUPEM() const override { return 0; } 66 class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings { 67 public: 68 bool next(SkTypeface::LocalizedString*) override { return false; } 69 }; 70 void onGetFamilyName(SkString* familyName) const override { 71 familyName->reset(); 72 } 73 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override { 74 return new EmptyLocalizedStrings; 75 } 76 int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], 77 int coordinateCount) const override 78 { 79 return 0; 80 } 81 int onGetTableTags(SkFontTableTag tags[]) const override { return 0; } 82 size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override { 83 return 0; 84 } 85 }; 86 87 } 88 89 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) { 90 static SkOnce once[4]; 91 static SkTypeface* defaults[4]; 92 93 SkASSERT((int)style < 4); 94 once[style]([style] { 95 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 96 SkTypeface* t = fm->legacyCreateTypeface(nullptr, SkFontStyle::FromOldStyle(style)); 97 defaults[style] = t ? t : SkEmptyTypeface::Create(); 98 }); 99 return defaults[style]; 100 } 101 102 sk_sp<SkTypeface> SkTypeface::MakeDefault(Style style) { 103 return sk_ref_sp(GetDefaultTypeface(style)); 104 } 105 106 uint32_t SkTypeface::UniqueID(const SkTypeface* face) { 107 if (nullptr == face) { 108 face = GetDefaultTypeface(); 109 } 110 return face->uniqueID(); 111 } 112 113 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) { 114 return facea == faceb || SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb); 115 } 116 117 /////////////////////////////////////////////////////////////////////////////// 118 119 sk_sp<SkTypeface> SkTypeface::MakeFromName(const char name[], 120 SkFontStyle fontStyle) { 121 if (gCreateTypefaceDelegate) { 122 sk_sp<SkTypeface> result = (*gCreateTypefaceDelegate)(name, fontStyle); 123 if (result) { 124 return result; 125 } 126 } 127 if (nullptr == name && (fontStyle.slant() == SkFontStyle::kItalic_Slant || 128 fontStyle.slant() == SkFontStyle::kUpright_Slant) && 129 (fontStyle.weight() == SkFontStyle::kBold_Weight || 130 fontStyle.weight() == SkFontStyle::kNormal_Weight)) { 131 return MakeDefault(static_cast<SkTypeface::Style>( 132 (fontStyle.slant() == SkFontStyle::kItalic_Slant ? SkTypeface::kItalic : 133 SkTypeface::kNormal) | 134 (fontStyle.weight() == SkFontStyle::kBold_Weight ? SkTypeface::kBold : 135 SkTypeface::kNormal))); 136 } 137 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 138 return sk_sp<SkTypeface>(fm->legacyCreateTypeface(name, fontStyle)); 139 } 140 141 sk_sp<SkTypeface> SkTypeface::MakeFromTypeface(SkTypeface* family, Style s) { 142 if (!family) { 143 return SkTypeface::MakeDefault(s); 144 } 145 146 if (family->style() == s) { 147 return sk_ref_sp(family); 148 } 149 150 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 151 return sk_sp<SkTypeface>(fm->matchFaceStyle(family, SkFontStyle::FromOldStyle(s))); 152 } 153 154 sk_sp<SkTypeface> SkTypeface::MakeFromStream(SkStreamAsset* stream, int index) { 155 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 156 return sk_sp<SkTypeface>(fm->createFromStream(stream, index)); 157 } 158 159 sk_sp<SkTypeface> SkTypeface::MakeFromFontData(std::unique_ptr<SkFontData> data) { 160 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 161 return sk_sp<SkTypeface>(fm->createFromFontData(std::move(data))); 162 } 163 164 sk_sp<SkTypeface> SkTypeface::MakeFromFile(const char path[], int index) { 165 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); 166 return sk_sp<SkTypeface>(fm->createFromFile(path, index)); 167 } 168 169 /////////////////////////////////////////////////////////////////////////////// 170 171 void SkTypeface::serialize(SkWStream* wstream) const { 172 if (gSerializeTypefaceDelegate) { 173 (*gSerializeTypefaceDelegate)(this, wstream); 174 return; 175 } 176 bool isLocal = false; 177 SkFontDescriptor desc; 178 this->onGetFontDescriptor(&desc, &isLocal); 179 180 // Embed font data if it's a local font. 181 if (isLocal && !desc.hasFontData()) { 182 desc.setFontData(this->onMakeFontData()); 183 } 184 desc.serialize(wstream); 185 } 186 187 sk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) { 188 if (gDeserializeTypefaceDelegate) { 189 return (*gDeserializeTypefaceDelegate)(stream); 190 } 191 192 SkFontDescriptor desc; 193 if (!SkFontDescriptor::Deserialize(stream, &desc)) { 194 return nullptr; 195 } 196 197 std::unique_ptr<SkFontData> data = desc.detachFontData(); 198 if (data) { 199 sk_sp<SkTypeface> typeface(SkTypeface::MakeFromFontData(std::move(data))); 200 if (typeface) { 201 return typeface; 202 } 203 } 204 205 return SkTypeface::MakeFromName(desc.getFamilyName(), desc.getStyle()); 206 } 207 208 /////////////////////////////////////////////////////////////////////////////// 209 210 int SkTypeface::getVariationDesignPosition( 211 SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const 212 { 213 return this->onGetVariationDesignPosition(coordinates, coordinateCount); 214 } 215 216 int SkTypeface::countTables() const { 217 return this->onGetTableTags(nullptr); 218 } 219 220 int SkTypeface::getTableTags(SkFontTableTag tags[]) const { 221 return this->onGetTableTags(tags); 222 } 223 224 size_t SkTypeface::getTableSize(SkFontTableTag tag) const { 225 return this->onGetTableData(tag, 0, ~0U, nullptr); 226 } 227 228 size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length, 229 void* data) const { 230 return this->onGetTableData(tag, offset, length, data); 231 } 232 233 SkStreamAsset* SkTypeface::openStream(int* ttcIndex) const { 234 int ttcIndexStorage; 235 if (nullptr == ttcIndex) { 236 // So our subclasses don't need to check for null param 237 ttcIndex = &ttcIndexStorage; 238 } 239 return this->onOpenStream(ttcIndex); 240 } 241 242 std::unique_ptr<SkFontData> SkTypeface::makeFontData() const { 243 return this->onMakeFontData(); 244 } 245 246 // This implementation is temporary until this method can be made pure virtual. 247 std::unique_ptr<SkFontData> SkTypeface::onMakeFontData() const { 248 int index; 249 std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index)); 250 return skstd::make_unique<SkFontData>(std::move(stream), index, nullptr, 0); 251 }; 252 253 int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding, 254 uint16_t glyphs[], int glyphCount) const { 255 if (glyphCount <= 0) { 256 return 0; 257 } 258 if (nullptr == chars || (unsigned)encoding > kUTF32_Encoding) { 259 if (glyphs) { 260 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); 261 } 262 return 0; 263 } 264 return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount); 265 } 266 267 int SkTypeface::countGlyphs() const { 268 return this->onCountGlyphs(); 269 } 270 271 int SkTypeface::getUnitsPerEm() const { 272 // should we try to cache this in the base-class? 273 return this->onGetUPEM(); 274 } 275 276 bool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count, 277 int32_t adjustments[]) const { 278 SkASSERT(count >= 0); 279 // check for the only legal way to pass a nullptr.. everything is 0 280 // in which case they just want to know if this face can possibly support 281 // kerning (true) or never (false). 282 if (nullptr == glyphs || nullptr == adjustments) { 283 SkASSERT(nullptr == glyphs); 284 SkASSERT(0 == count); 285 SkASSERT(nullptr == adjustments); 286 } 287 return this->onGetKerningPairAdjustments(glyphs, count, adjustments); 288 } 289 290 SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const { 291 return this->onCreateFamilyNameIterator(); 292 } 293 294 void SkTypeface::getFamilyName(SkString* name) const { 295 SkASSERT(name); 296 this->onGetFamilyName(name); 297 } 298 299 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::getAdvancedMetrics() const { 300 std::unique_ptr<SkAdvancedTypefaceMetrics> result = this->onGetAdvancedMetrics(); 301 if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) { 302 SkOTTableOS2::Version::V2::Type::Field fsType; 303 constexpr SkFontTableTag os2Tag = SkTEndian_SwapBE32(SkOTTableOS2::TAG); 304 constexpr size_t fsTypeOffset = offsetof(SkOTTableOS2::Version::V2, fsType); 305 if (this->getTableData(os2Tag, fsTypeOffset, sizeof(fsType), &fsType) == sizeof(fsType)) { 306 if (fsType.Bitmap || (fsType.Restricted && !(fsType.PreviewPrint || fsType.Editable))) { 307 result->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag; 308 } 309 if (fsType.NoSubsetting) { 310 result->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag; 311 } 312 } 313 } 314 return result; 315 } 316 317 bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count, 318 int32_t adjustments[]) const { 319 return false; 320 } 321 322 /////////////////////////////////////////////////////////////////////////////// 323 324 #include "SkDescriptor.h" 325 #include "SkPaint.h" 326 327 SkRect SkTypeface::getBounds() const { 328 fBoundsOnce([this] { 329 if (!this->onComputeBounds(&fBounds)) { 330 fBounds.setEmpty(); 331 } 332 }); 333 return fBounds; 334 } 335 336 bool SkTypeface::onComputeBounds(SkRect* bounds) const { 337 // we use a big size to ensure lots of significant bits from the scalercontext. 338 // then we scale back down to return our final answer (at 1-pt) 339 const SkScalar textSize = 2048; 340 const SkScalar invTextSize = 1 / textSize; 341 342 SkPaint paint; 343 paint.setTypeface(sk_ref_sp(const_cast<SkTypeface*>(this))); 344 paint.setTextSize(textSize); 345 paint.setLinearText(true); 346 347 SkScalerContext::Rec rec; 348 SkScalerContext::MakeRec(paint, nullptr, nullptr, &rec); 349 350 SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1)); 351 SkDescriptor* desc = ad.getDesc(); 352 desc->init(); 353 desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 354 355 SkScalerContextEffects noeffects; 356 std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, desc, true); 357 if (!ctx) { 358 return false; 359 } 360 361 SkPaint::FontMetrics fm; 362 ctx->getFontMetrics(&fm); 363 bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize, 364 fm.fXMax * invTextSize, fm.fBottom * invTextSize); 365 return true; 366 } 367 368 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::onGetAdvancedMetrics() const { 369 SkDEBUGFAIL("Typefaces that need to work with PDF backend must override this."); 370 return nullptr; 371 } 372