Flutter Engine
The Flutter Engine
SkTypeface.cpp
Go to the documentation of this file.
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 */
8
10#include "include/core/SkFont.h"
22#include "src/base/SkEndian.h"
24#include "src/base/SkUTF.h"
28#include "src/core/SkFontPriv.h"
32
33#ifdef SK_TYPEFACE_FACTORY_FREETYPE
35#endif
36
37#ifdef SK_TYPEFACE_FACTORY_CORETEXT
39#endif
40
41#ifdef SK_TYPEFACE_FACTORY_DIRECTWRITE
43#endif
44
45// TODO(https://crbug.com/skia/14338): This needs to be set by Bazel rules.
46#ifdef SK_TYPEFACE_FACTORY_FONTATIONS
48#endif
49
50#include <cstddef>
51#include <cstring>
52#include <vector>
53
54using namespace skia_private;
55
56SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch)
57 : fUniqueID(SkTypefaceCache::NewTypefaceID()), fStyle(style), fIsFixedPitch(isFixedPitch) { }
58
60
61///////////////////////////////////////////////////////////////////////////////
62
63namespace {
64
65class SkEmptyTypeface : public SkTypeface {
66public:
67 static sk_sp<SkTypeface> Make() {
69 return sk_ref_sp(instance.get());
70 }
71
72 static constexpr SkTypeface::FactoryId FactoryId = SkSetFourByteTag('e','m','t','y');
73 static sk_sp<SkTypeface> MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
74 const SkFontArguments&) {
75 if (stream->getLength() == 0) {
76 return SkEmptyTypeface::Make();
77 }
78 return nullptr;
79 }
80protected:
82 SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { }
83
84 std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override { return nullptr; }
85 sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
86 return sk_ref_sp(this);
87 }
88 std::unique_ptr<SkScalerContext> onCreateScalerContext(
89 const SkScalerContextEffects& effects, const SkDescriptor* desc) const override
90 {
92 sk_ref_sp(const_cast<SkEmptyTypeface*>(this)), effects, desc);
93 }
94 void onFilterRec(SkScalerContextRec*) const override { }
95 std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override {
96 return nullptr;
97 }
98 void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
99 desc->setFactoryId(FactoryId);
100 *serialize = false;
101 }
102 void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override {
103 sk_bzero(glyphs, count * sizeof(glyphs[0]));
104 }
105 int onCountGlyphs() const override { return 0; }
106 void getPostScriptGlyphNames(SkString*) const override {}
107 void getGlyphToUnicodeMap(SkUnichar*) const override {}
108 int onGetUPEM() const override { return 0; }
109 bool onComputeBounds(SkRect* bounds) const override { return false; }
110
111 class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
112 public:
113 bool next(SkTypeface::LocalizedString*) override { return false; }
114 };
115 void onGetFamilyName(SkString* familyName) const override {
116 familyName->reset();
117 }
118 bool onGetPostScriptName(SkString*) const override {
119 return false;
120 }
122 return new EmptyLocalizedStrings;
123 }
124 bool onGlyphMaskNeedsCurrentColor() const override {
125 return false;
126 }
128 int coordinateCount) const override
129 {
130 return 0;
131 }
133 int parameterCount) const override
134 {
135 return 0;
136 }
137 int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
138 size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
139 return 0;
140 }
141};
142
143} // namespace
144
146 return SkEmptyTypeface::Make();
147}
148
149bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
150 if (facea == faceb) {
151 return true;
152 }
153 if (!facea || !faceb) {
154 return false;
155 }
156 return facea->uniqueID() == faceb->uniqueID();
157}
158
159///////////////////////////////////////////////////////////////////////////////
160
161namespace {
162
163 struct DecoderProc {
165 sk_sp<SkTypeface> (*makeFromStream)(std::unique_ptr<SkStreamAsset>, const SkFontArguments&);
166 };
167
168 std::vector<DecoderProc>* decoders() {
170 { SkEmptyTypeface::FactoryId, SkEmptyTypeface::MakeFromStream },
172#ifdef SK_TYPEFACE_FACTORY_CORETEXT
173 { SkTypeface_Mac::FactoryId, SkTypeface_Mac::MakeFromStream },
174#endif
175#ifdef SK_TYPEFACE_FACTORY_DIRECTWRITE
177#endif
178#ifdef SK_TYPEFACE_FACTORY_FREETYPE
180#endif
181#ifdef SK_TYPEFACE_FACTORY_FONTATIONS
183#endif
184 }};
185 return decoders.get();
186 }
187
188} // namespace
189
191 return this->onMakeClone(args);
192}
193
194///////////////////////////////////////////////////////////////////////////////
195
197 FactoryId id,
198 sk_sp<SkTypeface> (*make)(std::unique_ptr<SkStreamAsset>, const SkFontArguments&)) {
199 decoders()->push_back(DecoderProc{id, make});
200}
201
202void SkTypeface::serialize(SkWStream* wstream, SerializeBehavior behavior) const {
203 bool isLocalData = false;
205 this->onGetFontDescriptor(&desc, &isLocalData);
206 if (desc.getFactoryId() == 0) {
207 SkDEBUGF("Factory was not set for %s.\n", desc.getFamilyName());
208 }
209
210 bool shouldSerializeData = false;
211 switch (behavior) {
212 case SerializeBehavior::kDoIncludeData: shouldSerializeData = true; break;
213 case SerializeBehavior::kDontIncludeData: shouldSerializeData = false; break;
214 case SerializeBehavior::kIncludeDataIfLocal: shouldSerializeData = isLocalData; break;
215 }
216
217 if (shouldSerializeData) {
218 int index;
219 desc.setStream(this->openStream(&index));
220 if (desc.hasStream()) {
221 desc.setCollectionIndex(index);
222 }
223
224 int numAxes = this->getVariationDesignPosition(nullptr, 0);
225 if (0 < numAxes) {
226 numAxes = this->getVariationDesignPosition(desc.setVariationCoordinates(numAxes), numAxes);
227 if (numAxes <= 0) {
228 desc.setVariationCoordinates(0);
229 }
230 }
231 }
232 desc.serialize(wstream);
233}
234
237 this->serialize(&stream, behavior);
238 return stream.detachAsData();
239}
240
244 return nullptr;
245 }
246
247 if (desc.hasStream()) {
248 for (const DecoderProc& proc : *decoders()) {
249 if (proc.id == desc.getFactoryId()) {
250 return proc.makeFromStream(desc.detachStream(), desc.getFontArguments());
251 }
252 }
253
254 [[maybe_unused]] FactoryId id = desc.getFactoryId();
255 SkDEBUGF("Could not find factory %c%c%c%c for %s.\n",
256 (char)((id >> 24) & 0xFF),
257 (char)((id >> 16) & 0xFF),
258 (char)((id >> 8) & 0xFF),
259 (char)((id >> 0) & 0xFF),
260 desc.getFamilyName());
261
262 if (lastResortMgr) {
263 // If we've gotten to here, we will try desperately to find something that might match
264 // as a kind of last ditch effort to make something work (and maybe this SkFontMgr knows
265 // something about the serialization and can look up the right thing by name anyway if
266 // the user provides it).
267 // Any time it is used the user will probably get the wrong glyphs drawn (and if they're
268 // right it is totally by accident). But sometimes drawing something or getting lucky
269 // while debugging is better than drawing nothing at all.
270 sk_sp<SkTypeface> typeface = lastResortMgr->makeFromStream(desc.detachStream(),
271 desc.getFontArguments());
272 if (typeface) {
273 return typeface;
274 }
275 }
276 }
277 if (lastResortMgr) {
278 return lastResortMgr->legacyMakeTypeface(desc.getFamilyName(), desc.getStyle());
279 }
280 return SkEmptyTypeface::Make();
281}
282
283///////////////////////////////////////////////////////////////////////////////
284
285bool SkTypeface::glyphMaskNeedsCurrentColor() const {
286 return this->onGlyphMaskNeedsCurrentColor();
287}
288
290 SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
291{
292 return this->onGetVariationDesignPosition(coordinates, coordinateCount);
293}
294
296 SkFontParameters::Variation::Axis parameters[], int parameterCount) const
297{
298 return this->onGetVariationDesignParameters(parameters, parameterCount);
299}
300
302 return this->onGetTableTags(nullptr);
303}
304
306 return this->onGetTableTags(tags);
307}
308
310 return this->onGetTableData(tag, 0, ~0U, nullptr);
311}
312
314 void* data) const {
315 return this->onGetTableData(tag, offset, length, data);
316}
317
319 return this->onCopyTableData(tag);
320}
321
323 size_t size = this->getTableSize(tag);
324 if (size) {
326 (void)this->getTableData(tag, 0, size, data->writable_data());
327 return data;
328 }
329 return nullptr;
330}
331
332std::unique_ptr<SkStreamAsset> SkTypeface::openStream(int* ttcIndex) const {
333 int ttcIndexStorage;
334 if (nullptr == ttcIndex) {
335 // So our subclasses don't need to check for null param
336 ttcIndex = &ttcIndexStorage;
337 }
338 return this->onOpenStream(ttcIndex);
339}
340
341std::unique_ptr<SkStreamAsset> SkTypeface::openExistingStream(int* ttcIndex) const {
342 int ttcIndexStorage;
343 if (nullptr == ttcIndex) {
344 // So our subclasses don't need to check for null param
345 ttcIndex = &ttcIndexStorage;
346 }
347 return this->onOpenExistingStream(ttcIndex);
348}
349
350std::unique_ptr<SkScalerContext> SkTypeface::createScalerContext(
351 const SkScalerContextEffects& effects, const SkDescriptor* desc) const {
352 std::unique_ptr<SkScalerContext> scalerContext = this->onCreateScalerContext(effects, desc);
353 SkASSERT(scalerContext);
354 return scalerContext;
355}
356
358 if (count > 0 && glyphs && uni) {
359 this->onCharsToGlyphs(uni, count, glyphs);
360 }
361}
362
364 SkGlyphID glyphs[1] = { 0 };
365 this->onCharsToGlyphs(&uni, 1, glyphs);
366 return glyphs[0];
367}
368
369namespace {
370class SkConvertToUTF32 {
371public:
372 SkConvertToUTF32() {}
373
374 const SkUnichar* convert(const void* text, size_t byteLength, SkTextEncoding encoding) {
375 const SkUnichar* uni;
376 switch (encoding) {
378 uni = fStorage.reset(byteLength);
379 const char* ptr = (const char*)text;
380 const char* end = ptr + byteLength;
381 for (int i = 0; ptr < end; ++i) {
382 fStorage[i] = SkUTF::NextUTF8(&ptr, end);
383 }
384 } break;
386 uni = fStorage.reset(byteLength);
387 const uint16_t* ptr = (const uint16_t*)text;
388 const uint16_t* end = ptr + (byteLength >> 1);
389 for (int i = 0; ptr < end; ++i) {
390 fStorage[i] = SkUTF::NextUTF16(&ptr, end);
391 }
392 } break;
394 uni = (const SkUnichar*)text;
395 break;
396 default:
397 SK_ABORT("unexpected enum");
398 }
399 return uni;
400 }
401
402private:
404};
405}
406
407int SkTypeface::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
408 SkGlyphID glyphs[], int maxGlyphCount) const {
409 if (0 == byteLength) {
410 return 0;
411 }
412
413 SkASSERT(text);
414
415 int count = SkFontPriv::CountTextElements(text, byteLength, encoding);
416 if (!glyphs || count > maxGlyphCount) {
417 return count;
418 }
419
420 if (encoding == SkTextEncoding::kGlyphID) {
421 memcpy(glyphs, text, count << 1);
422 return count;
423 }
424
425 SkConvertToUTF32 storage;
426 const SkUnichar* uni = storage.convert(text, byteLength, encoding);
427
428 this->unicharsToGlyphs(uni, count, glyphs);
429 return count;
430}
431
433 return this->onCountGlyphs();
434}
435
437 // should we try to cache this in the base-class?
438 return this->onGetUPEM();
439}
440
442 int32_t adjustments[]) const {
443 SkASSERT(count >= 0);
444 // check for the only legal way to pass a nullptr.. everything is 0
445 // in which case they just want to know if this face can possibly support
446 // kerning (true) or never (false).
447 if (nullptr == glyphs || nullptr == adjustments) {
448 SkASSERT(nullptr == glyphs);
449 SkASSERT(0 == count);
450 SkASSERT(nullptr == adjustments);
451 }
452 return this->onGetKerningPairAdjustments(glyphs, count, adjustments);
453}
454
456 return this->onCreateFamilyNameIterator();
457}
458
460 SkASSERT(name);
461 this->onGetFamilyName(name);
462}
463
465 return this->onGetPostScriptName(name);
466}
467
469 sk_bzero(dst, sizeof(SkUnichar) * this->countGlyphs());
470}
471
472std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface::getAdvancedMetrics() const {
473 std::unique_ptr<SkAdvancedTypefaceMetrics> result = this->onGetAdvancedMetrics();
474 if (result && result->fPostScriptName.isEmpty()) {
475 if (!this->getPostScriptName(&result->fPostScriptName)) {
476 this->getFamilyName(&result->fPostScriptName);
477 }
478 }
481 SkOTTableOS2::Version::V2::Type::Field fsType;
483 constexpr size_t fsTypeOffset = offsetof(SkOTTableOS2::Version::V2, fsType);
484 if (this->getTableData(os2Tag, fsTypeOffset, sizeof(fsType), &fsType) == sizeof(fsType)) {
485 if (fsType.Bitmap || (fsType.Restricted && !(fsType.PreviewPrint || fsType.Editable))) {
487 }
488 if (fsType.NoSubsetting) {
490 }
491 }
492 }
493 return result;
494}
495
497 int32_t adjustments[]) const {
498 return false;
499}
500
501std::unique_ptr<SkStreamAsset> SkTypeface::onOpenExistingStream(int* ttcIndex) const {
502 return this->onOpenStream(ttcIndex);
503}
504
505///////////////////////////////////////////////////////////////////////////////
506
508 fBoundsOnce([this] {
509 if (!this->onComputeBounds(&fBounds)) {
510 fBounds.setEmpty();
511 }
512 });
513 return fBounds;
514}
515
517 // we use a big size to ensure lots of significant bits from the scalercontext.
518 // then we scale back down to return our final answer (at 1-pt)
519 const SkScalar textSize = 2048;
520 const SkScalar invTextSize = 1 / textSize;
521
522 SkFont font;
523 font.setTypeface(sk_ref_sp(const_cast<SkTypeface*>(this)));
524 font.setSize(textSize);
525 font.setLinearMetrics(true);
526
529
531
533 SkScalerContextEffects noeffects;
535
536 std::unique_ptr<SkScalerContext> ctx = this->createScalerContext(noeffects, ad.getDesc());
537
538 SkFontMetrics fm;
539 ctx->getFontMetrics(&fm);
540 if (!fm.hasBounds()) {
541 return false;
542 }
543 bounds->setLTRB(fm.fXMin * invTextSize, fm.fTop * invTextSize,
544 fm.fXMax * invTextSize, fm.fBottom * invTextSize);
545 return true;
546}
SkStrokeRec::Style fStyle
sk_bzero(glyphs, sizeof(glyphs))
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
int count
Definition: FontMgrTest.cpp:50
static float next(float f)
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SkDEBUGF(...)
Definition: SkDebug.h:24
#define SkTEndian_SwapBE32(n)
Definition: SkEndian.h:143
SkTextEncoding
Definition: SkFontTypes.h:11
@ kUTF8
uses bytes to represent UTF-8 or ASCII
@ kUTF16
uses two byte words to represent most of Unicode
@ kUTF32
uses four byte words to represent all of Unicode
@ kGlyphID
uses two byte words to represent glyph indices
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
uint32_t SkFontTableTag
Definition: SkTypeface.h:41
int32_t SkUnichar
Definition: SkTypes.h:175
uint16_t SkGlyphID
Definition: SkTypes.h:179
uint32_t SkFourByteTag
Definition: SkTypes.h:166
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition: SkTypes.h:167
static sk_sp< SkTypeface > SK_SPI MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
static constexpr SkTypeface::FactoryId FactoryId
SkDescriptor * getDesc() const
Definition: SkDescriptor.h:103
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
static constexpr SkTypeface::FactoryId FactoryId
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
SkFontArguments::VariationPosition::Coordinate * setVariationCoordinates(int coordinateCount)
static bool Deserialize(SkStream *, SkFontDescriptor *result)
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:127
sk_sp< SkTypeface > legacyMakeTypeface(const char familyName[], SkFontStyle style) const
Definition: SkFontMgr.cpp:150
static int CountTextElements(const void *text, size_t byteLength, SkTextEncoding)
Definition: SkFont.cpp:381
Definition: SkFont.h:35
static SkDescriptor * AutoDescriptorGivenRecAndEffects(const SkScalerContextRec &rec, const SkScalerContextEffects &effects, SkAutoDescriptor *ad)
static void MakeRecAndEffectsFromFont(const SkFont &font, SkScalerContextRec *rec, SkScalerContextEffects *effects)
static std::unique_ptr< SkScalerContext > MakeEmpty(sk_sp< SkTypeface > typeface, const SkScalerContextEffects &effects, const SkDescriptor *desc)
void reset()
Definition: SkString.cpp:358
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
static constexpr SkTypeface::FactoryId FactoryId
static constexpr SkTypeface::FactoryId FactoryId
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
int countGlyphs() const
Definition: SkTypeface.cpp:432
virtual std::unique_ptr< SkStreamAsset > onOpenExistingStream(int *ttcIndex) const
Definition: SkTypeface.cpp:501
LocalizedStrings * createFamilyNameIterator() const
Definition: SkTypeface.cpp:455
std::unique_ptr< SkStreamAsset > openExistingStream(int *ttcIndex) const
Definition: SkTypeface.cpp:341
sk_sp< SkData > copyTableData(SkFontTableTag tag) const
Definition: SkTypeface.cpp:318
SkRect getBounds() const
Definition: SkTypeface.cpp:507
virtual sk_sp< SkData > onCopyTableData(SkFontTableTag) const
Definition: SkTypeface.cpp:322
virtual void getPostScriptGlyphNames(SkString *) const =0
~SkTypeface() override
Definition: SkTypeface.cpp:59
SkTypefaceID uniqueID() const
Definition: SkTypeface.h:101
virtual std::unique_ptr< SkAdvancedTypefaceMetrics > onGetAdvancedMetrics() const =0
int getUnitsPerEm() const
Definition: SkTypeface.cpp:436
virtual bool onGetKerningPairAdjustments(const SkGlyphID glyphs[], int count, int32_t adjustments[]) const
Definition: SkTypeface.cpp:496
virtual void getGlyphToUnicodeMap(SkUnichar *dstArray) const =0
Definition: SkTypeface.cpp:468
void getFamilyName(SkString *name) const
Definition: SkTypeface.cpp:459
virtual std::unique_ptr< SkScalerContext > onCreateScalerContext(const SkScalerContextEffects &, const SkDescriptor *) const =0
virtual int onCountGlyphs() const =0
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
Definition: SkTypeface.cpp:202
virtual int onGetTableTags(SkFontTableTag tags[]) const =0
static void Register(FactoryId id, sk_sp< SkTypeface >(*make)(std::unique_ptr< SkStreamAsset >, const SkFontArguments &))
Definition: SkTypeface.cpp:196
int getVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const
Definition: SkTypeface.cpp:295
int textToGlyphs(const void *text, size_t byteLength, SkTextEncoding encoding, SkGlyphID glyphs[], int maxGlyphCount) const
Definition: SkTypeface.cpp:407
bool getKerningPairAdjustments(const SkGlyphID glyphs[], int count, int32_t adjustments[]) const
Definition: SkTypeface.cpp:441
int getTableTags(SkFontTableTag tags[]) const
Definition: SkTypeface.cpp:305
virtual std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const =0
virtual void onGetFontDescriptor(SkFontDescriptor *, bool *isLocal) const =0
size_t getTableSize(SkFontTableTag) const
Definition: SkTypeface.cpp:309
int getVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
Definition: SkTypeface.cpp:289
virtual sk_sp< SkTypeface > onMakeClone(const SkFontArguments &) const =0
static bool Equal(const SkTypeface *facea, const SkTypeface *faceb)
Definition: SkTypeface.cpp:149
bool getPostScriptName(SkString *name) const
Definition: SkTypeface.cpp:464
static sk_sp< SkTypeface > MakeDeserialize(SkStream *, sk_sp< SkFontMgr > lastResortMgr)
Definition: SkTypeface.cpp:241
virtual size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void *data) const =0
virtual bool onGetPostScriptName(SkString *) const =0
virtual void onGetFamilyName(SkString *familyName) const =0
virtual void onFilterRec(SkScalerContextRec *) const =0
static sk_sp< SkTypeface > MakeEmpty()
Definition: SkTypeface.cpp:145
virtual bool onGlyphMaskNeedsCurrentColor() const =0
int countTables() const
Definition: SkTypeface.cpp:301
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
Definition: SkTypeface.cpp:332
virtual bool onComputeBounds(SkRect *) const
Definition: SkTypeface.cpp:516
virtual LocalizedStrings * onCreateFamilyNameIterator() const =0
virtual int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const =0
SkFourByteTag FactoryId
Definition: SkTypeface.h:335
std::unique_ptr< SkScalerContext > createScalerContext(const SkScalerContextEffects &, const SkDescriptor *) const
Definition: SkTypeface.cpp:350
size_t getTableData(SkFontTableTag tag, size_t offset, size_t length, void *data) const
Definition: SkTypeface.cpp:313
SkGlyphID unicharToGlyph(SkUnichar unichar) const
Definition: SkTypeface.cpp:363
virtual void onCharsToGlyphs(const SkUnichar *chars, int count, SkGlyphID glyphs[]) const =0
virtual int onGetUPEM() const =0
void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const
Definition: SkTypeface.cpp:357
SkTypeface(const SkFontStyle &style, bool isFixedPitch=false)
Definition: SkTypeface.cpp:56
virtual int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const =0
sk_sp< SkTypeface > makeClone(const SkFontArguments &) const
Definition: SkTypeface.cpp:190
T * get() const
Definition: SkRefCnt.h:303
static Editor::Movement convert(skui::Key key)
VkInstance instance
Definition: main.cc:48
float SkScalar
Definition: extension.cpp:12
glong glong end
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
size_t length
std::u16string text
std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream > stream, SkCodec::SelectionPolicy selectionPolicy, SkCodec::Result *result)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
Optional< SkRect > bounds
Definition: SkRecords.h:189
SK_SPI SkUnichar NextUTF16(const uint16_t **ptr, const uint16_t *end)
Definition: SkUTF.cpp:159
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
Definition: SkUTF.cpp:118
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
font
Font Metadata and Metrics.
dst
Definition: cp.py:12
static void make(SkBitmap *bitmap, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace)
Definition: encode_srgb.cpp:35
SeparatedVector2 offset
@ kNotEmbeddable_FontFlag
May not be embedded.
@ kNotSubsettable_FontFlag
May not be subset.
SkScalar fTop
greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable ...
Definition: SkFontMetrics.h:53
bool hasBounds() const
SkScalar fBottom
greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable ...
Definition: SkFontMetrics.h:56
SkScalar fXMin
greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with vari...
Definition: SkFontMetrics.h:60
SkScalar fXMax
greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with var...
Definition: SkFontMetrics.h:61
static constexpr SK_OT_ULONG TAG
void setEmpty()
Definition: SkRect.h:842
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
const uintptr_t id