769f4ea66f6c184e3a37f2a5ec33d9fee024cd42
[platform/upstream/libSkiaSharp.git] / src / fonts / SkTestScalerContext.cpp
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 "SkBitmap.h"
9 #include "SkCanvas.h"
10 #include "SkDescriptor.h"
11 #include "SkFontDescriptor.h"
12 #include "SkGlyph.h"
13 #include "SkMask.h"
14 // #include "SkOTUtils.h"
15 #include "SkScalerContext.h"
16 #include "SkTestScalerContext.h"
17 #include "SkTypefaceCache.h"
18
19 SkTestFont::SkTestFont(const SkTestFontData& fontData)
20     : INHERITED()
21     , fCharCodes(fontData.fCharCodes)
22     , fCharCodesCount(fontData.fCharCodesCount)
23     , fWidths(fontData.fWidths)
24     , fMetrics(fontData.fMetrics)
25     , fName(fontData.fName)
26     , fPaths(NULL)
27 {
28     init(fontData.fPoints, fontData.fVerbs);
29 #ifdef SK_DEBUG
30     sk_bzero(fDebugBits, sizeof(fDebugBits));
31     sk_bzero(fDebugOverage, sizeof(fDebugOverage));
32 #endif
33 }
34
35 SkTestFont::~SkTestFont() {
36     for (unsigned index = 0; index < fCharCodesCount; ++index) {
37         SkDELETE(fPaths[index]);
38     }
39     SkDELETE_ARRAY(fPaths);
40 }
41
42 #ifdef SK_DEBUG
43
44 #include "SkThread.h"
45 SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
46
47 #endif
48
49 int SkTestFont::codeToIndex(SkUnichar charCode) const {
50 #ifdef SK_DEBUG  // detect missing test font data
51     {
52         SkAutoMutexAcquire ac(gUsedCharsMutex);
53         if (charCode >= ' ' && charCode <= '~') {
54             int bitOffset = charCode - ' ';
55             fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
56         } else {
57             int index = 0;
58             while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
59                     && index < (int) sizeof(fDebugOverage)) {
60                 ++index;
61             }
62             SkASSERT(index < (int) sizeof(fDebugOverage));
63             if (fDebugOverage[index] == 0) {
64                 fDebugOverage[index] = charCode;
65             }
66         }
67     }
68 #endif
69     for (unsigned index = 0; index < fCharCodesCount; ++index) {
70         if (fCharCodes[index] == (unsigned) charCode) {
71             return (int) index;
72         }
73     }
74     SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
75             fDebugName, fDebugStyle));
76     return 0;
77 }
78
79 void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
80     fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
81     for (unsigned index = 0; index < fCharCodesCount; ++index) {
82         SkPath* path = SkNEW(SkPath);
83         SkPath::Verb verb;
84         while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
85             switch (verb) {
86                 case SkPath::kMove_Verb:
87                     path->moveTo(pts[0], pts[1]);
88                     pts += 2;
89                     break;
90                 case SkPath::kLine_Verb:
91                     path->lineTo(pts[0], pts[1]);
92                     pts += 2;
93                     break;
94                 case SkPath::kQuad_Verb:
95                     path->quadTo(pts[0], pts[1], pts[2], pts[3]);
96                     pts += 4;
97                     break;
98                 case SkPath::kCubic_Verb:
99                     path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
100                     pts += 6;
101                     break;
102                 case SkPath::kClose_Verb:
103                     path->close();
104                     break;
105                 default:
106                     SkDEBUGFAIL("bad verb");
107                     return;
108             }
109         }
110         fPaths[index] = path;
111     }
112 }
113
114 SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
115     : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
116     , fTestFont(testFont) {
117 }
118
119 void SkTestTypeface::getAdvance(SkGlyph* glyph) {
120     glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
121     glyph->fAdvanceY = 0;
122 }
123
124 void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
125     *metrics = fTestFont->fMetrics;
126 }
127
128 void SkTestTypeface::getMetrics(SkGlyph* glyph) {
129     glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
130     glyph->fAdvanceY = 0;
131 }
132
133 void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
134     *path = *fTestFont->fPaths[glyph.getGlyphID()];
135 }
136
137 void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
138     rec->setHinting(SkPaint::kNo_Hinting);
139     rec->fMaskFormat = SkMask::kA8_Format;
140 }
141
142 SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
143                                 SkAdvancedTypefaceMetrics::PerGlyphInfo ,
144                                 const uint32_t* glyphIDs,
145                                 uint32_t glyphIDsCount) const {
146 // pdf only
147     SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
148     info->fEmSize = 0;
149     info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
150     info->fStyle = 0;
151     info->fFontName.set(fTestFont->fName);
152     info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
153     info->fItalicAngle = 0;
154     info->fAscent = 0;
155     info->fDescent = 0;
156     info->fStemV = 0;
157     info->fCapHeight = 0;
158     info->fBBox = SkIRect::MakeEmpty();
159     return info;
160 }
161
162 void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
163     desc->setFamilyName(fTestFont->fName);
164     desc->setFontFileName(fTestFont->fName);
165     *isLocal = false;
166 }
167
168 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
178 void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
179     *familyName = fTestFont->fName;
180 }
181
182 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:
192     SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc)
193         : SkScalerContext(face, desc)
194         , fFace(face)
195     {
196         fRec.getSingleMatrix(&fMatrix);
197         this->forceGenerateImageFromPath();
198     }
199
200     virtual ~SkTestScalerContext() {
201     }
202
203 protected:
204     unsigned generateGlyphCount() SK_OVERRIDE {
205         return fFace->onCountGlyphs();
206     }
207
208     uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
209         uint16_t glyph;
210         (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
211         return glyph;
212     }
213
214     void generateAdvance(SkGlyph* glyph) SK_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
223     void generateMetrics(SkGlyph* glyph) SK_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
249     void generateImage(const SkGlyph& glyph) SK_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
267     void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {
268         fFace->getPath(glyph, path);
269         path->transform(fMatrix);
270     }
271
272     void generateFontMetrics(SkPaint::FontMetrics* metrics) SK_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
293 SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
294     return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));
295 }