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