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 "include/core/SkFontMetrics.h"
9 #include "include/core/SkFontMgr.h"
10 #include "include/core/SkStream.h"
11 #include "include/core/SkTypeface.h"
12 #include "include/private/SkMutex.h"
13 #include "include/private/SkOnce.h"
14 #include "include/utils/SkCustomTypeface.h"
15 #include "src/core/SkAdvancedTypefaceMetrics.h"
16 #include "src/core/SkEndian.h"
17 #include "src/core/SkFontDescriptor.h"
18 #include "src/core/SkScalerContext.h"
19 #include "src/core/SkSurfacePriv.h"
20 #include "src/core/SkTypefaceCache.h"
21 #include "src/sfnt/SkOTTable_OS_2.h"
22 
SkTypeface(const SkFontStyle & style,bool isFixedPitch)23 SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch)
24     : fUniqueID(SkTypefaceCache::NewFontID()), fStyle(style), fIsFixedPitch(isFixedPitch) { }
25 
~SkTypeface()26 SkTypeface::~SkTypeface() { }
27 
28 ///////////////////////////////////////////////////////////////////////////////
29 
30 namespace {
31 
32 class SkEmptyTypeface : public SkTypeface {
33 public:
Make()34     static sk_sp<SkTypeface> Make() { return sk_sp<SkTypeface>(new SkEmptyTypeface); }
35 protected:
SkEmptyTypeface()36     SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
37 
onOpenStream(int * ttcIndex) const38     std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override { return nullptr; }
onMakeClone(const SkFontArguments & args) const39     sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
40         return sk_ref_sp(this);
41     }
onCreateScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const42     SkScalerContext* onCreateScalerContext(const SkScalerContextEffects& effects,
43                                            const SkDescriptor* desc) const override {
44         return SkScalerContext::MakeEmptyContext(
45                 sk_ref_sp(const_cast<SkEmptyTypeface*>(this)), effects, desc);
46     }
onFilterRec(SkScalerContextRec *) const47     void onFilterRec(SkScalerContextRec*) const override { }
onGetAdvancedMetrics() const48     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
49         return nullptr;
50     }
onGetFontDescriptor(SkFontDescriptor *,bool *) const51     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
onCharsToGlyphs(const SkUnichar * chars,int count,SkGlyphID glyphs[]) const52     void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
53         sk_bzero(glyphs, count * sizeof(glyphs[0]));
54     }
onCountGlyphs() const55     int onCountGlyphs() const override { return 0; }
getPostScriptGlyphNames(SkString *) const56     void getPostScriptGlyphNames(SkString*) const override {}
getGlyphToUnicodeMap(SkUnichar *) const57     void getGlyphToUnicodeMap(SkUnichar*) const override {}
onGetUPEM() const58     int onGetUPEM() const override { return 0; }
59     class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
60     public:
next(SkTypeface::LocalizedString *)61         bool next(SkTypeface::LocalizedString*) override { return false; }
62     };
onGetFamilyName(SkString * familyName) const63     void onGetFamilyName(SkString* familyName) const override {
64         familyName->reset();
65     }
onGetPostScriptName(SkString *) const66     bool onGetPostScriptName(SkString*) const override {
67         return false;
68     }
onCreateFamilyNameIterator() const69     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
70         return new EmptyLocalizedStrings;
71     }
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const72     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
73                                      int coordinateCount) const override
74     {
75         return 0;
76     }
onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount) const77     int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
78                                        int parameterCount) const override
79     {
80         return 0;
81     }
onGetTableTags(SkFontTableTag tags[]) const82     int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
onGetTableData(SkFontTableTag,size_t,size_t,void *) const83     size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
84         return 0;
85     }
86 };
87 
88 }  // namespace
89 
FromOldStyle(Style oldStyle)90 SkFontStyle SkTypeface::FromOldStyle(Style oldStyle) {
91     return SkFontStyle((oldStyle & SkTypeface::kBold) ? SkFontStyle::kBold_Weight
92                                                       : SkFontStyle::kNormal_Weight,
93                        SkFontStyle::kNormal_Width,
94                        (oldStyle & SkTypeface::kItalic) ? SkFontStyle::kItalic_Slant
95                                                         : SkFontStyle::kUpright_Slant);
96 }
97 
GetDefaultTypeface(Style style)98 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
99     static SkOnce once[4];
100     static sk_sp<SkTypeface> defaults[4];
101 
102     SkASSERT((int)style < 4);
103     once[style]([style] {
104         sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
105         auto t = fm->legacyMakeTypeface(nullptr, FromOldStyle(style));
106         defaults[style] = t ? t : SkEmptyTypeface::Make();
107     });
108     return defaults[style].get();
109 }
110 
MakeDefault()111 sk_sp<SkTypeface> SkTypeface::MakeDefault() {
112     return sk_ref_sp(GetDefaultTypeface());
113 }
114 
UniqueID(const SkTypeface * face)115 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
116     if (nullptr == face) {
117         face = GetDefaultTypeface();
118     }
119     return face->uniqueID();
120 }
121 
Equal(const SkTypeface * facea,const SkTypeface * faceb)122 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
123     return facea == faceb || SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
124 }
125 
126 ///////////////////////////////////////////////////////////////////////////////
127 
MakeFromName(const char name[],SkFontStyle fontStyle)128 sk_sp<SkTypeface> SkTypeface::MakeFromName(const char name[],
129                                            SkFontStyle fontStyle) {
130     if (nullptr == name && (fontStyle.slant() == SkFontStyle::kItalic_Slant ||
131                             fontStyle.slant() == SkFontStyle::kUpright_Slant) &&
132                            (fontStyle.weight() == SkFontStyle::kBold_Weight ||
133                             fontStyle.weight() == SkFontStyle::kNormal_Weight)) {
134         return sk_ref_sp(GetDefaultTypeface(static_cast<SkTypeface::Style>(
135             (fontStyle.slant() == SkFontStyle::kItalic_Slant ? SkTypeface::kItalic :
136                                                                SkTypeface::kNormal) |
137             (fontStyle.weight() == SkFontStyle::kBold_Weight ? SkTypeface::kBold :
138                                                                SkTypeface::kNormal))));
139     }
140     return SkFontMgr::RefDefault()->legacyMakeTypeface(name, fontStyle);
141 }
142 
MakeFromStream(std::unique_ptr<SkStreamAsset> stream,int index)143 sk_sp<SkTypeface> SkTypeface::MakeFromStream(std::unique_ptr<SkStreamAsset> stream, int index) {
144     if (!stream) {
145         return nullptr;
146     }
147     return SkFontMgr::RefDefault()->makeFromStream(std::move(stream), index);
148 }
149 
MakeFromData(sk_sp<SkData> data,int index)150 sk_sp<SkTypeface> SkTypeface::MakeFromData(sk_sp<SkData> data, int index) {
151     if (!data) {
152         return nullptr;
153     }
154     return SkFontMgr::RefDefault()->makeFromData(std::move(data), index);
155 }
156 
MakeFromFile(const char path[],int index)157 sk_sp<SkTypeface> SkTypeface::MakeFromFile(const char path[], int index) {
158     return SkFontMgr::RefDefault()->makeFromFile(path, index);
159 }
160 
makeClone(const SkFontArguments & args) const161 sk_sp<SkTypeface> SkTypeface::makeClone(const SkFontArguments& args) const {
162     return this->onMakeClone(args);
163 }
164 
165 ///////////////////////////////////////////////////////////////////////////////
166 
serialize(SkWStream * wstream,SerializeBehavior behavior) const167 void SkTypeface::serialize(SkWStream* wstream, SerializeBehavior behavior) const {
168     bool isLocalData = false;
169     SkFontDescriptor desc;
170     this->onGetFontDescriptor(&desc, &isLocalData);
171 
172     bool shouldSerializeData = false;
173     switch (behavior) {
174         case SerializeBehavior::kDoIncludeData:      shouldSerializeData = true;        break;
175         case SerializeBehavior::kDontIncludeData:    shouldSerializeData = false;       break;
176         case SerializeBehavior::kIncludeDataIfLocal: shouldSerializeData = isLocalData; break;
177     }
178 
179     if (shouldSerializeData) {
180         int index;
181         desc.setStream(this->openStream(&index));
182         if (desc.hasStream()) {
183             desc.setCollectionIndex(index);
184         }
185 
186         int numAxes = this->getVariationDesignPosition(nullptr, 0);
187         if (0 < numAxes) {
188             numAxes = this->getVariationDesignPosition(desc.setVariationCoordinates(numAxes), numAxes);
189             if (numAxes <= 0) {
190                 desc.setVariationCoordinates(0);
191             }
192         }
193     }
194     desc.serialize(wstream);
195 }
196 
serialize(SerializeBehavior behavior) const197 sk_sp<SkData> SkTypeface::serialize(SerializeBehavior behavior) const {
198     SkDynamicMemoryWStream stream;
199     this->serialize(&stream, behavior);
200     return stream.detachAsData();
201 }
202 
MakeDeserialize(SkStream * stream)203 sk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) {
204     SkFontDescriptor desc;
205     if (!SkFontDescriptor::Deserialize(stream, &desc)) {
206         return nullptr;
207     }
208 
209     if (desc.hasStream()) {
210         if (auto tf = SkCustomTypefaceBuilder::Deserialize(desc.dupStream().get())) {
211             return tf;
212         }
213     }
214 
215     // Have to check for old data format first.
216     std::unique_ptr<SkFontData> data = desc.maybeAsSkFontData();
217     if (data) {
218         // Should only get here with old skps.
219         sk_sp<SkFontMgr> defaultFm = SkFontMgr::RefDefault();
220         sk_sp<SkTypeface> typeface(defaultFm->makeFromFontData(std::move(data)));
221         if (typeface) {
222             return typeface;
223         }
224     }
225 
226     if (desc.hasStream()) {
227         SkFontArguments args;
228         args.setCollectionIndex(desc.getCollectionIndex());
229         args.setVariationDesignPosition({desc.getVariation(), desc.getVariationCoordinateCount()});
230         sk_sp<SkFontMgr> defaultFm = SkFontMgr::RefDefault();
231         sk_sp<SkTypeface> typeface = defaultFm->makeFromStream(desc.detachStream(), args);
232         if (typeface) {
233             return typeface;
234         }
235     }
236 
237     return SkTypeface::MakeFromName(desc.getFamilyName(), desc.getStyle());
238 }
239 
240 ///////////////////////////////////////////////////////////////////////////////
241 
getVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const242 int SkTypeface::getVariationDesignPosition(
243         SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
244 {
245     return this->onGetVariationDesignPosition(coordinates, coordinateCount);
246 }
247 
getVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount) const248 int SkTypeface::getVariationDesignParameters(
249         SkFontParameters::Variation::Axis parameters[], int parameterCount) const
250 {
251     return this->onGetVariationDesignParameters(parameters, parameterCount);
252 }
253 
countTables() const254 int SkTypeface::countTables() const {
255     return this->onGetTableTags(nullptr);
256 }
257 
getTableTags(SkFontTableTag tags[]) const258 int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
259     return this->onGetTableTags(tags);
260 }
261 
getTableSize(SkFontTableTag tag) const262 size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
263     return this->onGetTableData(tag, 0, ~0U, nullptr);
264 }
265 
getTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const266 size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
267                                 void* data) const {
268     return this->onGetTableData(tag, offset, length, data);
269 }
270 
copyTableData(SkFontTableTag tag) const271 sk_sp<SkData> SkTypeface::copyTableData(SkFontTableTag tag) const {
272     return this->onCopyTableData(tag);
273 }
274 
onCopyTableData(SkFontTableTag tag) const275 sk_sp<SkData> SkTypeface::onCopyTableData(SkFontTableTag tag) const {
276     size_t size = this->getTableSize(tag);
277     if (size) {
278         sk_sp<SkData> data = SkData::MakeUninitialized(size);
279         (void)this->getTableData(tag, 0, size, data->writable_data());
280         return data;
281     }
282     return nullptr;
283 }
284 
openStream(int * ttcIndex) const285 std::unique_ptr<SkStreamAsset> SkTypeface::openStream(int* ttcIndex) const {
286     int ttcIndexStorage;
287     if (nullptr == ttcIndex) {
288         // So our subclasses don't need to check for null param
289         ttcIndex = &ttcIndexStorage;
290     }
291     return this->onOpenStream(ttcIndex);
292 }
293 
unicharsToGlyphs(const SkUnichar uni[],int count,SkGlyphID glyphs[]) const294 void SkTypeface::unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
295     if (count > 0 && glyphs && uni) {
296         this->onCharsToGlyphs(uni, count, glyphs);
297     }
298 }
299 
unicharToGlyph(SkUnichar uni) const300 SkGlyphID SkTypeface::unicharToGlyph(SkUnichar uni) const {
301     SkGlyphID glyphs[1] = { 0 };
302     this->onCharsToGlyphs(&uni, 1, glyphs);
303     return glyphs[0];
304 }
305 
countGlyphs() const306 int SkTypeface::countGlyphs() const {
307     return this->onCountGlyphs();
308 }
309 
getUnitsPerEm() const310 int SkTypeface::getUnitsPerEm() const {
311     // should we try to cache this in the base-class?
312     return this->onGetUPEM();
313 }
314 
getKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const315 bool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count,
316                                            int32_t adjustments[]) const {
317     SkASSERT(count >= 0);
318     // check for the only legal way to pass a nullptr.. everything is 0
319     // in which case they just want to know if this face can possibly support
320     // kerning (true) or never (false).
321     if (nullptr == glyphs || nullptr == adjustments) {
322         SkASSERT(nullptr == glyphs);
323         SkASSERT(0 == count);
324         SkASSERT(nullptr == adjustments);
325     }
326     return this->onGetKerningPairAdjustments(glyphs, count, adjustments);
327 }
328 
createFamilyNameIterator() const329 SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
330     return this->onCreateFamilyNameIterator();
331 }
332 
getFamilyName(SkString * name) const333 void SkTypeface::getFamilyName(SkString* name) const {
334     SkASSERT(name);
335     this->onGetFamilyName(name);
336 }
337 
getPostScriptName(SkString * name) const338 bool SkTypeface::getPostScriptName(SkString* name) const {
339     return this->onGetPostScriptName(name);
340 }
341 
getGlyphToUnicodeMap(SkUnichar * dst) const342 void SkTypeface::getGlyphToUnicodeMap(SkUnichar* dst) const {
343     sk_bzero(dst, sizeof(SkUnichar) * this->countGlyphs());
344 }
345 
getAdvancedMetrics() const346 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::getAdvancedMetrics() const {
347     std::unique_ptr<SkAdvancedTypefaceMetrics> result = this->onGetAdvancedMetrics();
348     if (result && result->fPostScriptName.isEmpty()) {
349         result->fPostScriptName = result->fFontName;
350     }
351     if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
352         SkOTTableOS2::Version::V2::Type::Field fsType;
353         constexpr SkFontTableTag os2Tag = SkTEndian_SwapBE32(SkOTTableOS2::TAG);
354         constexpr size_t fsTypeOffset = offsetof(SkOTTableOS2::Version::V2, fsType);
355         if (this->getTableData(os2Tag, fsTypeOffset, sizeof(fsType), &fsType) == sizeof(fsType)) {
356             if (fsType.Bitmap || (fsType.Restricted && !(fsType.PreviewPrint || fsType.Editable))) {
357                 result->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
358             }
359             if (fsType.NoSubsetting) {
360                 result->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag;
361             }
362         }
363     }
364     return result;
365 }
366 
onGetKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const367 bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
368                                              int32_t adjustments[]) const {
369     return false;
370 }
371 
372 ///////////////////////////////////////////////////////////////////////////////
373 
374 #include "include/core/SkPaint.h"
375 #include "src/core/SkDescriptor.h"
376 
getBounds() const377 SkRect SkTypeface::getBounds() const {
378     fBoundsOnce([this] {
379         if (!this->onComputeBounds(&fBounds)) {
380             fBounds.setEmpty();
381         }
382     });
383     return fBounds;
384 }
385 
onComputeBounds(SkRect * bounds) const386 bool SkTypeface::onComputeBounds(SkRect* bounds) const {
387     // we use a big size to ensure lots of significant bits from the scalercontext.
388     // then we scale back down to return our final answer (at 1-pt)
389     const SkScalar textSize = 2048;
390     const SkScalar invTextSize = 1 / textSize;
391 
392     SkFont font;
393     font.setTypeface(sk_ref_sp(const_cast<SkTypeface*>(this)));
394     font.setSize(textSize);
395     font.setLinearMetrics(true);
396 
397     SkScalerContextRec rec;
398     SkScalerContextEffects effects;
399 
400     SkScalerContext::MakeRecAndEffectsFromFont(font, &rec, &effects);
401 
402     SkAutoDescriptor ad;
403     SkScalerContextEffects noeffects;
404     SkScalerContext::AutoDescriptorGivenRecAndEffects(rec, noeffects, &ad);
405 
406     std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, ad.getDesc());
407 
408     SkFontMetrics fm;
409     ctx->getFontMetrics(&fm);
410     if (!fm.hasBounds()) {
411         return false;
412     }
413     bounds->setLTRB(fm.fXMin * invTextSize, fm.fTop * invTextSize,
414                     fm.fXMax * invTextSize, fm.fBottom * invTextSize);
415     return true;
416 }
417 
onGetAdvancedMetrics() const418 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::onGetAdvancedMetrics() const {
419     SkDEBUGFAIL("Typefaces that need to work with PDF backend must override this.");
420     return nullptr;
421 }
422