Flutter Engine
The Flutter Engine
SkFontDescriptor.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 Google Inc.
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
9
10#include "include/core/SkData.h"
17
18#include <cstddef>
19#include <cstdint>
20enum {
21 kInvalid = 0x00,
22
23 // Related to a font request.
24 kFontFamilyName = 0x01, // int length, data[length]
25 kFullName = 0x04, // int length, data[length]
26 kPostscriptName = 0x06, // int length, data[length]
27 kWeight = 0x10, // scalar (1 - 1000)
28 kWidth = 0x11, // scalar (percentage, 100 is 'normal')
29 kSlant = 0x12, // scalar (cw angle, 14 is a normal right leaning oblique)
30 kItalic = 0x13, // scalar (0 is Roman, 1 is fully Italic)
31
32 // Related to font data. Can also be used with a requested font.
33 kPaletteIndex = 0xF8, // int
34 kPaletteEntryOverrides = 0xF9, // int count, (int, u32)[count]
35 kFontVariation = 0xFA, // int count, (u32, scalar)[count]
36
37 // Related to font data.
38 kFactoryId = 0xFC, // int
39 kFontIndex = 0xFD, // int
40 kSentinel = 0xFF, // no data
41};
42
44
45[[nodiscard]] static bool read_string(SkStream* stream, SkString* string) {
46 size_t length;
47 if (!stream->readPackedUInt(&length)) { return false; }
48 if (length > 0) {
50 return false;
51 }
52 string->resize(length);
53 if (stream->read(string->data(), length) != length) { return false; }
54 }
55 return true;
56}
57
58static bool write_string(SkWStream* stream, const SkString& string, uint32_t id) {
59 if (string.isEmpty()) { return true; }
60 return stream->writePackedUInt(id) &&
61 stream->writePackedUInt(string.size()) &&
62 stream->write(string.c_str(), string.size());
63}
64
65static bool write_uint(SkWStream* stream, size_t n, uint32_t id) {
66 return stream->writePackedUInt(id) &&
67 stream->writePackedUInt(n);
68}
69
70static bool write_scalar(SkWStream* stream, SkScalar n, uint32_t id) {
71 return stream->writePackedUInt(id) &&
72 stream->writeScalar(n);
73}
74
75[[nodiscard]] static size_t read_id(SkStream* stream) {
76 size_t i;
77 if (!stream->readPackedUInt(&i)) { return kInvalid; }
78 return i;
79}
80
81static constexpr SkScalar usWidths[9] {
82 1, 2, 3, 4, 5, 6, 7, 8, 9
83};
84static constexpr SkScalar width_for_usWidth[0x10] = {
85 50,
86 50, 62.5, 75, 87.5, 100, 112.5, 125, 150, 200,
87 200, 200, 200, 200, 200, 200
88};
89
91 size_t factoryId;
92 using FactoryIdType = decltype(result->fFactoryId);
93
94 size_t coordinateCount;
95 using CoordinateCountType = decltype(result->fCoordinateCount);
96
97 size_t index;
98 using CollectionIndexType = decltype(result->fCollectionIndex);
99
100 size_t paletteIndex;
101 using PaletteIndexType = decltype(result->fPaletteIndex);
102
103 size_t paletteEntryOverrideCount;
104 using PaletteEntryOverrideCountType = decltype(result->fPaletteEntryOverrideCount);
105
106 size_t paletteEntryOverrideIndex;
107 using PaletteEntryOverrideIndexType = decltype(result->fPaletteEntryOverrides[0].index);
108
111 SkScalar slant = 0;
112 SkScalar italic = 0;
113
114 size_t styleBits;
115 if (!stream->readPackedUInt(&styleBits)) { return false; }
116 weight = ((styleBits >> 16) & 0xFFFF);
117 width = ((styleBits >> 8) & 0x000F)[width_for_usWidth];
118 slant = ((styleBits >> 0) & 0x000F) != SkFontStyle::kUpright_Slant ? 14 : 0;
119 italic = ((styleBits >> 0) & 0x000F) == SkFontStyle::kItalic_Slant ? 1 : 0;
120
121 for (size_t id; (id = read_id(stream)) != kSentinel;) {
122 switch (id) {
123 case kFontFamilyName:
124 if (!read_string(stream, &result->fFamilyName)) { return false; }
125 break;
126 case kFullName:
127 if (!read_string(stream, &result->fFullName)) { return false; }
128 break;
129 case kPostscriptName:
130 if (!read_string(stream, &result->fPostscriptName)) { return false; }
131 break;
132 case kWeight:
133 if (!stream->readScalar(&weight)) { return false; }
134 break;
135 case kWidth:
136 if (!stream->readScalar(&width)) { return false; }
137 break;
138 case kSlant:
139 if (!stream->readScalar(&slant)) { return false; }
140 break;
141 case kItalic:
142 if (!stream->readScalar(&italic)) { return false; }
143 break;
144 case kFontVariation:
145 if (!stream->readPackedUInt(&coordinateCount)) { return false; }
146 if (!SkTFitsIn<CoordinateCountType>(coordinateCount)) { return false; }
147 if (StreamRemainingLengthIsBelow(stream, coordinateCount)) {
148 return false;
149 }
150 result->fCoordinateCount = SkTo<CoordinateCountType>(coordinateCount);
151
152 result->fVariation.reset(coordinateCount);
153 for (size_t i = 0; i < coordinateCount; ++i) {
154 if (!stream->readU32(&result->fVariation[i].axis)) { return false; }
155 if (!stream->readScalar(&result->fVariation[i].value)) { return false; }
156 }
157 break;
158 case kFontIndex:
159 if (!stream->readPackedUInt(&index)) { return false; }
160 if (!SkTFitsIn<CollectionIndexType>(index)) { return false; }
161 result->fCollectionIndex = SkTo<CollectionIndexType>(index);
162 break;
163 case kPaletteIndex:
164 if (!stream->readPackedUInt(&paletteIndex)) { return false; }
165 if (!SkTFitsIn<PaletteIndexType>(paletteIndex)) { return false; }
166 result->fPaletteIndex = SkTo<PaletteIndexType>(paletteIndex);
167 break;
169 if (!stream->readPackedUInt(&paletteEntryOverrideCount)) { return false; }
170 if (!SkTFitsIn<PaletteEntryOverrideCountType>(paletteEntryOverrideCount)) {
171 return false;
172 }
173 if (StreamRemainingLengthIsBelow(stream, paletteEntryOverrideCount)) {
174 return false;
175 }
176 result->fPaletteEntryOverrideCount =
177 SkTo<PaletteEntryOverrideCountType>(paletteEntryOverrideCount);
178
179 result->fPaletteEntryOverrides.reset(paletteEntryOverrideCount);
180 for (size_t i = 0; i < paletteEntryOverrideCount; ++i) {
181 if (!stream->readPackedUInt(&paletteEntryOverrideIndex)) { return false; }
182 if (!SkTFitsIn<PaletteEntryOverrideIndexType>(paletteEntryOverrideIndex)) {
183 return false;
184 }
185 result->fPaletteEntryOverrides[i].index =
186 SkTo<PaletteEntryOverrideIndexType>(paletteEntryOverrideIndex);
187 if (!stream->readU32(&result->fPaletteEntryOverrides[i].color)) {
188 return false;
189 }
190 }
191 break;
192 case kFactoryId:
193 if (!stream->readPackedUInt(&factoryId)) { return false; }
194 if (!SkTFitsIn<FactoryIdType>(factoryId)) { return false; }
195 result->fFactoryId = SkTo<FactoryIdType>(factoryId);
196 break;
197 default:
198 SkDEBUGFAIL("Unknown id used by a font descriptor");
199 return false;
200 }
201 }
202
204 if (slant != 0) { slantEnum = SkFontStyle::kOblique_Slant; }
205 if (0 < italic) { slantEnum = SkFontStyle::kItalic_Slant; }
207 result->fStyle = SkFontStyle(SkScalarRoundToInt(weight), widthEnum, slantEnum);
208
209 size_t length;
210 if (!stream->readPackedUInt(&length)) { return false; }
211 if (length > 0) {
213 return false;
214 }
216 if (stream->read(data->writable_data(), length) != length) {
217 SkDEBUGFAIL("Could not read font data");
218 return false;
219 }
220 result->fStream = SkMemoryStream::Make(std::move(data));
221 }
222 return true;
223}
224
226 uint32_t styleBits = (fStyle.weight() << 16) | (fStyle.width() << 8) | (fStyle.slant());
227 stream->writePackedUInt(styleBits);
228
229 write_string(stream, fFamilyName, kFontFamilyName);
230 write_string(stream, fFullName, kFullName);
231 write_string(stream, fPostscriptName, kPostscriptName);
232
233 write_scalar(stream, fStyle.weight(), kWeight);
237
238 if (fCollectionIndex > 0) {
239 write_uint(stream, fCollectionIndex, kFontIndex);
240 }
241 if (fPaletteIndex > 0) {
242 write_uint(stream, fPaletteIndex, kPaletteIndex);
243 }
244 if (fCoordinateCount > 0) {
245 write_uint(stream, fCoordinateCount, kFontVariation);
246 for (int i = 0; i < fCoordinateCount; ++i) {
247 stream->write32(fVariation[i].axis);
248 stream->writeScalar(fVariation[i].value);
249 }
250 }
251 if (fPaletteEntryOverrideCount > 0) {
252 write_uint(stream, fPaletteEntryOverrideCount, kPaletteEntryOverrides);
253 for (int i = 0; i < fPaletteEntryOverrideCount; ++i) {
254 stream->writePackedUInt(fPaletteEntryOverrides[i].index);
255 stream->write32(fPaletteEntryOverrides[i].color);
256 }
257 }
258
259 write_uint(stream, fFactoryId, kFactoryId);
260
261 stream->writePackedUInt(kSentinel);
262
263 if (fStream) {
264 std::unique_ptr<SkStreamAsset> fontStream = fStream->duplicate();
265 size_t length = fontStream->getLength();
266 stream->writePackedUInt(length);
267 stream->writeStream(fontStream.get(), length);
268 } else {
269 stream->writePackedUInt(0);
270 }
271}
272
275 return static_cast<SkFontStyle::Width>(usWidth);
276}
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
static size_t read_id(SkStream *stream)
static bool write_scalar(SkWStream *stream, SkScalar n, uint32_t id)
static constexpr SkScalar width_for_usWidth[0x10]
static bool read_string(SkStream *stream, SkString *string)
@ kPaletteEntryOverrides
@ kFullName
@ kSlant
@ kWeight
@ kItalic
@ kFontFamilyName
@ kPaletteIndex
@ kInvalid
@ kWidth
@ kFontVariation
@ kFontIndex
@ kPostscriptName
@ kFactoryId
@ kSentinel
static bool write_string(SkWStream *stream, const SkString &string, uint32_t id)
static bool write_uint(SkWStream *stream, size_t n, uint32_t id)
static constexpr SkScalar usWidths[9]
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[], const SkScalar values[], int length)
Definition: SkScalar.cpp:11
bool StreamRemainingLengthIsBelow(SkStream *stream, size_t len)
Definition: SkStream.cpp:976
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
static SkFontStyle::Width SkFontStyleWidthForWidthAxisValue(SkScalar width)
void serialize(SkWStream *) const
static bool Deserialize(SkStream *, SkFontDescriptor *result)
Slant slant() const
Definition: SkFontStyle.h:64
int width() const
Definition: SkFontStyle.h:63
int weight() const
Definition: SkFontStyle.h:62
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition: SkStream.cpp:314
const char * data() const
Definition: SkString.h:132
DlColor color
float SkScalar
Definition: extension.cpp:12
uint8_t value
GAsyncResult * result
size_t length
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
int32_t width
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63