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 "SkAdvancedTypefaceMetrics.h"
9 #include "SkBitmap.h"
10 #include "SkCanvas.h"
11 #include "SkDescriptor.h"
12 #include "SkFontDescriptor.h"
13 #include "SkGlyph.h"
14 #include "SkMask.h"
15 // #include "SkOTUtils.h"
16 #include "SkScalerContext.h"
17 #include "SkTestScalerContext.h"
18 #include "SkTypefaceCache.h"
19
SkTestFont(const SkTestFontData & fontData)20 SkTestFont::SkTestFont(const SkTestFontData& fontData)
21 : INHERITED()
22 , fCharCodes(fontData.fCharCodes)
23 , fCharCodesCount(fontData.fCharCodesCount)
24 , fWidths(fontData.fWidths)
25 , fMetrics(fontData.fMetrics)
26 , fName(fontData.fName)
27 , fPaths(NULL)
28 {
29 init(fontData.fPoints, fontData.fVerbs);
30 #ifdef SK_DEBUG
31 sk_bzero(fDebugBits, sizeof(fDebugBits));
32 sk_bzero(fDebugOverage, sizeof(fDebugOverage));
33 #endif
34 }
35
~SkTestFont()36 SkTestFont::~SkTestFont() {
37 for (unsigned index = 0; index < fCharCodesCount; ++index) {
38 SkDELETE(fPaths[index]);
39 }
40 SkDELETE_ARRAY(fPaths);
41 }
42
43 #ifdef SK_DEBUG
44
45 #include "SkThread.h"
46 SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
47
48 #endif
49
codeToIndex(SkUnichar charCode) const50 int SkTestFont::codeToIndex(SkUnichar charCode) const {
51 #ifdef SK_DEBUG // detect missing test font data
52 {
53 SkAutoMutexAcquire ac(gUsedCharsMutex);
54 if (charCode >= ' ' && charCode <= '~') {
55 int bitOffset = charCode - ' ';
56 fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
57 } else {
58 int index = 0;
59 while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
60 && index < (int) sizeof(fDebugOverage)) {
61 ++index;
62 }
63 SkASSERT(index < (int) sizeof(fDebugOverage));
64 if (fDebugOverage[index] == 0) {
65 fDebugOverage[index] = charCode;
66 }
67 }
68 }
69 #endif
70 for (unsigned index = 0; index < fCharCodesCount; ++index) {
71 if (fCharCodes[index] == (unsigned) charCode) {
72 return (int) index;
73 }
74 }
75 SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
76 fDebugName, fDebugStyle));
77 return 0;
78 }
79
init(const SkScalar * pts,const unsigned char * verbs)80 void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
81 fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
82 for (unsigned index = 0; index < fCharCodesCount; ++index) {
83 SkPath* path = SkNEW(SkPath);
84 SkPath::Verb verb;
85 while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
86 switch (verb) {
87 case SkPath::kMove_Verb:
88 path->moveTo(pts[0], pts[1]);
89 pts += 2;
90 break;
91 case SkPath::kLine_Verb:
92 path->lineTo(pts[0], pts[1]);
93 pts += 2;
94 break;
95 case SkPath::kQuad_Verb:
96 path->quadTo(pts[0], pts[1], pts[2], pts[3]);
97 pts += 4;
98 break;
99 case SkPath::kCubic_Verb:
100 path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
101 pts += 6;
102 break;
103 case SkPath::kClose_Verb:
104 path->close();
105 break;
106 default:
107 SkDEBUGFAIL("bad verb");
108 return;
109 }
110 }
111 fPaths[index] = path;
112 }
113 }
114
SkTestTypeface(SkTestFont * testFont,const SkFontStyle & style)115 SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
116 : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
117 , fTestFont(testFont) {
118 }
119
getAdvance(SkGlyph * glyph)120 void SkTestTypeface::getAdvance(SkGlyph* glyph) {
121 glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
122 glyph->fAdvanceY = 0;
123 }
124
getFontMetrics(SkPaint::FontMetrics * metrics)125 void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
126 *metrics = fTestFont->fMetrics;
127 }
128
getMetrics(SkGlyph * glyph)129 void SkTestTypeface::getMetrics(SkGlyph* glyph) {
130 glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
131 glyph->fAdvanceY = 0;
132 }
133
getPath(const SkGlyph & glyph,SkPath * path)134 void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
135 *path = *fTestFont->fPaths[glyph.getGlyphID()];
136 }
137
onFilterRec(SkScalerContextRec * rec) const138 void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
139 rec->setHinting(SkPaint::kNo_Hinting);
140 rec->fMaskFormat = SkMask::kA8_Format;
141 }
142
onGetAdvancedTypefaceMetrics(PerGlyphInfo,const uint32_t * glyphIDs,uint32_t glyphIDsCount) const143 SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
144 PerGlyphInfo ,
145 const uint32_t* glyphIDs,
146 uint32_t glyphIDsCount) const {
147 // pdf only
148 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
149 info->fEmSize = 0;
150 info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
151 info->fStyle = 0;
152 info->fFontName.set(fTestFont->fName);
153 info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
154 info->fItalicAngle = 0;
155 info->fAscent = 0;
156 info->fDescent = 0;
157 info->fStemV = 0;
158 info->fCapHeight = 0;
159 info->fBBox = SkIRect::MakeEmpty();
160 return info;
161 }
162
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const163 void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
164 desc->setFamilyName(fTestFont->fName);
165 *isLocal = false;
166 }
167
onCharsToGlyphs(const void * chars,Encoding encoding,uint16_t glyphs[],int glyphCount) const168 int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
169 uint16_t glyphs[], int glyphCount) const {
170 SkASSERT(encoding == kUTF16_Encoding);
171 for (int index = 0; index < glyphCount; ++index) {
172 SkUnichar ch = ((SkUnichar*) chars)[index];
173 glyphs[index] = fTestFont->codeToIndex(ch);
174 }
175 return glyphCount;
176 }
177
onGetFamilyName(SkString * familyName) const178 void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
179 *familyName = fTestFont->fName;
180 }
181
onCreateFamilyNameIterator() const182 SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
183 SkString familyName(fTestFont->fName);
184 SkString language("und"); //undetermined
185 SkASSERT(0); // incomplete
186 return NULL;
187 // return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
188 }
189
190 class SkTestScalerContext : public SkScalerContext {
191 public:
SkTestScalerContext(SkTestTypeface * face,const SkDescriptor * desc)192 SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc)
193 : SkScalerContext(face, desc)
194 , fFace(face)
195 {
196 fRec.getSingleMatrix(&fMatrix);
197 this->forceGenerateImageFromPath();
198 }
199
~SkTestScalerContext()200 virtual ~SkTestScalerContext() {
201 }
202
203 protected:
generateGlyphCount()204 unsigned generateGlyphCount() override {
205 return fFace->onCountGlyphs();
206 }
207
generateCharToGlyph(SkUnichar uni)208 uint16_t generateCharToGlyph(SkUnichar uni) override {
209 uint16_t glyph;
210 (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
211 return glyph;
212 }
213
generateAdvance(SkGlyph * glyph)214 void generateAdvance(SkGlyph* glyph) override {
215 fFace->getAdvance(glyph);
216
217 const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
218 SkFixedToScalar(glyph->fAdvanceY));
219 glyph->fAdvanceX = SkScalarToFixed(advance.fX);
220 glyph->fAdvanceY = SkScalarToFixed(advance.fY);
221 }
222
generateMetrics(SkGlyph * glyph)223 void generateMetrics(SkGlyph* glyph) override {
224 fFace->getMetrics(glyph);
225
226 const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
227 SkFixedToScalar(glyph->fAdvanceY));
228 glyph->fAdvanceX = SkScalarToFixed(advance.fX);
229 glyph->fAdvanceY = SkScalarToFixed(advance.fY);
230
231 SkPath path;
232 fFace->getPath(*glyph, &path);
233 path.transform(fMatrix);
234
235 SkRect storage;
236 const SkPaint paint;
237 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
238 &storage,
239 SkPaint::kFill_Style);
240 SkIRect ibounds;
241 newBounds.roundOut(&ibounds);
242 glyph->fLeft = ibounds.fLeft;
243 glyph->fTop = ibounds.fTop;
244 glyph->fWidth = ibounds.width();
245 glyph->fHeight = ibounds.height();
246 glyph->fMaskFormat = SkMask::kARGB32_Format;
247 }
248
generateImage(const SkGlyph & glyph)249 void generateImage(const SkGlyph& glyph) override {
250 SkPath path;
251 fFace->getPath(glyph, &path);
252
253 SkBitmap bm;
254 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
255 glyph.fImage, glyph.rowBytes());
256 bm.eraseColor(0);
257
258 SkCanvas canvas(bm);
259 canvas.translate(-SkIntToScalar(glyph.fLeft),
260 -SkIntToScalar(glyph.fTop));
261 canvas.concat(fMatrix);
262 SkPaint paint;
263 paint.setAntiAlias(true);
264 canvas.drawPath(path, paint);
265 }
266
generatePath(const SkGlyph & glyph,SkPath * path)267 void generatePath(const SkGlyph& glyph, SkPath* path) override {
268 fFace->getPath(glyph, path);
269 path->transform(fMatrix);
270 }
271
generateFontMetrics(SkPaint::FontMetrics * metrics)272 void generateFontMetrics(SkPaint::FontMetrics* metrics) override {
273 fFace->getFontMetrics(metrics);
274 if (metrics) {
275 SkScalar scale = fMatrix.getScaleY();
276 metrics->fTop = SkScalarMul(metrics->fTop, scale);
277 metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
278 metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
279 metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
280 metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
281 metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
282 metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
283 metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
284 metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
285 }
286 }
287
288 private:
289 SkTestTypeface* fFace;
290 SkMatrix fMatrix;
291 };
292
onCreateScalerContext(const SkDescriptor * desc) const293 SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
294 return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));
295 }
296