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
8 #include "include/core/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkFontMetrics.h"
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkMatrix.h"
13 #include "include/core/SkPathBuilder.h"
14 #include "include/core/SkPoint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkString.h"
17 #include "include/private/base/SkTDArray.h"
18 #include "include/private/base/SkTo.h"
19 #include "src/base/SkUtils.h"
20 #include "src/core/SkAdvancedTypefaceMetrics.h"
21 #include "src/core/SkFontDescriptor.h"
22 #include "src/core/SkFontPriv.h"
23 #include "src/core/SkGlyph.h"
24 #include "src/core/SkPaintPriv.h"
25 #include "src/core/SkScalerContext.h"
26 #include "src/sfnt/SkOTUtils.h"
27 #include "tools/fonts/TestTypeface.h"
28
29 #include <utility>
30
31 namespace {
32
33 #include "tools/fonts/test_font_monospace.inc"
34 #include "tools/fonts/test_font_sans_serif.inc"
35 #include "tools/fonts/test_font_serif.inc"
36
37 #include "tools/fonts/test_font_index.inc"
38
39 } // namespace
40
41 class SkDescriptor;
42
Typefaces()43 const TestTypeface::List& TestTypeface::Typefaces() {
44 static List list = []() -> List {
45 TestTypeface::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
SkTestFont(const SkTestFontData & fontData)70 SkTestFont::SkTestFont(const SkTestFontData& fontData)
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
~SkTestFont()81 SkTestFont::~SkTestFont() {
82 delete[] fPaths;
83 }
84
glyphForUnichar(SkUnichar charCode) const85 SkGlyphID SkTestFont::glyphForUnichar(SkUnichar charCode) const {
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
init(const SkScalar * pts,const unsigned char * verbs)94 void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
95 fPaths = new SkPath[fCharCodesCount];
96 for (unsigned index = 0; index < fCharCodesCount; ++index) {
97 SkPathBuilder b;
98 SkPath::Verb verb;
99 while ((verb = (SkPath::Verb)*verbs++) != SkPath::kDone_Verb) {
100 switch (verb) {
101 case SkPath::kMove_Verb:
102 b.moveTo(pts[0], pts[1]);
103 pts += 2;
104 break;
105 case SkPath::kLine_Verb:
106 b.lineTo(pts[0], pts[1]);
107 pts += 2;
108 break;
109 case SkPath::kQuad_Verb:
110 b.quadTo(pts[0], pts[1], pts[2], pts[3]);
111 pts += 4;
112 break;
113 case SkPath::kCubic_Verb:
114 b.cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
115 pts += 6;
116 break;
117 case SkPath::kClose_Verb:
118 b.close();
119 break;
120 default: SkDEBUGFAIL("bad verb"); return;
121 }
122 }
123 fPaths[index] = b.detach();
124 }
125 }
126
TestTypeface(sk_sp<SkTestFont> testFont,const SkFontStyle & style)127 TestTypeface::TestTypeface(sk_sp<SkTestFont> testFont, const SkFontStyle& style)
128 : SkTypeface(style, false), fTestFont(std::move(testFont)) {}
129
getAdvance(SkGlyph * glyph)130 void TestTypeface::getAdvance(SkGlyph* glyph) {
131 SkGlyphID glyphID = glyph->getGlyphID();
132 glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0;
133
134 // TODO(benjaminwagner): Update users to use floats.
135 glyph->fAdvanceX = SkFixedToFloat(fTestFont->fWidths[glyphID]);
136 glyph->fAdvanceY = 0;
137 }
138
getFontMetrics(SkFontMetrics * metrics)139 void TestTypeface::getFontMetrics(SkFontMetrics* metrics) { *metrics = fTestFont->fMetrics; }
140
getPath(SkGlyphID glyphID)141 SkPath TestTypeface::getPath(SkGlyphID glyphID) {
142 glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0;
143 return fTestFont->fPaths[glyphID];
144 }
145
onFilterRec(SkScalerContextRec * rec) const146 void TestTypeface::onFilterRec(SkScalerContextRec* rec) const {
147 rec->setHinting(SkFontHinting::kNone);
148 }
149
getGlyphToUnicodeMap(SkUnichar * glyphToUnicode) const150 void TestTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
151 unsigned glyphCount = fTestFont->fCharCodesCount;
152 for (unsigned gid = 0; gid < glyphCount; ++gid) {
153 glyphToUnicode[gid] = SkTo<SkUnichar>(fTestFont->fCharCodes[gid]);
154 }
155 }
156
onGetAdvancedMetrics() const157 std::unique_ptr<SkAdvancedTypefaceMetrics> TestTypeface::onGetAdvancedMetrics() const { // pdf only
158 std::unique_ptr<SkAdvancedTypefaceMetrics>info(new SkAdvancedTypefaceMetrics);
159 info->fFontName.set(fTestFont->fName);
160 return info;
161 }
162
163 static constexpr const char gHeaderString[] = "SkTestTypeface01";
164 static constexpr const size_t kHeaderSize = sizeof(gHeaderString);
165
onOpenStream(int * ttcIndex) const166 std::unique_ptr<SkStreamAsset> TestTypeface::onOpenStream(int* ttcIndex) const {
167 SkDynamicMemoryWStream wstream;
168 wstream.write(gHeaderString, kHeaderSize);
169
170 SkString name;
171 this->getFamilyName(&name);
172 SkFontStyle style = this->fontStyle();
173
174 wstream.writePackedUInt(name.size());
175 wstream.write(name.c_str(), name.size());
176 wstream.writeScalar(style.weight());
177 wstream.writeScalar(style.width());
178 wstream.writePackedUInt(style.slant());
179
180 *ttcIndex = 0;
181 return wstream.detachAsStream();
182 }
183
MakeFromStream(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments &)184 sk_sp<SkTypeface> TestTypeface::MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
185 const SkFontArguments&) {
186 char header[kHeaderSize];
187 if (stream->read(header, kHeaderSize) != kHeaderSize ||
188 0 != memcmp(header, gHeaderString, kHeaderSize))
189 {
190 return nullptr;
191 }
192
193 size_t familyNameSize;
194 SkString familyName;
195 if (!stream->readPackedUInt(&familyNameSize)) { return nullptr; }
196 familyName.resize(familyNameSize);
197 if (!stream->read(familyName.data(), familyNameSize)) { return nullptr; }
198
199 SkScalar weight;
200 SkScalar width;
201 size_t slant;
202 if (!stream->readScalar(&weight)) { return nullptr; }
203 if (!stream->readScalar(&width)) { return nullptr; }
204 if (!stream->readPackedUInt(&slant)) { return nullptr; }
205 SkFontStyle style(weight, width, (SkFontStyle::Slant)slant);
206
207 auto&& list = TestTypeface::Typefaces();
208 for (auto&& family : list.families) {
209 if (familyName.equals(family.name)) {
210 for (auto&& face : family.faces) {
211 if (face.typeface->fontStyle() == style) {
212 return face.typeface;
213 }
214 }
215 }
216 }
217 return nullptr;
218 }
219
onGetFontDescriptor(SkFontDescriptor * desc,bool * serialize) const220 void TestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const {
221 desc->setFamilyName(fTestFont->fName);
222 desc->setStyle(this->fontStyle());
223 desc->setFactoryId(FactoryId);
224 *serialize = true;
225 }
226
Register()227 TestTypeface::Register::Register() {
228 SkTypeface::Register(TestTypeface::FactoryId, &TestTypeface::MakeFromStream);
229 }
230 static TestTypeface::Register registerer;
231
onCharsToGlyphs(const SkUnichar * uni,int count,SkGlyphID glyphs[]) const232 void TestTypeface::onCharsToGlyphs(const SkUnichar* uni, int count, SkGlyphID glyphs[]) const {
233 for (int i = 0; i < count; ++i) {
234 glyphs[i] = fTestFont->glyphForUnichar(uni[i]);
235 }
236 }
237
onGetFamilyName(SkString * familyName) const238 void TestTypeface::onGetFamilyName(SkString* familyName) const { *familyName = fTestFont->fName; }
239
onGetPostScriptName(SkString *) const240 bool TestTypeface::onGetPostScriptName(SkString*) const { return false; }
241
onCreateFamilyNameIterator() const242 SkTypeface::LocalizedStrings* TestTypeface::onCreateFamilyNameIterator() const {
243 SkString familyName(fTestFont->fName);
244 SkString language("und"); // undetermined
245 return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
246 }
247
248 class SkTestScalerContext : public SkScalerContext {
249 public:
SkTestScalerContext(sk_sp<TestTypeface> face,const SkScalerContextEffects & effects,const SkDescriptor * desc)250 SkTestScalerContext(sk_sp<TestTypeface> face,
251 const SkScalerContextEffects& effects,
252 const SkDescriptor* desc)
253 : SkScalerContext(std::move(face), effects, desc) {
254 fRec.getSingleMatrix(&fMatrix);
255 this->forceGenerateImageFromPath();
256 }
257
258 protected:
getTestTypeface() const259 TestTypeface* getTestTypeface() const {
260 return static_cast<TestTypeface*>(this->getTypeface());
261 }
262
generateAdvance(SkGlyph * glyph)263 bool generateAdvance(SkGlyph* glyph) override {
264 this->getTestTypeface()->getAdvance(glyph);
265
266 const SkVector advance =
267 fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX), SkFloatToScalar(glyph->fAdvanceY));
268 glyph->fAdvanceX = SkScalarToFloat(advance.fX);
269 glyph->fAdvanceY = SkScalarToFloat(advance.fY);
270 return true;
271 }
272
generateMetrics(SkGlyph * glyph,SkArenaAlloc *)273 void generateMetrics(SkGlyph* glyph, SkArenaAlloc*) override {
274 glyph->zeroMetrics();
275 this->generateAdvance(glyph);
276 // Always generates from paths, so SkScalerContext::makeGlyph will figure the bounds.
277 }
278
generateImage(const SkGlyph &)279 void generateImage(const SkGlyph&) override { SK_ABORT("Should have generated from path."); }
280
generatePath(const SkGlyph & glyph,SkPath * path)281 bool generatePath(const SkGlyph& glyph, SkPath* path) override {
282 *path = this->getTestTypeface()->getPath(glyph.getGlyphID()).makeTransform(fMatrix);
283 return true;
284 }
285
generateFontMetrics(SkFontMetrics * metrics)286 void generateFontMetrics(SkFontMetrics* metrics) override {
287 this->getTestTypeface()->getFontMetrics(metrics);
288 SkFontPriv::ScaleFontMetrics(metrics, fMatrix.getScaleY());
289 }
290
291 private:
292 SkMatrix fMatrix;
293 };
294
onCreateScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const295 std::unique_ptr<SkScalerContext> TestTypeface::onCreateScalerContext(
296 const SkScalerContextEffects& effects, const SkDescriptor* desc) const
297 {
298 return std::make_unique<SkTestScalerContext>(
299 sk_ref_sp(const_cast<TestTypeface*>(this)), effects, desc);
300 }
301