OLD | NEW |
(Empty) | |
| 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 "SkGlyph.h" |
| 12 #include "SkMask.h" |
| 13 // #include "SkOTUtils.h" |
| 14 #include "SkScalerContext.h" |
| 15 #include "SkTestScalerContext.h" |
| 16 #include "SkTypefaceCache.h" |
| 17 |
| 18 class SkTestTypeface : public SkTypeface { |
| 19 public: |
| 20 SkTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>& , SkTDArray
<SkFixed>& ), |
| 21 SkTypeface::Style style) |
| 22 : SkTypeface(style, SkTypefaceCache::NewFontID(), false) { |
| 23 fMetrics = (*funct)(fPaths, fWidths); |
| 24 } |
| 25 |
| 26 virtual ~SkTestTypeface() { |
| 27 fPaths.deleteAll(); |
| 28 } |
| 29 |
| 30 void getAdvance(SkGlyph* glyph) { |
| 31 glyph->fAdvanceX = fWidths[SkGlyph::ID2Code(glyph->fID)]; |
| 32 glyph->fAdvanceY = 0; |
| 33 } |
| 34 |
| 35 void getFontMetrics(SkPaint::FontMetrics* metrics) { |
| 36 *metrics = fMetrics; |
| 37 } |
| 38 |
| 39 void getMetrics(SkGlyph* glyph) { |
| 40 glyph->fAdvanceX = fWidths[SkGlyph::ID2Code(glyph->fID)]; |
| 41 glyph->fAdvanceY = 0; |
| 42 } |
| 43 |
| 44 void getPath(const SkGlyph& glyph, SkPath* path) { |
| 45 *path = *fPaths[SkGlyph::ID2Code(glyph.fID)]; |
| 46 } |
| 47 |
| 48 protected: |
| 49 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) con
st SK_OVERRIDE; |
| 50 |
| 51 virtual void onFilterRec(SkScalerContextRec* rec) const SK_OVERRIDE { |
| 52 rec->setHinting(SkPaint::kNo_Hinting); |
| 53 rec->fMaskFormat = SkMask::kA8_Format; |
| 54 } |
| 55 |
| 56 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( |
| 57 SkAdvancedTypefaceMetrics::PerGlyphInfo , |
| 58 const uint32_t* glyphIDs, |
| 59 uint32_t glyphIDsCount) const SK_OVERRIDE { |
| 60 // pdf only |
| 61 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; |
| 62 info->fEmSize = 0; |
| 63 info->fLastGlyphID = SkToU16(onCountGlyphs() - 1); |
| 64 info->fStyle = 0; |
| 65 info->fFontName.set("SkiaTest"); |
| 66 info->fType = SkAdvancedTypefaceMetrics::kOther_Font; |
| 67 info->fItalicAngle = 0; |
| 68 info->fAscent = 0; |
| 69 info->fDescent = 0; |
| 70 info->fStemV = 0; |
| 71 info->fCapHeight = 0; |
| 72 info->fBBox = SkIRect::MakeEmpty(); |
| 73 return info; |
| 74 } |
| 75 |
| 76 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { |
| 77 SkASSERT(0); // don't expect to get here |
| 78 return NULL; |
| 79 } |
| 80 |
| 81 virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) cons
t SK_OVERRIDE { |
| 82 SkASSERT(0); // don't expect to get here |
| 83 } |
| 84 |
| 85 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, |
| 86 uint16_t glyphs[], int glyphCount) const SK_OVER
RIDE { |
| 87 SkASSERT(encoding == kUTF8_Encoding); |
| 88 for (int index = 0; index < glyphCount; ++index) { |
| 89 int ch = ((unsigned char*) chars)[index]; |
| 90 SkASSERT(ch < 0x7F); |
| 91 if (ch < 0x20) { |
| 92 glyphs[index] = 0; |
| 93 } else { |
| 94 glyphs[index] = ch - 0x20; |
| 95 } |
| 96 } |
| 97 return glyphCount; |
| 98 } |
| 99 |
| 100 virtual int onCountGlyphs() const SK_OVERRIDE { |
| 101 return fPaths.count(); |
| 102 } |
| 103 |
| 104 virtual int onGetUPEM() const SK_OVERRIDE { |
| 105 SkASSERT(0); // don't expect to get here |
| 106 return 1; |
| 107 } |
| 108 |
| 109 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE { |
| 110 SkString familyName("SkiaTest"); |
| 111 SkString language("und"); //undetermined |
| 112 SkASSERT(0); // incomplete |
| 113 return NULL; |
| 114 // return new SkOTUtils::LocalizedStrings_SingleName(familyName, language
); |
| 115 } |
| 116 |
| 117 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE { |
| 118 return 0; |
| 119 } |
| 120 |
| 121 virtual size_t onGetTableData(SkFontTableTag tag, size_t offset, |
| 122 size_t length, void* data) const SK_OVERRIDE { |
| 123 return 0; |
| 124 } |
| 125 |
| 126 private: |
| 127 SkTDArray<SkPath* > fPaths; |
| 128 SkTDArray<SkFixed> fWidths; |
| 129 SkPaint::FontMetrics fMetrics; |
| 130 friend class SkTestScalerContext; |
| 131 }; |
| 132 |
| 133 SkTypeface* CreateTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>&
pathArray, |
| 134 SkTDArray<SkFixed>& widthArray), |
| 135 SkTypeface::Style style) { |
| 136 SkTypeface* test = SkNEW_ARGS(SkTestTypeface, (funct, style)); |
| 137 return test; |
| 138 } |
| 139 |
| 140 class SkTestScalerContext : public SkScalerContext { |
| 141 public: |
| 142 SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc) |
| 143 : SkScalerContext(face, desc) |
| 144 , fFace(face) |
| 145 { |
| 146 fRec.getSingleMatrix(&fMatrix); |
| 147 this->forceGenerateImageFromPath(); |
| 148 } |
| 149 |
| 150 virtual ~SkTestScalerContext() { |
| 151 } |
| 152 |
| 153 protected: |
| 154 virtual unsigned generateGlyphCount() SK_OVERRIDE { |
| 155 return fFace->onCountGlyphs(); |
| 156 } |
| 157 |
| 158 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE { |
| 159 uint8_t ch = (uint8_t) uni; |
| 160 SkASSERT(ch < 0x7f); |
| 161 uint16_t glyph; |
| 162 (void) fFace->onCharsToGlyphs((const void *) &ch, SkTypeface::kUTF8_Enco
ding, &glyph, 1); |
| 163 return glyph; |
| 164 } |
| 165 |
| 166 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE { |
| 167 fFace->getAdvance(glyph); |
| 168 |
| 169 SkVector advance; |
| 170 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), |
| 171 SkFixedToScalar(glyph->fAdvanceY), &advance); |
| 172 glyph->fAdvanceX = SkScalarToFixed(advance.fX); |
| 173 glyph->fAdvanceY = SkScalarToFixed(advance.fY); |
| 174 } |
| 175 |
| 176 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE { |
| 177 fFace->getMetrics(glyph); |
| 178 |
| 179 SkVector advance; |
| 180 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), |
| 181 SkFixedToScalar(glyph->fAdvanceY), &advance); |
| 182 glyph->fAdvanceX = SkScalarToFixed(advance.fX); |
| 183 glyph->fAdvanceY = SkScalarToFixed(advance.fY); |
| 184 |
| 185 SkPath path; |
| 186 fFace->getPath(*glyph, &path); |
| 187 path.transform(fMatrix); |
| 188 |
| 189 SkRect storage; |
| 190 const SkPaint paint; |
| 191 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), |
| 192 &storage, |
| 193 SkPaint::kFill_Style
); |
| 194 SkIRect ibounds; |
| 195 newBounds.roundOut(&ibounds); |
| 196 glyph->fLeft = ibounds.fLeft; |
| 197 glyph->fTop = ibounds.fTop; |
| 198 glyph->fWidth = ibounds.width(); |
| 199 glyph->fHeight = ibounds.height(); |
| 200 glyph->fMaskFormat = SkMask::kARGB32_Format; |
| 201 } |
| 202 |
| 203 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE { |
| 204 SkPath path; |
| 205 fFace->getPath(glyph, &path); |
| 206 |
| 207 SkBitmap bm; |
| 208 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight)
, |
| 209 glyph.fImage, glyph.rowBytes()); |
| 210 bm.eraseColor(0); |
| 211 |
| 212 SkCanvas canvas(bm); |
| 213 canvas.translate(-SkIntToScalar(glyph.fLeft), |
| 214 -SkIntToScalar(glyph.fTop)); |
| 215 canvas.concat(fMatrix); |
| 216 SkPaint paint; |
| 217 paint.setAntiAlias(true); |
| 218 canvas.drawPath(path, paint); |
| 219 } |
| 220 |
| 221 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE { |
| 222 fFace->getPath(glyph, path); |
| 223 path->transform(fMatrix); |
| 224 } |
| 225 |
| 226 virtual void generateFontMetrics(SkPaint::FontMetrics* , |
| 227 SkPaint::FontMetrics* metrics) SK_OVERRIDE
{ |
| 228 fFace->getFontMetrics(metrics); |
| 229 if (metrics) { |
| 230 SkScalar scale = fMatrix.getScaleY(); |
| 231 metrics->fTop = SkScalarMul(metrics->fTop, scale); |
| 232 metrics->fAscent = SkScalarMul(metrics->fAscent, scale); |
| 233 metrics->fDescent = SkScalarMul(metrics->fDescent, scale); |
| 234 metrics->fBottom = SkScalarMul(metrics->fBottom, scale); |
| 235 metrics->fLeading = SkScalarMul(metrics->fLeading, scale); |
| 236 metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); |
| 237 metrics->fXMin = SkScalarMul(metrics->fXMin, scale); |
| 238 metrics->fXMax = SkScalarMul(metrics->fXMax, scale); |
| 239 metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); |
| 240 } |
| 241 } |
| 242 |
| 243 private: |
| 244 SkTestTypeface* fFace; |
| 245 SkMatrix fMatrix; |
| 246 }; |
| 247 |
| 248 SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc)
const { |
| 249 return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), d
esc)); |
| 250 } |
OLD | NEW |