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