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