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 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