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