Flutter Engine
The Flutter Engine
TestTypeface.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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
15#include "include/core/SkRect.h"
19#include "src/base/SkUtils.h"
22#include "src/core/SkFontPriv.h"
23#include "src/core/SkGlyph.h"
26#include "src/sfnt/SkOTUtils.h"
28
29#include <utility>
30
31namespace {
32
36
38
39} // namespace
40
41class SkDescriptor;
42
44 static List list = []() -> List {
46 for (const auto& sub : gSubFonts) {
47 List::Family* existingFamily = nullptr;
48 for (auto& family : list.families) {
49 if (strcmp(family.name, sub.fFamilyName) == 0) {
50 existingFamily = &family;
51 break;
52 }
53 }
54 if (!existingFamily) {
55 existingFamily = &list.families.emplace_back();
56 existingFamily->name = sub.fFamilyName;
57 }
58
59 auto font = sk_make_sp<SkTestFont>(sub.fFont);
60 sk_sp<SkTypeface> typeface(new TestTypeface(std::move(font), sub.fStyle));
61 bool isDefault = (&sub - gSubFonts == gDefaultFontIndex);
62 existingFamily->faces.emplace_back(
63 List::Family::Face{std::move(typeface), sub.fStyleName, isDefault});
64 }
65 return list;
66 }();
67 return list;
68}
69
71 : INHERITED()
72 , fCharCodes(fontData.fCharCodes)
73 , fCharCodesCount(fontData.fCharCodes ? fontData.fCharCodesCount : 0)
74 , fWidths(fontData.fWidths)
75 , fMetrics(fontData.fMetrics)
76 , fName(fontData.fName)
77 , fPaths(nullptr) {
78 init(fontData.fPoints, fontData.fVerbs);
79}
80
82 delete[] fPaths;
83}
84
86 for (size_t index = 0; index < fCharCodesCount; ++index) {
87 if (fCharCodes[index] == charCode) {
88 return SkTo<SkGlyphID>(index);
89 }
90 }
91 return 0;
92}
93
94void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
95 fPaths = new SkPath[fCharCodesCount];
96 for (unsigned index = 0; index < fCharCodesCount; ++index) {
98 SkPath::Verb verb;
99 while ((verb = (SkPath::Verb)*verbs++) != SkPath::kDone_Verb) {
100 switch (verb) {
102 b.moveTo(pts[0], pts[1]);
103 pts += 2;
104 break;
106 b.lineTo(pts[0], pts[1]);
107 pts += 2;
108 break;
110 b.quadTo(pts[0], pts[1], pts[2], pts[3]);
111 pts += 4;
112 break;
114 b.cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
115 pts += 6;
116 break;
118 b.close();
119 break;
120 default:
121 SK_ABORT("bad verb");
122 }
123 }
124 fPaths[index] = b.detach();
125 }
126}
127
128TestTypeface::TestTypeface(sk_sp<SkTestFont> testFont, const SkFontStyle& style)
129 : SkTypeface(style, false), fTestFont(std::move(testFont)) {}
130
132 glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0;
133
134 // TODO(benjaminwagner): Update users to use floats.
135 return {SkFixedToFloat(fTestFont->fWidths[glyphID]), 0};
136}
137
138void TestTypeface::getFontMetrics(SkFontMetrics* metrics) { *metrics = fTestFont->fMetrics; }
139
141 glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0;
142 return fTestFont->fPaths[glyphID];
143}
144
147}
148
150 unsigned glyphCount = fTestFont->fCharCodesCount;
151 for (unsigned gid = 0; gid < glyphCount; ++gid) {
152 glyphToUnicode[gid] = SkTo<SkUnichar>(fTestFont->fCharCodes[gid]);
153 }
154}
155
156std::unique_ptr<SkAdvancedTypefaceMetrics> TestTypeface::onGetAdvancedMetrics() const { // pdf only
157 std::unique_ptr<SkAdvancedTypefaceMetrics>info(new SkAdvancedTypefaceMetrics);
158 info->fPostScriptName.set(fTestFont->fName);
159 return info;
160}
161
162static constexpr const char gHeaderString[] = "SkTestTypeface01";
163static constexpr const size_t kHeaderSize = sizeof(gHeaderString);
164
165std::unique_ptr<SkStreamAsset> TestTypeface::onOpenStream(int* ttcIndex) const {
168
170 this->getFamilyName(&name);
171 SkFontStyle style = this->fontStyle();
172
173 wstream.writePackedUInt(name.size());
174 wstream.write(name.c_str(), name.size());
175 wstream.writeScalar(style.weight());
176 wstream.writeScalar(style.width());
177 wstream.writePackedUInt(style.slant());
178
179 *ttcIndex = 0;
180 return wstream.detachAsStream();
181}
182
183sk_sp<SkTypeface> TestTypeface::MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
184 const SkFontArguments&) {
185 char header[kHeaderSize];
186 if (stream->read(header, kHeaderSize) != kHeaderSize ||
187 0 != memcmp(header, gHeaderString, kHeaderSize))
188 {
189 return nullptr;
190 }
191
192 size_t familyNameSize;
193 SkString familyName;
194 if (!stream->readPackedUInt(&familyNameSize)) { return nullptr; }
195 familyName.resize(familyNameSize);
196 if (!stream->read(familyName.data(), familyNameSize)) { return nullptr; }
197
198 SkScalar weight;
200 size_t slant;
201 if (!stream->readScalar(&weight)) { return nullptr; }
202 if (!stream->readScalar(&width)) { return nullptr; }
203 if (!stream->readPackedUInt(&slant)) { return nullptr; }
204 SkFontStyle style(weight, width, (SkFontStyle::Slant)slant);
205
206 auto&& list = TestTypeface::Typefaces();
207 for (auto&& family : list.families) {
208 if (familyName.equals(family.name)) {
209 for (auto&& face : family.faces) {
210 if (face.typeface->fontStyle() == style) {
211 return face.typeface;
212 }
213 }
214 }
215 }
216 return nullptr;
217}
218
220 desc->setFamilyName(fTestFont->fName);
221 desc->setStyle(this->fontStyle());
222 desc->setFactoryId(FactoryId);
223 *serialize = true;
224}
225
227 SkTypeface::Register(TestTypeface::FactoryId, &TestTypeface::MakeFromStream);
228}
230
232 for (int i = 0; i < count; ++i) {
233 glyphs[i] = fTestFont->glyphForUnichar(uni[i]);
234 }
235}
236
237void TestTypeface::onGetFamilyName(SkString* familyName) const { *familyName = fTestFont->fName; }
238
239bool TestTypeface::onGetPostScriptName(SkString*) const { return false; }
240
242 SkString familyName(fTestFont->fName);
243 SkString language("und"); // undetermined
244 return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
245}
246
248public:
250 const SkScalerContextEffects& effects,
251 const SkDescriptor* desc)
252 : SkScalerContext(std::move(face), effects, desc) {
253 fRec.getSingleMatrix(&fMatrix);
254 this->forceGenerateImageFromPath();
255 }
256
257protected:
259 return static_cast<TestTypeface*>(this->getTypeface());
260 }
261
263 GlyphMetrics mx(glyph.maskFormat());
264
265 auto advance = this->getTestTypeface()->getAdvance(glyph.getGlyphID());
266
267 mx.advance = fMatrix.mapXY(advance.fX, advance.fY);
268 return mx;
269
270 // Always generates from paths, so SkScalerContext::makeGlyph will figure the bounds.
271 }
272
273 void generateImage(const SkGlyph&, void*) override {
274 SK_ABORT("Should have generated from path.");
275 }
276
277 bool generatePath(const SkGlyph& glyph, SkPath* path) override {
278 *path = this->getTestTypeface()->getPath(glyph.getGlyphID()).makeTransform(fMatrix);
279 return true;
280 }
281
282 void generateFontMetrics(SkFontMetrics* metrics) override {
283 this->getTestTypeface()->getFontMetrics(metrics);
285 }
286
287private:
289};
290
291std::unique_ptr<SkScalerContext> TestTypeface::onCreateScalerContext(
292 const SkScalerContextEffects& effects, const SkDescriptor* desc) const
293{
294 return std::make_unique<SkTestScalerContext>(
295 sk_ref_sp(const_cast<TestTypeface*>(this)), effects, desc);
296}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkMatrix fMatrix
Definition: FillRRectOp.cpp:74
const char * fName
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
int count
Definition: FontMgrTest.cpp:50
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkFixedToFloat(x)
Definition: SkFixed.h:41
@ kNone
glyph outlines unchanged
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
int32_t SkUnichar
Definition: SkTypes.h:175
uint16_t SkGlyphID
Definition: SkTypes.h:179
static TestTypeface::Register registerer
static constexpr const char gHeaderString[]
static constexpr const size_t kHeaderSize
std::unique_ptr< SkStreamAsset > detachAsStream()
Definition: SkStream.cpp:876
bool write(const void *buffer, size_t size) override
Definition: SkStream.cpp:535
void setFactoryId(SkTypeface::FactoryId factoryId)
static void ScaleFontMetrics(SkFontMetrics *, SkScalar)
Definition: SkFont.cpp:336
Slant slant() const
Definition: SkFontStyle.h:64
int width() const
Definition: SkFontStyle.h:63
int weight() const
Definition: SkFontStyle.h:62
SkGlyphID getGlyphID() const
Definition: SkGlyph.h:429
SkMask::Format maskFormat() const
Definition: SkGlyph.h:500
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
Definition: SkMatrix.cpp:777
SkScalar getScaleY() const
Definition: SkMatrix.h:422
Definition: SkPath.h:59
@ kClose_Verb
Definition: SkPath.h:1471
@ kMove_Verb
Definition: SkPath.h:1466
@ kDone_Verb
Definition: SkPath.h:1472
@ kCubic_Verb
Definition: SkPath.h:1470
@ kQuad_Verb
Definition: SkPath.h:1468
@ kLine_Verb
Definition: SkPath.h:1467
const char * data() const
Definition: SkString.h:132
bool equals(const SkString &) const
Definition: SkString.cpp:324
void resize(size_t len)
Definition: SkString.cpp:374
~SkTestFont() override
void init(const SkScalar *pts, const unsigned char *verbs)
SkTestFont(const SkTestFontData &)
SkGlyphID glyphForUnichar(SkUnichar charCode) const
void generateImage(const SkGlyph &, void *) override
bool generatePath(const SkGlyph &glyph, SkPath *path) override
TestTypeface * getTestTypeface() const
SkTestScalerContext(sk_sp< TestTypeface > face, const SkScalerContextEffects &effects, const SkDescriptor *desc)
GlyphMetrics generateMetrics(const SkGlyph &glyph, SkArenaAlloc *) override
void generateFontMetrics(SkFontMetrics *metrics) override
void getFamilyName(SkString *name) const
Definition: SkTypeface.cpp:459
SkFontStyle fontStyle() const
Definition: SkTypeface.h:55
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
Definition: SkTypeface.cpp:202
static void Register(FactoryId id, sk_sp< SkTypeface >(*make)(std::unique_ptr< SkStreamAsset >, const SkFontArguments &))
Definition: SkTypeface.cpp:196
SkFourByteTag FactoryId
Definition: SkTypeface.h:335
bool writePackedUInt(size_t)
Definition: SkStream.cpp:122
bool writeScalar(SkScalar)
Definition: SkStream.cpp:109
void getGlyphToUnicodeMap(SkUnichar *glyphToUnicode) const override
SkVector getAdvance(SkGlyphID) const
void onCharsToGlyphs(const SkUnichar *chars, int count, SkGlyphID glyphs[]) const override
SkTypeface::LocalizedStrings * onCreateFamilyNameIterator() const override
bool onGetPostScriptName(SkString *) const override
std::unique_ptr< SkAdvancedTypefaceMetrics > onGetAdvancedMetrics() const override
void onGetFamilyName(SkString *familyName) const override
SkPath getPath(SkGlyphID glyph)
static const List & Typefaces()
std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const override
std::unique_ptr< SkScalerContext > onCreateScalerContext(const SkScalerContextEffects &, const SkDescriptor *desc) const override
void getFontMetrics(SkFontMetrics *metrics)
void onFilterRec(SkScalerContextRec *rec) const override
void onGetFontDescriptor(SkFontDescriptor *desc, bool *serialize) const override
float SkScalar
Definition: extension.cpp:12
static bool b
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
font
Font Metadata and Metrics.
Definition: ref_ptr.h:256
int32_t width
static const char header[]
Definition: skpbench.cpp:88
void setHinting(SkFontHinting)
const SkScalar * fPoints
Definition: TestTypeface.h:37
const unsigned char * fVerbs
Definition: TestTypeface.h:38
std::vector< Family > families
Definition: TestTypeface.h:77