2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
10 #include "SkDescriptor.h"
11 #include "SkFontDescriptor.h"
14 // #include "SkOTUtils.h"
15 #include "SkScalerContext.h"
16 #include "SkTestScalerContext.h"
17 #include "SkTypefaceCache.h"
19 SkTestFont::SkTestFont(const SkTestFontData& fontData)
21 , fCharCodes(fontData.fCharCodes)
22 , fCharCodesCount(fontData.fCharCodesCount)
23 , fWidths(fontData.fWidths)
24 , fMetrics(fontData.fMetrics)
25 , fName(fontData.fName)
28 init(fontData.fPoints, fontData.fVerbs);
30 sk_bzero(fDebugBits, sizeof(fDebugBits));
31 sk_bzero(fDebugOverage, sizeof(fDebugOverage));
35 SkTestFont::~SkTestFont() {
36 for (unsigned index = 0; index < fCharCodesCount; ++index) {
37 SkDELETE(fPaths[index]);
39 SkDELETE_ARRAY(fPaths);
45 SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
49 int SkTestFont::codeToIndex(SkUnichar charCode) const {
50 #ifdef SK_DEBUG // detect missing test font data
52 SkAutoMutexAcquire ac(gUsedCharsMutex);
53 if (charCode >= ' ' && charCode <= '~') {
54 int bitOffset = charCode - ' ';
55 fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
58 while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
59 && index < (int) sizeof(fDebugOverage)) {
62 SkASSERT(index < (int) sizeof(fDebugOverage));
63 if (fDebugOverage[index] == 0) {
64 fDebugOverage[index] = charCode;
69 for (unsigned index = 0; index < fCharCodesCount; ++index) {
70 if (fCharCodes[index] == (unsigned) charCode) {
74 SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
75 fDebugName, fDebugStyle));
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);
84 while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
86 case SkPath::kMove_Verb:
87 path->moveTo(pts[0], pts[1]);
90 case SkPath::kLine_Verb:
91 path->lineTo(pts[0], pts[1]);
94 case SkPath::kQuad_Verb:
95 path->quadTo(pts[0], pts[1], pts[2], pts[3]);
98 case SkPath::kCubic_Verb:
99 path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
102 case SkPath::kClose_Verb:
106 SkDEBUGFAIL("bad verb");
110 fPaths[index] = path;
114 SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
115 : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
116 , fTestFont(testFont) {
119 void SkTestTypeface::getAdvance(SkGlyph* glyph) {
120 glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
121 glyph->fAdvanceY = 0;
124 void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
125 *metrics = fTestFont->fMetrics;
128 void SkTestTypeface::getMetrics(SkGlyph* glyph) {
129 glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
130 glyph->fAdvanceY = 0;
133 void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
134 *path = *fTestFont->fPaths[SkGlyph::ID2Code(glyph.fID)];
137 void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
138 rec->setHinting(SkPaint::kNo_Hinting);
139 rec->fMaskFormat = SkMask::kA8_Format;
142 SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
143 SkAdvancedTypefaceMetrics::PerGlyphInfo ,
144 const uint32_t* glyphIDs,
145 uint32_t glyphIDsCount) const {
147 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
149 info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
151 info->fFontName.set(fTestFont->fName);
152 info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
153 info->fItalicAngle = 0;
157 info->fCapHeight = 0;
158 info->fBBox = SkIRect::MakeEmpty();
162 void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
163 desc->setFamilyName(fTestFont->fName);
164 desc->setFontFileName(fTestFont->fName);
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);
178 void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
179 *familyName = fTestFont->fName;
182 SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
183 SkString familyName(fTestFont->fName);
184 SkString language("und"); //undetermined
185 SkASSERT(0); // incomplete
187 // return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
190 class SkTestScalerContext : public SkScalerContext {
192 SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc)
193 : SkScalerContext(face, desc)
196 fRec.getSingleMatrix(&fMatrix);
197 this->forceGenerateImageFromPath();
200 virtual ~SkTestScalerContext() {
204 virtual unsigned generateGlyphCount() SK_OVERRIDE {
205 return fFace->onCountGlyphs();
208 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
210 (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
214 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
215 fFace->getAdvance(glyph);
218 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
219 SkFixedToScalar(glyph->fAdvanceY), &advance);
220 glyph->fAdvanceX = SkScalarToFixed(advance.fX);
221 glyph->fAdvanceY = SkScalarToFixed(advance.fY);
224 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
225 fFace->getMetrics(glyph);
228 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
229 SkFixedToScalar(glyph->fAdvanceY), &advance);
230 glyph->fAdvanceX = SkScalarToFixed(advance.fX);
231 glyph->fAdvanceY = SkScalarToFixed(advance.fY);
234 fFace->getPath(*glyph, &path);
235 path.transform(fMatrix);
239 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
241 SkPaint::kFill_Style);
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;
251 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {
253 fFace->getPath(glyph, &path);
256 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
257 glyph.fImage, glyph.rowBytes());
261 canvas.translate(-SkIntToScalar(glyph.fLeft),
262 -SkIntToScalar(glyph.fTop));
263 canvas.concat(fMatrix);
265 paint.setAntiAlias(true);
266 canvas.drawPath(path, paint);
269 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {
270 fFace->getPath(glyph, path);
271 path->transform(fMatrix);
274 virtual void generateFontMetrics(SkPaint::FontMetrics* metrics) SK_OVERRIDE {
275 fFace->getFontMetrics(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);
291 SkTestTypeface* fFace;
295 SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
296 return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));