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