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 unsigned generateGlyphCount() override; 20 uint16_t generateCharToGlyph(SkUnichar) override; 21 void generateAdvance(SkGlyph*) override; 22 void generateMetrics(SkGlyph*) override; 23 void generateImage(const SkGlyph&) override; 24 void generatePath(const SkGlyph&, SkPath*) override; 25 void generateFontMetrics(SkPaint::FontMetrics*) 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() { delete fProxy; } 67 68unsigned SkGScalerContext::generateGlyphCount() { 69 return fProxy->getGlyphCount(); 70} 71 72uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) { 73 return fProxy->charToGlyphID(uni); 74} 75 76void SkGScalerContext::generateAdvance(SkGlyph* glyph) { 77 fProxy->getAdvance(glyph); 78 79 SkVector advance; 80 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), 81 SkFixedToScalar(glyph->fAdvanceY), &advance); 82 glyph->fAdvanceX = SkScalarToFixed(advance.fX); 83 glyph->fAdvanceY = SkScalarToFixed(advance.fY); 84} 85 86void SkGScalerContext::generateMetrics(SkGlyph* glyph) { 87 fProxy->getMetrics(glyph); 88 89 SkVector advance; 90 fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), 91 SkFixedToScalar(glyph->fAdvanceY), &advance); 92 glyph->fAdvanceX = SkScalarToFixed(advance.fX); 93 glyph->fAdvanceY = SkScalarToFixed(advance.fY); 94 95 SkPath path; 96 fProxy->getPath(*glyph, &path); 97 path.transform(fMatrix); 98 99 SkRect storage; 100 const SkPaint& paint = fFace->paint(); 101 const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), 102 &storage, 103 SkPaint::kFill_Style); 104 SkIRect ibounds; 105 newBounds.roundOut(&ibounds); 106 glyph->fLeft = ibounds.fLeft; 107 glyph->fTop = ibounds.fTop; 108 glyph->fWidth = ibounds.width(); 109 glyph->fHeight = ibounds.height(); 110 glyph->fMaskFormat = SkMask::kARGB32_Format; 111} 112 113void SkGScalerContext::generateImage(const SkGlyph& glyph) { 114 if (SkMask::kARGB32_Format == glyph.fMaskFormat) { 115 SkPath path; 116 fProxy->getPath(glyph, &path); 117 118 SkBitmap bm; 119 bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), 120 glyph.fImage, glyph.rowBytes()); 121 bm.eraseColor(0); 122 123 SkCanvas canvas(bm); 124 canvas.translate(-SkIntToScalar(glyph.fLeft), 125 -SkIntToScalar(glyph.fTop)); 126 canvas.concat(fMatrix); 127 canvas.drawPath(path, fFace->paint()); 128 } else { 129 fProxy->getImage(glyph); 130 } 131} 132 133void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) { 134 fProxy->getPath(glyph, path); 135 path->transform(fMatrix); 136} 137 138void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) { 139 fProxy->getFontMetrics(metrics); 140 if (metrics) { 141 SkScalar scale = fMatrix.getScaleY(); 142 metrics->fTop = SkScalarMul(metrics->fTop, scale); 143 metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 144 metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 145 metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 146 metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 147 metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); 148 metrics->fXMin = SkScalarMul(metrics->fXMin, scale); 149 metrics->fXMax = SkScalarMul(metrics->fXMax, scale); 150 metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); 151 } 152} 153 154/////////////////////////////////////////////////////////////////////////////// 155 156#include "SkTypefaceCache.h" 157 158SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint) 159 : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false) 160 , fProxy(SkRef(proxy)) 161 , fPaint(paint) {} 162 163SkGTypeface::~SkGTypeface() { 164 fProxy->unref(); 165} 166 167SkScalerContext* SkGTypeface::onCreateScalerContext( 168 const SkDescriptor* desc) const { 169 return new SkGScalerContext(const_cast<SkGTypeface*>(this), desc); 170} 171 172void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const { 173 fProxy->filterRec(rec); 174 rec->setHinting(SkPaint::kNo_Hinting); 175 rec->fMaskFormat = SkMask::kARGB32_Format; 176} 177 178SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics( 179 PerGlyphInfo info, 180 const uint32_t* glyphIDs, 181 uint32_t glyphIDsCount) const { 182 return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 183} 184 185SkStreamAsset* SkGTypeface::onOpenStream(int* ttcIndex) const { 186 return fProxy->openStream(ttcIndex); 187} 188 189void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 190 bool* isLocal) const { 191 fProxy->getFontDescriptor(desc, isLocal); 192} 193 194int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 195 uint16_t glyphs[], int glyphCount) const { 196 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 197} 198 199int SkGTypeface::onCountGlyphs() const { 200 return fProxy->countGlyphs(); 201} 202 203int SkGTypeface::onGetUPEM() const { 204 return fProxy->getUnitsPerEm(); 205} 206 207void SkGTypeface::onGetFamilyName(SkString* familyName) const { 208 fProxy->getFamilyName(familyName); 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