SkGScalerContext.cpp revision 7435f34b4720241f20d101879dffdcbf678a53a0
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 rec->setHinting(SkPaint::kNo_Hinting); 180 rec->fMaskFormat = SkMask::kARGB32_Format; 181} 182 183SkAdvancedTypefaceMetrics* 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 190SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const { 191 return fProxy->openStream(ttcIndex); 192} 193 194void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 195 bool* isLocal) const { 196 fProxy->getFontDescriptor(desc, isLocal); 197} 198 199int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 200 uint16_t glyphs[], int glyphCount) const { 201 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 202} 203 204int SkGTypeface::onCountGlyphs() const { 205 return fProxy->countGlyphs(); 206} 207 208int SkGTypeface::onGetUPEM() const { 209 return fProxy->getUnitsPerEm(); 210} 211 212SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { 213 return fProxy->createFamilyNameIterator(); 214} 215 216int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { 217 return fProxy->getTableTags(tags); 218} 219 220size_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. 230class SkGFont : public SkRefCnt { 231public: 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 248private: 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 261class SkGFontBuilder { 262public: 263 264}; 265#endif 266