Home | History | Annotate | Download | only in core
      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