• 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 "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     std::unique_ptr<SkScalerContext> onCreateScalerContext(
43         const SkScalerContextEffects& effects, const SkDescriptor* desc) const override
44     {
45         return SkScalerContext::MakeEmpty(
46                 sk_ref_sp(const_cast<SkEmptyTypeface*>(this)), effects, desc);
47     }
onFilterRec(SkScalerContextRec *) const48     void onFilterRec(SkScalerContextRec*) const override { }
onGetAdvancedMetrics() const49     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
50         return nullptr;
51     }
onGetFontDescriptor(SkFontDescriptor *,bool *) const52     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
onCharsToGlyphs(const SkUnichar * chars,int count,SkGlyphID glyphs[]) const53     void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
54         sk_bzero(glyphs, count * sizeof(glyphs[0]));
55     }
onCountGlyphs() const56     int onCountGlyphs() const override { return 0; }
getPostScriptGlyphNames(SkString *) const57     void getPostScriptGlyphNames(SkString*) const override {}
getGlyphToUnicodeMap(SkUnichar *) const58     void getGlyphToUnicodeMap(SkUnichar*) const override {}
onGetUPEM() const59     int onGetUPEM() const override { return 0; }
60     class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
61     public:
next(SkTypeface::LocalizedString *)62         bool next(SkTypeface::LocalizedString*) override { return false; }
63     };
onGetFamilyName(SkString * familyName) const64     void onGetFamilyName(SkString* familyName) const override {
65         familyName->reset();
66     }
onGetPostScriptName(SkString *) const67     bool onGetPostScriptName(SkString*) const override {
68         return false;
69     }
onCreateFamilyNameIterator() const70     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
71         return new EmptyLocalizedStrings;
72     }
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const73     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
74                                      int coordinateCount) const override
75     {
76         return 0;
77     }
onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount) const78     int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
79                                        int parameterCount) const override
80     {
81         return 0;
82     }
onGetTableTags(SkFontTableTag tags[]) const83     int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
onGetTableData(SkFontTableTag,size_t,size_t,void *) const84     size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
85         return 0;
86     }
87 };
88 
89 }  // namespace
90 
FromOldStyle(Style oldStyle)91 SkFontStyle SkTypeface::FromOldStyle(Style oldStyle) {
92     return SkFontStyle((oldStyle & SkTypeface::kBold) ? SkFontStyle::kBold_Weight
93                                                       : SkFontStyle::kNormal_Weight,
94                        SkFontStyle::kNormal_Width,
95                        (oldStyle & SkTypeface::kItalic) ? SkFontStyle::kItalic_Slant
96                                                         : SkFontStyle::kUpright_Slant);
97 }
98 
GetDefaultTypeface(Style style)99 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
100     static SkOnce once[4];
101     static sk_sp<SkTypeface> defaults[4];
102 
103     SkASSERT((int)style < 4);
104     once[style]([style] {
105         sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
106         auto t = fm->legacyMakeTypeface(nullptr, FromOldStyle(style));
107         defaults[style] = t ? t : SkEmptyTypeface::Make();
108     });
109     return defaults[style].get();
110 }
111 
MakeDefault()112 sk_sp<SkTypeface> SkTypeface::MakeDefault() {
113     return sk_ref_sp(GetDefaultTypeface());
114 }
115 
UniqueID(const SkTypeface * face)116 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
117     if (nullptr == face) {
118         face = GetDefaultTypeface();
119     }
120     return face->uniqueID();
121 }
122 
Equal(const SkTypeface * facea,const SkTypeface * faceb)123 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
124     return facea == faceb || SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
125 }
126 
127 ///////////////////////////////////////////////////////////////////////////////
128 
MakeFromName(const char name[],SkFontStyle fontStyle)129 sk_sp<SkTypeface> SkTypeface::MakeFromName(const char name[],
130                                            SkFontStyle fontStyle) {
131     if (nullptr == name && (fontStyle.slant() == SkFontStyle::kItalic_Slant ||
132                             fontStyle.slant() == SkFontStyle::kUpright_Slant) &&
133                            (fontStyle.weight() == SkFontStyle::kBold_Weight ||
134                             fontStyle.weight() == SkFontStyle::kNormal_Weight)) {
135         return sk_ref_sp(GetDefaultTypeface(static_cast<SkTypeface::Style>(
136             (fontStyle.slant() == SkFontStyle::kItalic_Slant ? SkTypeface::kItalic :
137                                                                SkTypeface::kNormal) |
138             (fontStyle.weight() == SkFontStyle::kBold_Weight ? SkTypeface::kBold :
139                                                                SkTypeface::kNormal))));
140     }
141     return SkFontMgr::RefDefault()->legacyMakeTypeface(name, fontStyle);
142 }
143 
MakeFromStream(std::unique_ptr<SkStreamAsset> stream,int index)144 sk_sp<SkTypeface> SkTypeface::MakeFromStream(std::unique_ptr<SkStreamAsset> stream, int index) {
145     if (!stream) {
146         return nullptr;
147     }
148     return SkFontMgr::RefDefault()->makeFromStream(std::move(stream), index);
149 }
150 
MakeFromData(sk_sp<SkData> data,int index)151 sk_sp<SkTypeface> SkTypeface::MakeFromData(sk_sp<SkData> data, int index) {
152     if (!data) {
153         return nullptr;
154     }
155     return SkFontMgr::RefDefault()->makeFromData(std::move(data), index);
156 }
157 
MakeFromFile(const char path[],int index)158 sk_sp<SkTypeface> SkTypeface::MakeFromFile(const char path[], int index) {
159     return SkFontMgr::RefDefault()->makeFromFile(path, index);
160 }
161 
makeClone(const SkFontArguments & args) const162 sk_sp<SkTypeface> SkTypeface::makeClone(const SkFontArguments& args) const {
163     return this->onMakeClone(args);
164 }
165 
166 ///////////////////////////////////////////////////////////////////////////////
167 
serialize(SkWStream * wstream,SerializeBehavior behavior) const168 void SkTypeface::serialize(SkWStream* wstream, SerializeBehavior behavior) const {
169     bool isLocalData = false;
170     SkFontDescriptor desc;
171     this->onGetFontDescriptor(&desc, &isLocalData);
172 
173     bool shouldSerializeData = false;
174     switch (behavior) {
175         case SerializeBehavior::kDoIncludeData:      shouldSerializeData = true;        break;
176         case SerializeBehavior::kDontIncludeData:    shouldSerializeData = false;       break;
177         case SerializeBehavior::kIncludeDataIfLocal: shouldSerializeData = isLocalData; break;
178     }
179 
180     if (shouldSerializeData) {
181         int index;
182         desc.setStream(this->openStream(&index));
183         if (desc.hasStream()) {
184             desc.setCollectionIndex(index);
185         }
186 
187         int numAxes = this->getVariationDesignPosition(nullptr, 0);
188         if (0 < numAxes) {
189             numAxes = this->getVariationDesignPosition(desc.setVariationCoordinates(numAxes), numAxes);
190             if (numAxes <= 0) {
191                 desc.setVariationCoordinates(0);
192             }
193         }
194     }
195     desc.serialize(wstream);
196 }
197 
serialize(SerializeBehavior behavior) const198 sk_sp<SkData> SkTypeface::serialize(SerializeBehavior behavior) const {
199     SkDynamicMemoryWStream stream;
200     this->serialize(&stream, behavior);
201     return stream.detachAsData();
202 }
203 
MakeDeserialize(SkStream * stream)204 sk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) {
205     SkFontDescriptor desc;
206     if (!SkFontDescriptor::Deserialize(stream, &desc)) {
207         return nullptr;
208     }
209 
210     if (desc.hasStream()) {
211         if (auto tf = SkCustomTypefaceBuilder::Deserialize(desc.dupStream().get())) {
212             return tf;
213         }
214     }
215 
216     // Have to check for old data format first.
217     std::unique_ptr<SkFontData> data = desc.maybeAsSkFontData();
218     if (data) {
219         // Should only get here with old skps.
220         sk_sp<SkFontMgr> defaultFm = SkFontMgr::RefDefault();
221         sk_sp<SkTypeface> typeface(defaultFm->makeFromFontData(std::move(data)));
222         if (typeface) {
223             return typeface;
224         }
225     }
226 
227     if (desc.hasStream()) {
228         SkFontArguments args;
229         args.setCollectionIndex(desc.getCollectionIndex());
230         args.setVariationDesignPosition({desc.getVariation(), desc.getVariationCoordinateCount()});
231         sk_sp<SkFontMgr> defaultFm = SkFontMgr::RefDefault();
232         sk_sp<SkTypeface> typeface = defaultFm->makeFromStream(desc.detachStream(), args);
233         if (typeface) {
234             return typeface;
235         }
236     }
237 
238     return SkTypeface::MakeFromName(desc.getFamilyName(), desc.getStyle());
239 }
240 
241 ///////////////////////////////////////////////////////////////////////////////
242 
getVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const243 int SkTypeface::getVariationDesignPosition(
244         SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
245 {
246     return this->onGetVariationDesignPosition(coordinates, coordinateCount);
247 }
248 
getVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount) const249 int SkTypeface::getVariationDesignParameters(
250         SkFontParameters::Variation::Axis parameters[], int parameterCount) const
251 {
252     return this->onGetVariationDesignParameters(parameters, parameterCount);
253 }
254 
countTables() const255 int SkTypeface::countTables() const {
256     return this->onGetTableTags(nullptr);
257 }
258 
getTableTags(SkFontTableTag tags[]) const259 int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
260     return this->onGetTableTags(tags);
261 }
262 
getTableSize(SkFontTableTag tag) const263 size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
264     return this->onGetTableData(tag, 0, ~0U, nullptr);
265 }
266 
getTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const267 size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
268                                 void* data) const {
269     return this->onGetTableData(tag, offset, length, data);
270 }
271 
copyTableData(SkFontTableTag tag) const272 sk_sp<SkData> SkTypeface::copyTableData(SkFontTableTag tag) const {
273     return this->onCopyTableData(tag);
274 }
275 
onCopyTableData(SkFontTableTag tag) const276 sk_sp<SkData> SkTypeface::onCopyTableData(SkFontTableTag tag) const {
277     size_t size = this->getTableSize(tag);
278     if (size) {
279         sk_sp<SkData> data = SkData::MakeUninitialized(size);
280         (void)this->getTableData(tag, 0, size, data->writable_data());
281         return data;
282     }
283     return nullptr;
284 }
285 
openStream(int * ttcIndex) const286 std::unique_ptr<SkStreamAsset> SkTypeface::openStream(int* ttcIndex) const {
287     int ttcIndexStorage;
288     if (nullptr == ttcIndex) {
289         // So our subclasses don't need to check for null param
290         ttcIndex = &ttcIndexStorage;
291     }
292     return this->onOpenStream(ttcIndex);
293 }
294 
createScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const295 std::unique_ptr<SkScalerContext> SkTypeface::createScalerContext(
296         const SkScalerContextEffects& effects, const SkDescriptor* desc) const {
297     std::unique_ptr<SkScalerContext> scalerContext = this->onCreateScalerContext(effects, desc);
298     SkASSERT(scalerContext);
299     return scalerContext;
300 }
301 
unicharsToGlyphs(const SkUnichar uni[],int count,SkGlyphID glyphs[]) const302 void SkTypeface::unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
303     if (count > 0 && glyphs && uni) {
304         this->onCharsToGlyphs(uni, count, glyphs);
305     }
306 }
307 
unicharToGlyph(SkUnichar uni) const308 SkGlyphID SkTypeface::unicharToGlyph(SkUnichar uni) const {
309     SkGlyphID glyphs[1] = { 0 };
310     this->onCharsToGlyphs(&uni, 1, glyphs);
311     return glyphs[0];
312 }
313 
countGlyphs() const314 int SkTypeface::countGlyphs() const {
315     return this->onCountGlyphs();
316 }
317 
getUnitsPerEm() const318 int SkTypeface::getUnitsPerEm() const {
319     // should we try to cache this in the base-class?
320     return this->onGetUPEM();
321 }
322 
getKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const323 bool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count,
324                                            int32_t adjustments[]) const {
325     SkASSERT(count >= 0);
326     // check for the only legal way to pass a nullptr.. everything is 0
327     // in which case they just want to know if this face can possibly support
328     // kerning (true) or never (false).
329     if (nullptr == glyphs || nullptr == adjustments) {
330         SkASSERT(nullptr == glyphs);
331         SkASSERT(0 == count);
332         SkASSERT(nullptr == adjustments);
333     }
334     return this->onGetKerningPairAdjustments(glyphs, count, adjustments);
335 }
336 
createFamilyNameIterator() const337 SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
338     return this->onCreateFamilyNameIterator();
339 }
340 
getFamilyName(SkString * name) const341 void SkTypeface::getFamilyName(SkString* name) const {
342     SkASSERT(name);
343     this->onGetFamilyName(name);
344 }
345 
getPostScriptName(SkString * name) const346 bool SkTypeface::getPostScriptName(SkString* name) const {
347     return this->onGetPostScriptName(name);
348 }
349 
getGlyphToUnicodeMap(SkUnichar * dst) const350 void SkTypeface::getGlyphToUnicodeMap(SkUnichar* dst) const {
351     sk_bzero(dst, sizeof(SkUnichar) * this->countGlyphs());
352 }
353 
getAdvancedMetrics() const354 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::getAdvancedMetrics() const {
355     std::unique_ptr<SkAdvancedTypefaceMetrics> result = this->onGetAdvancedMetrics();
356     if (result && result->fPostScriptName.isEmpty()) {
357         result->fPostScriptName = result->fFontName;
358     }
359     if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
360         SkOTTableOS2::Version::V2::Type::Field fsType;
361         constexpr SkFontTableTag os2Tag = SkTEndian_SwapBE32(SkOTTableOS2::TAG);
362         constexpr size_t fsTypeOffset = offsetof(SkOTTableOS2::Version::V2, fsType);
363         if (this->getTableData(os2Tag, fsTypeOffset, sizeof(fsType), &fsType) == sizeof(fsType)) {
364             if (fsType.Bitmap || (fsType.Restricted && !(fsType.PreviewPrint || fsType.Editable))) {
365                 result->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
366             }
367             if (fsType.NoSubsetting) {
368                 result->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag;
369             }
370         }
371     }
372     return result;
373 }
374 
onGetKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const375 bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
376                                              int32_t adjustments[]) const {
377     return false;
378 }
379 
380 ///////////////////////////////////////////////////////////////////////////////
381 
382 #include "include/core/SkPaint.h"
383 #include "src/core/SkDescriptor.h"
384 
getBounds() const385 SkRect SkTypeface::getBounds() const {
386     fBoundsOnce([this] {
387         if (!this->onComputeBounds(&fBounds)) {
388             fBounds.setEmpty();
389         }
390     });
391     return fBounds;
392 }
393 
onComputeBounds(SkRect * bounds) const394 bool SkTypeface::onComputeBounds(SkRect* bounds) const {
395     // we use a big size to ensure lots of significant bits from the scalercontext.
396     // then we scale back down to return our final answer (at 1-pt)
397     const SkScalar textSize = 2048;
398     const SkScalar invTextSize = 1 / textSize;
399 
400     SkFont font;
401     font.setTypeface(sk_ref_sp(const_cast<SkTypeface*>(this)));
402     font.setSize(textSize);
403     font.setLinearMetrics(true);
404 
405     SkScalerContextRec rec;
406     SkScalerContextEffects effects;
407 
408     SkScalerContext::MakeRecAndEffectsFromFont(font, &rec, &effects);
409 
410     SkAutoDescriptor ad;
411     SkScalerContextEffects noeffects;
412     SkScalerContext::AutoDescriptorGivenRecAndEffects(rec, noeffects, &ad);
413 
414     std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, ad.getDesc());
415 
416     SkFontMetrics fm;
417     ctx->getFontMetrics(&fm);
418     if (!fm.hasBounds()) {
419         return false;
420     }
421     bounds->setLTRB(fm.fXMin * invTextSize, fm.fTop * invTextSize,
422                     fm.fXMax * invTextSize, fm.fBottom * invTextSize);
423     return true;
424 }
425 
onGetAdvancedMetrics() const426 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::onGetAdvancedMetrics() const {
427     SkDEBUGFAIL("Typefaces that need to work with PDF backend must override this.");
428     return nullptr;
429 }
430