• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkTypeface(const SkFontStyle & style,bool isFixedPitch)20 SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch)
21     : fUniqueID(SkTypefaceCache::NewFontID()), fStyle(style), fIsFixedPitch(isFixedPitch) { }
22 
~SkTypeface()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:
Create()43     static SkEmptyTypeface* Create() { return new SkEmptyTypeface; }
44 protected:
SkEmptyTypeface()45     SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
46 
onOpenStream(int * ttcIndex) const47     SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; }
onCreateScalerContext(const SkScalerContextEffects &,const SkDescriptor *) const48     SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
49                                            const SkDescriptor*) const override {
50         return nullptr;
51     }
onFilterRec(SkScalerContextRec *) const52     void onFilterRec(SkScalerContextRec*) const override { }
onGetAdvancedMetrics() const53     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
54         return nullptr;
55     }
onGetFontDescriptor(SkFontDescriptor *,bool *) const56     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
onCharsToGlyphs(const void * chars,Encoding encoding,uint16_t glyphs[],int glyphCount) const57     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     }
onCountGlyphs() const64     int onCountGlyphs() const override { return 0; }
onGetUPEM() const65     int onGetUPEM() const override { return 0; }
66     class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
67     public:
next(SkTypeface::LocalizedString *)68         bool next(SkTypeface::LocalizedString*) override { return false; }
69     };
onGetFamilyName(SkString * familyName) const70     void onGetFamilyName(SkString* familyName) const override {
71         familyName->reset();
72     }
onCreateFamilyNameIterator() const73     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
74         return new EmptyLocalizedStrings;
75     }
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const76     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
77                                      int coordinateCount) const override
78     {
79         return 0;
80     }
onGetTableTags(SkFontTableTag tags[]) const81     int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
onGetTableData(SkFontTableTag,size_t,size_t,void *) const82     size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
83         return 0;
84     }
85 };
86 
87 }
88 
GetDefaultTypeface(Style style)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 
MakeDefault(Style style)102 sk_sp<SkTypeface> SkTypeface::MakeDefault(Style style) {
103     return sk_ref_sp(GetDefaultTypeface(style));
104 }
105 
UniqueID(const SkTypeface * face)106 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
107     if (nullptr == face) {
108         face = GetDefaultTypeface();
109     }
110     return face->uniqueID();
111 }
112 
Equal(const SkTypeface * facea,const SkTypeface * faceb)113 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
114     return facea == faceb || SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
115 }
116 
117 ///////////////////////////////////////////////////////////////////////////////
118 
MakeFromName(const char name[],SkFontStyle fontStyle)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 
MakeFromTypeface(SkTypeface * family,Style s)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 
MakeFromStream(SkStreamAsset * stream,int index)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 
MakeFromFontData(std::unique_ptr<SkFontData> data)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 
MakeFromFile(const char path[],int index)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 
serialize(SkWStream * wstream) const171 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 
MakeDeserialize(SkStream * stream)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 
getVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const210 int SkTypeface::getVariationDesignPosition(
211         SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
212 {
213     return this->onGetVariationDesignPosition(coordinates, coordinateCount);
214 }
215 
countTables() const216 int SkTypeface::countTables() const {
217     return this->onGetTableTags(nullptr);
218 }
219 
getTableTags(SkFontTableTag tags[]) const220 int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
221     return this->onGetTableTags(tags);
222 }
223 
getTableSize(SkFontTableTag tag) const224 size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
225     return this->onGetTableData(tag, 0, ~0U, nullptr);
226 }
227 
getTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const228 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 
openStream(int * ttcIndex) const233 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 
makeFontData() const242 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.
onMakeFontData() const247 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 
charsToGlyphs(const void * chars,Encoding encoding,uint16_t glyphs[],int glyphCount) const253 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 
countGlyphs() const267 int SkTypeface::countGlyphs() const {
268     return this->onCountGlyphs();
269 }
270 
getUnitsPerEm() const271 int SkTypeface::getUnitsPerEm() const {
272     // should we try to cache this in the base-class?
273     return this->onGetUPEM();
274 }
275 
getKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const276 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 
createFamilyNameIterator() const290 SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
291     return this->onCreateFamilyNameIterator();
292 }
293 
getFamilyName(SkString * name) const294 void SkTypeface::getFamilyName(SkString* name) const {
295     SkASSERT(name);
296     this->onGetFamilyName(name);
297 }
298 
getAdvancedMetrics() const299 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 
onGetKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const317 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 
getBounds() const327 SkRect SkTypeface::getBounds() const {
328     fBoundsOnce([this] {
329         if (!this->onComputeBounds(&fBounds)) {
330             fBounds.setEmpty();
331         }
332     });
333     return fBounds;
334 }
335 
onComputeBounds(SkRect * bounds) const336 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 
onGetAdvancedMetrics() const368 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