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.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 136void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) { 137 fProxy->getPath(glyph, path); 138 path->transform(fMatrix); 139} 140 141void 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 162SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint) 163 : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false) 164 , fProxy(SkRef(proxy)) 165 , fPaint(paint) {} 166 167SkGTypeface::~SkGTypeface() { 168 fProxy->unref(); 169} 170 171SkScalerContext* SkGTypeface::onCreateScalerContext( 172 const SkDescriptor* desc) const { 173 return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc)); 174} 175 176void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const { 177 fProxy->filterRec(rec); 178 rec->setHinting(SkPaint::kNo_Hinting); 179 rec->fMaskFormat = SkMask::kARGB32_Format; 180} 181 182SkAdvancedTypefaceMetrics* 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 189SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const { 190 return fProxy->openStream(ttcIndex); 191} 192 193void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 194 bool* isLocal) const { 195 fProxy->getFontDescriptor(desc, isLocal); 196} 197 198int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 199 uint16_t glyphs[], int glyphCount) const { 200 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 201} 202 203int SkGTypeface::onCountGlyphs() const { 204 return fProxy->countGlyphs(); 205} 206 207int SkGTypeface::onGetUPEM() const { 208 return fProxy->getUnitsPerEm(); 209} 210 211SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { 212 return fProxy->createFamilyNameIterator(); 213} 214 215int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { 216 return fProxy->getTableTags(tags); 217} 218 219size_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. 229class SkGFont : public SkRefCnt { 230public: 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 247private: 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 260class SkGFontBuilder { 261public: 262 263}; 264#endif 265