SkGScalerContext.cpp revision b3d154de5e4c318f88e4c4ad15fe626054365997
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 13class SkGScalerContext : public SkScalerContext { 14public: 15 SkGScalerContext(SkGTypeface*, const SkDescriptor*); 16 virtual ~SkGScalerContext(); 17 18protected: 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 28private: 29 SkGTypeface* fFace; 30 SkScalerContext* fProxy; 31 SkMatrix fMatrix; 32}; 33 34#define STD_SIZE 1 35 36#include "SkDescriptor.h" 37 38SkGScalerContext::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 67SkGScalerContext::~SkGScalerContext() { 68 SkDELETE(fProxy); 69} 70 71unsigned SkGScalerContext::generateGlyphCount() { 72 return fProxy->getGlyphCount(); 73} 74 75uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) { 76 return fProxy->charToGlyphID(uni); 77} 78 79void 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 89void 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 116void 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 137void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) { 138 fProxy->getPath(glyph, path); 139 path->transform(fMatrix); 140} 141 142void 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 163SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint) 164 : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false) 165 , fProxy(SkRef(proxy)) 166 , fPaint(paint) {} 167 168SkGTypeface::~SkGTypeface() { 169 fProxy->unref(); 170} 171 172SkScalerContext* SkGTypeface::onCreateScalerContext( 173 const SkDescriptor* desc) const { 174 return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc)); 175} 176 177void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const { 178 fProxy->filterRec(rec); 179} 180 181SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics( 182 SkAdvancedTypefaceMetrics::PerGlyphInfo info, 183 const uint32_t* glyphIDs, 184 uint32_t glyphIDsCount) const { 185 return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 186} 187 188SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const { 189 return fProxy->openStream(ttcIndex); 190} 191 192void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 193 bool* isLocal) const { 194 fProxy->getFontDescriptor(desc, isLocal); 195} 196 197int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 198 uint16_t glyphs[], int glyphCount) const { 199 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 200} 201 202int SkGTypeface::onCountGlyphs() const { 203 return fProxy->countGlyphs(); 204} 205 206int SkGTypeface::onGetUPEM() const { 207 return fProxy->getUnitsPerEm(); 208} 209 210SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { 211 return fProxy->createFamilyNameIterator(); 212} 213 214int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { 215 return fProxy->getTableTags(tags); 216} 217 218size_t SkGTypeface::onGetTableData(SkFontTableTag tag, size_t offset, 219 size_t length, void* data) const { 220 return fProxy->getTableData(tag, offset, length, data); 221} 222 223/////////////////////////////////////////////////////////////////////////////// 224 225#if 0 226// under construction -- defining a font purely in terms of skia primitives 227// ala an SVG-font. 228class SkGFont : public SkRefCnt { 229public: 230 virtual ~SkGFont(); 231 232 int unicharToGlyph(SkUnichar) const; 233 234 int countGlyphs() const { return fCount; } 235 236 float getAdvance(int index) const { 237 SkASSERT((unsigned)index < (unsigned)fCount); 238 return fGlyphs[index].fAdvance; 239 } 240 241 const SkPath& getPath(int index) const { 242 SkASSERT((unsigned)index < (unsigned)fCount); 243 return fGlyphs[index].fPath; 244 } 245 246private: 247 struct Glyph { 248 SkUnichar fUni; 249 float fAdvance; 250 SkPath fPath; 251 }; 252 int fCount; 253 Glyph* fGlyphs; 254 255 friend class SkGFontBuilder; 256 SkGFont(int count, Glyph* array); 257}; 258 259class SkGFontBuilder { 260public: 261 262}; 263#endif 264