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/SkTDArray.h"
18 #include "include/private/SkTo.h"
19 #include "src/core/SkAdvancedTypefaceMetrics.h"
20 #include "src/core/SkFontDescriptor.h"
21 #include "src/core/SkFontPriv.h"
22 #include "src/core/SkGlyph.h"
23 #include "src/core/SkPaintPriv.h"
24 #include "src/core/SkScalerContext.h"
25 #include "src/core/SkUtils.h"
26 #include "src/sfnt/SkOTUtils.h"
27 #include "tools/fonts/TestTypeface.h"
28
29 #include <utility>
30
31 class SkDescriptor;
32
SkTestFont(const SkTestFontData & fontData)33 SkTestFont::SkTestFont(const SkTestFontData& fontData)
34 : INHERITED()
35 , fCharCodes(fontData.fCharCodes)
36 , fCharCodesCount(fontData.fCharCodes ? fontData.fCharCodesCount : 0)
37 , fWidths(fontData.fWidths)
38 , fMetrics(fontData.fMetrics)
39 , fName(fontData.fName)
40 , fPaths(nullptr) {
41 init(fontData.fPoints, fontData.fVerbs);
42 }
43
~SkTestFont()44 SkTestFont::~SkTestFont() {
45 delete[] fPaths;
46 }
47
glyphForUnichar(SkUnichar charCode) const48 SkGlyphID SkTestFont::glyphForUnichar(SkUnichar charCode) const {
49 for (size_t index = 0; index < fCharCodesCount; ++index) {
50 if (fCharCodes[index] == charCode) {
51 return SkTo<SkGlyphID>(index);
52 }
53 }
54 return 0;
55 }
56
init(const SkScalar * pts,const unsigned char * verbs)57 void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
58 fPaths = new SkPath[fCharCodesCount];
59 for (unsigned index = 0; index < fCharCodesCount; ++index) {
60 SkPathBuilder b;
61 SkPath::Verb verb;
62 while ((verb = (SkPath::Verb)*verbs++) != SkPath::kDone_Verb) {
63 switch (verb) {
64 case SkPath::kMove_Verb:
65 b.moveTo(pts[0], pts[1]);
66 pts += 2;
67 break;
68 case SkPath::kLine_Verb:
69 b.lineTo(pts[0], pts[1]);
70 pts += 2;
71 break;
72 case SkPath::kQuad_Verb:
73 b.quadTo(pts[0], pts[1], pts[2], pts[3]);
74 pts += 4;
75 break;
76 case SkPath::kCubic_Verb:
77 b.cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
78 pts += 6;
79 break;
80 case SkPath::kClose_Verb:
81 b.close();
82 break;
83 default: SkDEBUGFAIL("bad verb"); return;
84 }
85 }
86 fPaths[index] = b.detach();
87 }
88 }
89
TestTypeface(sk_sp<SkTestFont> testFont,const SkFontStyle & style)90 TestTypeface::TestTypeface(sk_sp<SkTestFont> testFont, const SkFontStyle& style)
91 : SkTypeface(style, false), fTestFont(std::move(testFont)) {}
92
getAdvance(SkGlyph * glyph)93 void TestTypeface::getAdvance(SkGlyph* glyph) {
94 SkGlyphID glyphID = glyph->getGlyphID();
95 glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0;
96
97 // TODO(benjaminwagner): Update users to use floats.
98 glyph->fAdvanceX = SkFixedToFloat(fTestFont->fWidths[glyphID]);
99 glyph->fAdvanceY = 0;
100 }
101
getFontMetrics(SkFontMetrics * metrics)102 void TestTypeface::getFontMetrics(SkFontMetrics* metrics) { *metrics = fTestFont->fMetrics; }
103
getPath(SkGlyphID glyphID)104 SkPath TestTypeface::getPath(SkGlyphID glyphID) {
105 glyphID = glyphID < fTestFont->fCharCodesCount ? glyphID : 0;
106 return fTestFont->fPaths[glyphID];
107 }
108
onFilterRec(SkScalerContextRec * rec) const109 void TestTypeface::onFilterRec(SkScalerContextRec* rec) const {
110 rec->setHinting(SkFontHinting::kNone);
111 }
112
getGlyphToUnicodeMap(SkUnichar * glyphToUnicode) const113 void TestTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
114 unsigned glyphCount = fTestFont->fCharCodesCount;
115 for (unsigned gid = 0; gid < glyphCount; ++gid) {
116 glyphToUnicode[gid] = SkTo<SkUnichar>(fTestFont->fCharCodes[gid]);
117 }
118 }
119
onGetAdvancedMetrics() const120 std::unique_ptr<SkAdvancedTypefaceMetrics> TestTypeface::onGetAdvancedMetrics() const { // pdf only
121 std::unique_ptr<SkAdvancedTypefaceMetrics>info(new SkAdvancedTypefaceMetrics);
122 info->fFontName.set(fTestFont->fName);
123 return info;
124 }
125
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const126 void TestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
127 desc->setFamilyName(fTestFont->fName);
128 desc->setStyle(this->fontStyle());
129 *isLocal = false;
130 }
131
onCharsToGlyphs(const SkUnichar * uni,int count,SkGlyphID glyphs[]) const132 void TestTypeface::onCharsToGlyphs(const SkUnichar* uni, int count, SkGlyphID glyphs[]) const {
133 for (int i = 0; i < count; ++i) {
134 glyphs[i] = fTestFont->glyphForUnichar(uni[i]);
135 }
136 }
137
onGetFamilyName(SkString * familyName) const138 void TestTypeface::onGetFamilyName(SkString* familyName) const { *familyName = fTestFont->fName; }
139
onGetPostScriptName(SkString *) const140 bool TestTypeface::onGetPostScriptName(SkString*) const { return false; }
141
onCreateFamilyNameIterator() const142 SkTypeface::LocalizedStrings* TestTypeface::onCreateFamilyNameIterator() const {
143 SkString familyName(fTestFont->fName);
144 SkString language("und"); // undetermined
145 return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
146 }
147
148 class SkTestScalerContext : public SkScalerContext {
149 public:
SkTestScalerContext(sk_sp<TestTypeface> face,const SkScalerContextEffects & effects,const SkDescriptor * desc)150 SkTestScalerContext(sk_sp<TestTypeface> face,
151 const SkScalerContextEffects& effects,
152 const SkDescriptor* desc)
153 : SkScalerContext(std::move(face), effects, desc) {
154 fRec.getSingleMatrix(&fMatrix);
155 this->forceGenerateImageFromPath();
156 }
157
158 protected:
getTestTypeface() const159 TestTypeface* getTestTypeface() const {
160 return static_cast<TestTypeface*>(this->getTypeface());
161 }
162
generateAdvance(SkGlyph * glyph)163 bool generateAdvance(SkGlyph* glyph) override {
164 this->getTestTypeface()->getAdvance(glyph);
165
166 const SkVector advance =
167 fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX), SkFloatToScalar(glyph->fAdvanceY));
168 glyph->fAdvanceX = SkScalarToFloat(advance.fX);
169 glyph->fAdvanceY = SkScalarToFloat(advance.fY);
170 return true;
171 }
172
generateMetrics(SkGlyph * glyph)173 void generateMetrics(SkGlyph* glyph) override {
174 glyph->zeroMetrics();
175 this->generateAdvance(glyph);
176 // Always generates from paths, so SkScalerContext::makeGlyph will figure the bounds.
177 }
178
generateImage(const SkGlyph &)179 void generateImage(const SkGlyph&) override { SK_ABORT("Should have generated from path."); }
180
generatePath(SkGlyphID glyph,SkPath * path)181 bool generatePath(SkGlyphID glyph, SkPath* path) override {
182 *path = this->getTestTypeface()->getPath(glyph).makeTransform(fMatrix);
183 return true;
184 }
185
generateFontMetrics(SkFontMetrics * metrics)186 void generateFontMetrics(SkFontMetrics* metrics) override {
187 this->getTestTypeface()->getFontMetrics(metrics);
188 SkFontPriv::ScaleFontMetrics(metrics, fMatrix.getScaleY());
189 }
190
191 private:
192 SkMatrix fMatrix;
193 };
194
onCreateScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const195 std::unique_ptr<SkScalerContext> TestTypeface::onCreateScalerContext(
196 const SkScalerContextEffects& effects, const SkDescriptor* desc) const
197 {
198 return std::make_unique<SkTestScalerContext>(
199 sk_ref_sp(const_cast<TestTypeface*>(this)), effects, desc);
200 }
201