1 /* 2 * Copyright 2013 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 "SkGScalerContext.h" 9 #include "SkGlyph.h" 10 #include "SkPath.h" 11 #include "SkCanvas.h" 12 13 class SkGScalerContext : public SkScalerContext { 14 public: 15 SkGScalerContext(SkGTypeface*, const SkDescriptor*); 16 virtual ~SkGScalerContext(); 17 18 protected: 19 virtual unsigned generateGlyphCount() SK_OVERRIDE; 20 virtual uint16_t generateCharToGlyph(SkUnichar) SK_OVERRIDE; 21 virtual void generateAdvance(SkGlyph*) SK_OVERRIDE; 22 virtual void generateMetrics(SkGlyph*) SK_OVERRIDE; 23 virtual void generateImage(const SkGlyph&) SK_OVERRIDE; 24 virtual void generatePath(const SkGlyph&, SkPath*) SK_OVERRIDE; 25 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, 26 SkPaint::FontMetrics* mY) SK_OVERRIDE; 27 28 private: 29 SkGTypeface* fFace; 30 SkScalerContext* fProxy; 31 SkMatrix fMatrix; 32 }; 33 34 #define STD_SIZE 1 35 36 #include "SkDescriptor.h" 37 38 SkGScalerContext::SkGScalerContext(SkGTypeface* face, const SkDescriptor* desc) 39 : SkScalerContext(face, desc) 40 , fFace(face) 41 { 42 43 size_t descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec); 44 SkAutoDescriptor ad(descSize); 45 SkDescriptor* newDesc = ad.getDesc(); 46 47 newDesc->init(); 48 void* entry = newDesc->addEntry(kRec_SkDescriptorTag, 49 sizeof(SkScalerContext::Rec), &fRec); 50 { 51 SkScalerContext::Rec* rec = (SkScalerContext::Rec*)entry; 52 rec->fTextSize = STD_SIZE; 53 rec->fPreScaleX = SK_Scalar1; 54 rec->fPreSkewX = 0; 55 rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 56 rec->fPost2x2[1][0] = rec->fPost2x2[0][1] = 0; 57 } 58 SkASSERT(descSize == newDesc->getLength()); 59 newDesc->computeChecksum(); 60 61 fProxy = face->proxy()->createScalerContext(newDesc); 62 63 fRec.getSingleMatrix(&fMatrix); 64 fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE); 65 } 66 67 SkGScalerContext::~SkGScalerContext() { 68 SkDELETE(fProxy); 69 } 70 71 unsigned SkGScalerContext::generateGlyphCount() { 72 return fProxy->getGlyphCount(); 73 } 74 75 uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) { 76 return fProxy->charToGlyphID(uni); 77 } 78 79 void SkGScalerContext::generateAdvance(SkGlyph* glyph) { 80 fProxy->getAdvance(glyph); 81 82 SkVector advance; 83 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), 84 SkFixedToScalar(glyph->fAdvanceY), &advance); 85 glyph->fAdvanceX = SkScalarToFixed(advance.fX); 86 glyph->fAdvanceY = SkScalarToFixed(advance.fY); 87 } 88 89 void SkGScalerContext::generateMetrics(SkGlyph* glyph) { 90 fProxy->getMetrics(glyph); 91 92 SkVector advance; 93 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), 94 SkFixedToScalar(glyph->fAdvanceY), &advance); 95 glyph->fAdvanceX = SkScalarToFixed(advance.fX); 96 glyph->fAdvanceY = SkScalarToFixed(advance.fY); 97 98 SkPath path; 99 fProxy->getPath(*glyph, &path); 100 path.transform(fMatrix); 101 102 SkRect storage; 103 const SkPaint& paint = fFace->paint(); 104 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), 105 &storage, 106 SkPaint::kFill_Style); 107 SkIRect ibounds; 108 newBounds.roundOut(&ibounds); 109 glyph->fLeft = ibounds.fLeft; 110 glyph->fTop = ibounds.fTop; 111 glyph->fWidth = ibounds.width(); 112 glyph->fHeight = ibounds.height(); 113 glyph->fMaskFormat = SkMask::kARGB32_Format; 114 } 115 116 void SkGScalerContext::generateImage(const SkGlyph& glyph) { 117 if (SkMask::kARGB32_Format == glyph.fMaskFormat) { 118 SkPath path; 119 fProxy->getPath(glyph, &path); 120 121 SkBitmap bm; 122 bm.setConfig(SkBitmap::kARGB_8888_Config, glyph.fWidth, glyph.fHeight, 123 glyph.rowBytes()); 124 bm.setPixels(glyph.fImage); 125 bm.eraseColor(0); 126 127 SkCanvas canvas(bm); 128 canvas.translate(-SkIntToScalar(glyph.fLeft), 129 -SkIntToScalar(glyph.fTop)); 130 canvas.concat(fMatrix); 131 canvas.drawPath(path, fFace->paint()); 132 } else { 133 fProxy->getImage(glyph); 134 } 135 } 136 137 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) { 138 fProxy->getPath(glyph, path); 139 path->transform(fMatrix); 140 } 141 142 void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics*, 143 SkPaint::FontMetrics* metrics) { 144 fProxy->getFontMetrics(metrics); 145 if (metrics) { 146 SkScalar scale = fMatrix.getScaleY(); 147 metrics->fTop = SkScalarMul(metrics->fTop, scale); 148 metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 149 metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 150 metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 151 metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 152 metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); 153 metrics->fXMin = SkScalarMul(metrics->fXMin, scale); 154 metrics->fXMax = SkScalarMul(metrics->fXMax, scale); 155 metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); 156 } 157 } 158 159 /////////////////////////////////////////////////////////////////////////////// 160 161 #include "SkTypefaceCache.h" 162 163 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint) 164 : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false) 165 , fProxy(SkRef(proxy)) 166 , fPaint(paint) {} 167 168 SkGTypeface::~SkGTypeface() { 169 fProxy->unref(); 170 } 171 172 SkScalerContext* SkGTypeface::onCreateScalerContext( 173 const SkDescriptor* desc) const { 174 return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc)); 175 } 176 177 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const { 178 fProxy->filterRec(rec); 179 rec->setHinting(SkPaint::kNo_Hinting); 180 rec->fMaskFormat = SkMask::kARGB32_Format; 181 } 182 183 SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics( 184 SkAdvancedTypefaceMetrics::PerGlyphInfo info, 185 const uint32_t* glyphIDs, 186 uint32_t glyphIDsCount) const { 187 return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 188 } 189 190 SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const { 191 return fProxy->openStream(ttcIndex); 192 } 193 194 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 195 bool* isLocal) const { 196 fProxy->getFontDescriptor(desc, isLocal); 197 } 198 199 int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 200 uint16_t glyphs[], int glyphCount) const { 201 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 202 } 203 204 int SkGTypeface::onCountGlyphs() const { 205 return fProxy->countGlyphs(); 206 } 207 208 int SkGTypeface::onGetUPEM() const { 209 return fProxy->getUnitsPerEm(); 210 } 211 212 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { 213 return fProxy->createFamilyNameIterator(); 214 } 215 216 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { 217 return fProxy->getTableTags(tags); 218 } 219 220 size_t SkGTypeface::onGetTableData(SkFontTableTag tag, size_t offset, 221 size_t length, void* data) const { 222 return fProxy->getTableData(tag, offset, length, data); 223 } 224 225 /////////////////////////////////////////////////////////////////////////////// 226 227 #if 0 228 // under construction -- defining a font purely in terms of skia primitives 229 // ala an SVG-font. 230 class SkGFont : public SkRefCnt { 231 public: 232 virtual ~SkGFont(); 233 234 int unicharToGlyph(SkUnichar) const; 235 236 int countGlyphs() const { return fCount; } 237 238 float getAdvance(int index) const { 239 SkASSERT((unsigned)index < (unsigned)fCount); 240 return fGlyphs[index].fAdvance; 241 } 242 243 const SkPath& getPath(int index) const { 244 SkASSERT((unsigned)index < (unsigned)fCount); 245 return fGlyphs[index].fPath; 246 } 247 248 private: 249 struct Glyph { 250 SkUnichar fUni; 251 float fAdvance; 252 SkPath fPath; 253 }; 254 int fCount; 255 Glyph* fGlyphs; 256 257 friend class SkGFontBuilder; 258 SkGFont(int count, Glyph* array); 259 }; 260 261 class SkGFontBuilder { 262 public: 263 264 }; 265 #endif 266