Line data Source code
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 :
20 2 : SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch)
21 2 : : fUniqueID(SkTypefaceCache::NewFontID()), fStyle(style), fIsFixedPitch(isFixedPitch) { }
22 :
23 0 : 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 0 : class SkEmptyTypeface : public SkTypeface {
42 : public:
43 0 : static SkEmptyTypeface* Create() { return new SkEmptyTypeface; }
44 : protected:
45 0 : SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
46 :
47 0 : SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; }
48 0 : SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
49 : const SkDescriptor*) const override {
50 0 : return nullptr;
51 : }
52 0 : void onFilterRec(SkScalerContextRec*) const override { }
53 0 : virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
54 : PerGlyphInfo,
55 0 : const uint32_t*, uint32_t) const override { return nullptr; }
56 0 : void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
57 0 : virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
58 : uint16_t glyphs[], int glyphCount) const override {
59 0 : if (glyphs && glyphCount > 0) {
60 0 : sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
61 : }
62 0 : return 0;
63 : }
64 0 : int onCountGlyphs() const override { return 0; }
65 0 : int onGetUPEM() const override { return 0; }
66 0 : class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
67 : public:
68 0 : bool next(SkTypeface::LocalizedString*) override { return false; }
69 : };
70 0 : void onGetFamilyName(SkString* familyName) const override {
71 0 : familyName->reset();
72 0 : }
73 0 : SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
74 0 : return new EmptyLocalizedStrings;
75 : }
76 0 : int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
77 : int coordinateCount) const override
78 : {
79 0 : return 0;
80 : }
81 0 : int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
82 0 : size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
83 0 : return 0;
84 : }
85 : };
86 :
87 : }
88 :
89 0 : SkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
90 : static SkOnce once[4];
91 : static SkTypeface* defaults[4];
92 :
93 0 : SkASSERT((int)style < 4);
94 0 : once[style]([style] {
95 0 : sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
96 0 : SkTypeface* t = fm->legacyCreateTypeface(nullptr, SkFontStyle::FromOldStyle(style));
97 0 : defaults[style] = t ? t : SkEmptyTypeface::Create();
98 0 : });
99 0 : return defaults[style];
100 : }
101 :
102 0 : sk_sp<SkTypeface> SkTypeface::MakeDefault(Style style) {
103 0 : return sk_ref_sp(GetDefaultTypeface(style));
104 : }
105 :
106 0 : uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
107 0 : if (nullptr == face) {
108 0 : face = GetDefaultTypeface();
109 : }
110 0 : return face->uniqueID();
111 : }
112 :
113 0 : bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
114 0 : return facea == faceb || SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
115 : }
116 :
117 : ///////////////////////////////////////////////////////////////////////////////
118 :
119 0 : sk_sp<SkTypeface> SkTypeface::MakeFromName(const char name[],
120 : SkFontStyle fontStyle) {
121 0 : if (gCreateTypefaceDelegate) {
122 0 : sk_sp<SkTypeface> result = (*gCreateTypefaceDelegate)(name, fontStyle);
123 0 : if (result) {
124 0 : return result;
125 : }
126 : }
127 0 : if (nullptr == name && (fontStyle.slant() == SkFontStyle::kItalic_Slant ||
128 0 : fontStyle.slant() == SkFontStyle::kUpright_Slant) &&
129 0 : (fontStyle.weight() == SkFontStyle::kBold_Weight ||
130 0 : fontStyle.weight() == SkFontStyle::kNormal_Weight)) {
131 : return MakeDefault(static_cast<SkTypeface::Style>(
132 0 : (fontStyle.slant() == SkFontStyle::kItalic_Slant ? SkTypeface::kItalic :
133 0 : SkTypeface::kNormal) |
134 0 : (fontStyle.weight() == SkFontStyle::kBold_Weight ? SkTypeface::kBold :
135 0 : SkTypeface::kNormal)));
136 : }
137 0 : sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
138 0 : return sk_sp<SkTypeface>(fm->legacyCreateTypeface(name, fontStyle));
139 : }
140 :
141 0 : sk_sp<SkTypeface> SkTypeface::MakeFromTypeface(SkTypeface* family, Style s) {
142 0 : if (!family) {
143 0 : return SkTypeface::MakeDefault(s);
144 : }
145 :
146 0 : if (family->style() == s) {
147 0 : return sk_ref_sp(family);
148 : }
149 :
150 0 : sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
151 0 : return sk_sp<SkTypeface>(fm->matchFaceStyle(family, SkFontStyle::FromOldStyle(s)));
152 : }
153 :
154 0 : sk_sp<SkTypeface> SkTypeface::MakeFromStream(SkStreamAsset* stream, int index) {
155 0 : sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
156 0 : return sk_sp<SkTypeface>(fm->createFromStream(stream, index));
157 : }
158 :
159 0 : sk_sp<SkTypeface> SkTypeface::MakeFromFontData(std::unique_ptr<SkFontData> data) {
160 0 : sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
161 0 : return sk_sp<SkTypeface>(fm->createFromFontData(std::move(data)));
162 : }
163 :
164 0 : sk_sp<SkTypeface> SkTypeface::MakeFromFile(const char path[], int index) {
165 0 : sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
166 0 : return sk_sp<SkTypeface>(fm->createFromFile(path, index));
167 : }
168 :
169 : ///////////////////////////////////////////////////////////////////////////////
170 :
171 0 : void SkTypeface::serialize(SkWStream* wstream) const {
172 0 : if (gSerializeTypefaceDelegate) {
173 0 : (*gSerializeTypefaceDelegate)(this, wstream);
174 0 : return;
175 : }
176 0 : bool isLocal = false;
177 0 : SkFontDescriptor desc;
178 0 : this->onGetFontDescriptor(&desc, &isLocal);
179 :
180 : // Embed font data if it's a local font.
181 0 : if (isLocal && !desc.hasFontData()) {
182 0 : desc.setFontData(this->onMakeFontData());
183 : }
184 0 : desc.serialize(wstream);
185 : }
186 :
187 0 : sk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) {
188 0 : if (gDeserializeTypefaceDelegate) {
189 0 : return (*gDeserializeTypefaceDelegate)(stream);
190 : }
191 :
192 0 : SkFontDescriptor desc;
193 0 : if (!SkFontDescriptor::Deserialize(stream, &desc)) {
194 0 : return nullptr;
195 : }
196 :
197 0 : std::unique_ptr<SkFontData> data = desc.detachFontData();
198 0 : if (data) {
199 0 : sk_sp<SkTypeface> typeface(SkTypeface::MakeFromFontData(std::move(data)));
200 0 : if (typeface) {
201 0 : return typeface;
202 : }
203 : }
204 :
205 0 : return SkTypeface::MakeFromName(desc.getFamilyName(), desc.getStyle());
206 : }
207 :
208 : ///////////////////////////////////////////////////////////////////////////////
209 :
210 0 : int SkTypeface::getVariationDesignPosition(
211 : SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
212 : {
213 0 : return this->onGetVariationDesignPosition(coordinates, coordinateCount);
214 : }
215 :
216 0 : int SkTypeface::countTables() const {
217 0 : return this->onGetTableTags(nullptr);
218 : }
219 :
220 0 : int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
221 0 : return this->onGetTableTags(tags);
222 : }
223 :
224 0 : size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
225 0 : return this->onGetTableData(tag, 0, ~0U, nullptr);
226 : }
227 :
228 0 : size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
229 : void* data) const {
230 0 : return this->onGetTableData(tag, offset, length, data);
231 : }
232 :
233 0 : SkStreamAsset* SkTypeface::openStream(int* ttcIndex) const {
234 : int ttcIndexStorage;
235 0 : if (nullptr == ttcIndex) {
236 : // So our subclasses don't need to check for null param
237 0 : ttcIndex = &ttcIndexStorage;
238 : }
239 0 : return this->onOpenStream(ttcIndex);
240 : }
241 :
242 0 : std::unique_ptr<SkFontData> SkTypeface::makeFontData() const {
243 0 : return this->onMakeFontData();
244 : }
245 :
246 : // This implementation is temporary until this method can be made pure virtual.
247 0 : std::unique_ptr<SkFontData> SkTypeface::onMakeFontData() const {
248 : int index;
249 0 : std::unique_ptr<SkStreamAsset> stream(this->onOpenStream(&index));
250 0 : return skstd::make_unique<SkFontData>(std::move(stream), index, nullptr, 0);
251 : };
252 :
253 0 : int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding,
254 : uint16_t glyphs[], int glyphCount) const {
255 0 : if (glyphCount <= 0) {
256 0 : return 0;
257 : }
258 0 : if (nullptr == chars || (unsigned)encoding > kUTF32_Encoding) {
259 0 : if (glyphs) {
260 0 : sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
261 : }
262 0 : return 0;
263 : }
264 0 : return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount);
265 : }
266 :
267 0 : int SkTypeface::countGlyphs() const {
268 0 : return this->onCountGlyphs();
269 : }
270 :
271 0 : int SkTypeface::getUnitsPerEm() const {
272 : // should we try to cache this in the base-class?
273 0 : return this->onGetUPEM();
274 : }
275 :
276 0 : bool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count,
277 : int32_t adjustments[]) const {
278 0 : 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 0 : if (nullptr == glyphs || nullptr == adjustments) {
283 0 : SkASSERT(nullptr == glyphs);
284 0 : SkASSERT(0 == count);
285 0 : SkASSERT(nullptr == adjustments);
286 : }
287 0 : return this->onGetKerningPairAdjustments(glyphs, count, adjustments);
288 : }
289 :
290 0 : SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
291 0 : return this->onCreateFamilyNameIterator();
292 : }
293 :
294 0 : void SkTypeface::getFamilyName(SkString* name) const {
295 0 : SkASSERT(name);
296 0 : this->onGetFamilyName(name);
297 0 : }
298 :
299 0 : SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
300 : PerGlyphInfo info,
301 : const uint32_t* glyphIDs,
302 : uint32_t glyphIDsCount) const {
303 : SkAdvancedTypefaceMetrics* result =
304 0 : this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
305 0 : if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
306 : SkOTTableOS2::Version::V2::Type::Field fsType;
307 0 : constexpr SkFontTableTag os2Tag = SkTEndian_SwapBE32(SkOTTableOS2::TAG);
308 0 : constexpr size_t fsTypeOffset = offsetof(SkOTTableOS2::Version::V2, fsType);
309 0 : if (this->getTableData(os2Tag, fsTypeOffset, sizeof(fsType), &fsType) == sizeof(fsType)) {
310 0 : if (fsType.Bitmap || (fsType.Restricted && !(fsType.PreviewPrint || fsType.Editable))) {
311 0 : result->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
312 : }
313 0 : if (fsType.NoSubsetting) {
314 0 : result->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag;
315 : }
316 : }
317 : }
318 0 : return result;
319 : }
320 :
321 0 : bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
322 : int32_t adjustments[]) const {
323 0 : return false;
324 : }
325 :
326 : ///////////////////////////////////////////////////////////////////////////////
327 :
328 : #include "SkDescriptor.h"
329 : #include "SkPaint.h"
330 :
331 0 : SkRect SkTypeface::getBounds() const {
332 0 : fBoundsOnce([this] {
333 0 : if (!this->onComputeBounds(&fBounds)) {
334 0 : fBounds.setEmpty();
335 : }
336 0 : });
337 0 : return fBounds;
338 : }
339 :
340 0 : bool SkTypeface::onComputeBounds(SkRect* bounds) const {
341 : // we use a big size to ensure lots of significant bits from the scalercontext.
342 : // then we scale back down to return our final answer (at 1-pt)
343 0 : const SkScalar textSize = 2048;
344 0 : const SkScalar invTextSize = 1 / textSize;
345 :
346 0 : SkPaint paint;
347 0 : paint.setTypeface(sk_ref_sp(const_cast<SkTypeface*>(this)));
348 0 : paint.setTextSize(textSize);
349 0 : paint.setLinearText(true);
350 :
351 : SkScalerContext::Rec rec;
352 0 : SkScalerContext::MakeRec(paint, nullptr, nullptr, &rec);
353 :
354 0 : SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
355 0 : SkDescriptor* desc = ad.getDesc();
356 0 : desc->init();
357 0 : desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
358 :
359 0 : SkScalerContextEffects noeffects;
360 0 : std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, desc, true);
361 0 : if (!ctx) {
362 0 : return false;
363 : }
364 :
365 : SkPaint::FontMetrics fm;
366 0 : ctx->getFontMetrics(&fm);
367 0 : bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize,
368 0 : fm.fXMax * invTextSize, fm.fBottom * invTextSize);
369 0 : return true;
370 : }
|