LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkTypeface.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 2 183 1.1 %
Date: 2017-07-14 16:53:18 Functions: 1 55 1.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13