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