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.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), 123 glyph.fImage, glyph.rowBytes()); 124 bm.eraseColor(0); 125 126 SkCanvas canvas(bm); 127 canvas.translate(-SkIntToScalar(glyph.fLeft), 128 -SkIntToScalar(glyph.fTop)); 129 canvas.concat(fMatrix); 130 canvas.drawPath(path, fFace->paint()); 131 } else { 132 fProxy->getImage(glyph); 133 } 134 } 135 136 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) { 137 fProxy->getPath(glyph, path); 138 path->transform(fMatrix); 139 } 140 141 void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics*, 142 SkPaint::FontMetrics* metrics) { 143 fProxy->getFontMetrics(metrics); 144 if (metrics) { 145 SkScalar scale = fMatrix.getScaleY(); 146 metrics->fTop = SkScalarMul(metrics->fTop, scale); 147 metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 148 metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 149 metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 150 metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 151 metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); 152 metrics->fXMin = SkScalarMul(metrics->fXMin, scale); 153 metrics->fXMax = SkScalarMul(metrics->fXMax, scale); 154 metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); 155 } 156 } 157 158 /////////////////////////////////////////////////////////////////////////////// 159 160 #include "SkTypefaceCache.h" 161 162 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint) 163 : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false) 164 , fProxy(SkRef(proxy)) 165 , fPaint(paint) {} 166 167 SkGTypeface::~SkGTypeface() { 168 fProxy->unref(); 169 } 170 171 SkScalerContext* SkGTypeface::onCreateScalerContext( 172 const SkDescriptor* desc) const { 173 return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc)); 174 } 175 176 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const { 177 fProxy->filterRec(rec); 178 rec->setHinting(SkPaint::kNo_Hinting); 179 rec->fMaskFormat = SkMask::kARGB32_Format; 180 } 181 182 SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics( 183 SkAdvancedTypefaceMetrics::PerGlyphInfo info, 184 const uint32_t* glyphIDs, 185 uint32_t glyphIDsCount) const { 186 return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 187 } 188 189 SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const { 190 return fProxy->openStream(ttcIndex); 191 } 192 193 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 194 bool* isLocal) const { 195 fProxy->getFontDescriptor(desc, isLocal); 196 } 197 198 int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 199 uint16_t glyphs[], int glyphCount) const { 200 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 201 } 202 203 int SkGTypeface::onCountGlyphs() const { 204 return fProxy->countGlyphs(); 205 } 206 207 int SkGTypeface::onGetUPEM() const { 208 return fProxy->getUnitsPerEm(); 209 } 210 211 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { 212 return fProxy->createFamilyNameIterator(); 213 } 214 215 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { 216 return fProxy->getTableTags(tags); 217 } 218 219 size_t SkGTypeface::onGetTableData(SkFontTableTag tag, size_t offset, 220 size_t length, void* data) const { 221 return fProxy->getTableData(tag, offset, length, data); 222 } 223 224 /////////////////////////////////////////////////////////////////////////////// 225 226 #if 0 227 // under construction -- defining a font purely in terms of skia primitives 228 // ala an SVG-font. 229 class SkGFont : public SkRefCnt { 230 public: 231 virtual ~SkGFont(); 232 233 int unicharToGlyph(SkUnichar) const; 234 235 int countGlyphs() const { return fCount; } 236 237 float getAdvance(int index) const { 238 SkASSERT((unsigned)index < (unsigned)fCount); 239 return fGlyphs[index].fAdvance; 240 } 241 242 const SkPath& getPath(int index) const { 243 SkASSERT((unsigned)index < (unsigned)fCount); 244 return fGlyphs[index].fPath; 245 } 246 247 private: 248 struct Glyph { 249 SkUnichar fUni; 250 float fAdvance; 251 SkPath fPath; 252 }; 253 int fCount; 254 Glyph* fGlyphs; 255 256 friend class SkGFontBuilder; 257 SkGFont(int count, Glyph* array); 258 }; 259 260 class SkGFontBuilder { 261 public: 262 263 }; 264 #endif 265