SkTestScalerContext.cpp revision a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7ee
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
19SkTestFont::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
35SkTestFont::~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"
45SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
46
47#endif
48
49int 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
79void 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
114SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
115    : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
116    , fTestFont(testFont) {
117}
118
119void SkTestTypeface::getAdvance(SkGlyph* glyph) {
120    glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
121    glyph->fAdvanceY = 0;
122}
123
124void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
125    *metrics = fTestFont->fMetrics;
126}
127
128void SkTestTypeface::getMetrics(SkGlyph* glyph) {
129    glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
130    glyph->fAdvanceY = 0;
131}
132
133void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
134    *path = *fTestFont->fPaths[SkGlyph::ID2Code(glyph.fID)];
135}
136
137void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
138    rec->setHinting(SkPaint::kNo_Hinting);
139    rec->fMaskFormat = SkMask::kA8_Format;
140}
141
142SkAdvancedTypefaceMetrics* 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
162void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
163    desc->setFamilyName(fTestFont->fName);
164    desc->setFontFileName(fTestFont->fName);
165    *isLocal = false;
166}
167
168int 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
178void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
179    *familyName = fTestFont->fName;
180}
181
182SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
183    SkString familyName(fTestFont->fName);
184    SkString language("und"); //undetermined
185SkASSERT(0);  // incomplete
186    return NULL;
187//     return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
188}
189
190class SkTestScalerContext : public SkScalerContext {
191public:
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
203protected:
204    virtual unsigned generateGlyphCount() SK_OVERRIDE {
205        return fFace->onCountGlyphs();
206    }
207
208    virtual 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    virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
215        fFace->getAdvance(glyph);
216
217        SkVector advance;
218        fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
219                      SkFixedToScalar(glyph->fAdvanceY), &advance);
220        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
221        glyph->fAdvanceY = SkScalarToFixed(advance.fY);
222    }
223
224    virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
225        fFace->getMetrics(glyph);
226
227        SkVector advance;
228        fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
229                      SkFixedToScalar(glyph->fAdvanceY), &advance);
230        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
231        glyph->fAdvanceY = SkScalarToFixed(advance.fY);
232
233        SkPath path;
234        fFace->getPath(*glyph, &path);
235        path.transform(fMatrix);
236
237        SkRect storage;
238        const SkPaint paint;
239        const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
240                                                            &storage,
241                                                            SkPaint::kFill_Style);
242        SkIRect ibounds;
243        newBounds.roundOut(&ibounds);
244        glyph->fLeft = ibounds.fLeft;
245        glyph->fTop = ibounds.fTop;
246        glyph->fWidth = ibounds.width();
247        glyph->fHeight = ibounds.height();
248        glyph->fMaskFormat = SkMask::kARGB32_Format;
249    }
250
251    virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {
252        SkPath path;
253        fFace->getPath(glyph, &path);
254
255        SkBitmap bm;
256        bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
257                            glyph.fImage, glyph.rowBytes());
258        bm.eraseColor(0);
259
260        SkCanvas canvas(bm);
261        canvas.translate(-SkIntToScalar(glyph.fLeft),
262                            -SkIntToScalar(glyph.fTop));
263        canvas.concat(fMatrix);
264        SkPaint paint;
265        paint.setAntiAlias(true);
266        canvas.drawPath(path, paint);
267    }
268
269    virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {
270        fFace->getPath(glyph, path);
271        path->transform(fMatrix);
272    }
273
274    virtual void generateFontMetrics(SkPaint::FontMetrics* metrics) SK_OVERRIDE {
275        fFace->getFontMetrics(metrics);
276        if (metrics) {
277            SkScalar scale = fMatrix.getScaleY();
278            metrics->fTop = SkScalarMul(metrics->fTop, scale);
279            metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
280            metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
281            metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
282            metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
283            metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
284            metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
285            metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
286            metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
287        }
288    }
289
290private:
291    SkTestTypeface*  fFace;
292    SkMatrix         fMatrix;
293};
294
295SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
296    return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));
297}
298