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 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 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 50 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 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 115 SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style) 116 : SkTypeface(style, SkTypefaceCache::NewFontID(), false) 117 , fTestFont(testFont) { 118 } 119 120 void SkTestTypeface::getAdvance(SkGlyph* glyph) { 121 glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()]; 122 glyph->fAdvanceY = 0; 123 } 124 125 void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) { 126 *metrics = fTestFont->fMetrics; 127 } 128 129 void SkTestTypeface::getMetrics(SkGlyph* glyph) { 130 glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()]; 131 glyph->fAdvanceY = 0; 132 } 133 134 void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) { 135 *path = *fTestFont->fPaths[glyph.getGlyphID()]; 136 } 137 138 void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const { 139 rec->setHinting(SkPaint::kNo_Hinting); 140 rec->fMaskFormat = SkMask::kA8_Format; 141 } 142 143 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 163 void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const { 164 desc->setFamilyName(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() override { 205 return fFace->onCountGlyphs(); 206 } 207 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 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 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 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 267 void generatePath(const SkGlyph& glyph, SkPath* path) override { 268 fFace->getPath(glyph, path); 269 path->transform(fMatrix); 270 } 271 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 293 SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const { 294 return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc)); 295 } 296