Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
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
219void TestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const {
220 desc->setFamilyName(fTestFont->fName);
221 desc->setStyle(this->fontStyle());
222 desc->setFactoryId(FactoryId);
223 *serialize = true;
224}
225
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);
284 SkFontPriv::ScaleFontMetrics(metrics, fMatrix.getScaleY());
285 }
286
287private:
288 SkMatrix fMatrix;
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}
const Face faces[]
Definition 3DSlide.cpp:137
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
const char * fName
uint16_t glyphs[5]
int count
#define SK_ABORT(message,...)
Definition SkAssert.h:70
static const char gHeaderString[]
static constexpr size_t kHeaderSize
#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
SkPathBuilder & close()
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & cubicTo(SkPoint pt1, SkPoint pt2, SkPoint pt3)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & quadTo(SkPoint pt1, SkPoint pt2)
SkPath detach()
Definition SkPath.h:147
@ kClose_Verb
Definition SkPath.h:1463
@ kMove_Verb
Definition SkPath.h:1458
@ kDone_Verb
Definition SkPath.h:1464
@ kCubic_Verb
Definition SkPath.h:1462
@ kQuad_Verb
Definition SkPath.h:1460
@ kLine_Verb
Definition SkPath.h:1459
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
SkFontStyle fontStyle() const
Definition SkTypeface.h:55
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
static void Register(FactoryId id, sk_sp< SkTypeface >(*make)(std::unique_ptr< SkStreamAsset >, const SkFontArguments &))
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
const char * name
Definition fuchsia.cc:50
Definition ref_ptr.h:256
int32_t width
static const char header[]
Definition skpbench.cpp:88
void setHinting(SkFontHinting)
const SkScalar * fPoints
const unsigned char * fVerbs
std::vector< Family > families