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 13 class SkGScalerContext : public SkScalerContext { 14 public: 15 SkGScalerContext(SkGTypeface*, const SkDescriptor*); 16 virtual ~SkGScalerContext(); 17 18 protected: 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 27 private: 28 SkGTypeface* fFace; 29 SkScalerContext* fProxy; 30 SkMatrix fMatrix; 31 }; 32 33 #define STD_SIZE 1 34 35 #include "SkDescriptor.h" 36 37 SkGScalerContext::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 66 SkGScalerContext::~SkGScalerContext() { 67 SkDELETE(fProxy); 68 } 69 70 unsigned SkGScalerContext::generateGlyphCount() { 71 return fProxy->getGlyphCount(); 72 } 73 74 uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) { 75 return fProxy->charToGlyphID(uni); 76 } 77 78 void 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 88 void 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 115 void 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 135 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) { 136 fProxy->getPath(glyph, path); 137 path->transform(fMatrix); 138 } 139 140 void 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 160 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint) 161 : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false) 162 , fProxy(SkRef(proxy)) 163 , fPaint(paint) {} 164 165 SkGTypeface::~SkGTypeface() { 166 fProxy->unref(); 167 } 168 169 SkScalerContext* SkGTypeface::onCreateScalerContext( 170 const SkDescriptor* desc) const { 171 return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc)); 172 } 173 174 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const { 175 fProxy->filterRec(rec); 176 rec->setHinting(SkPaint::kNo_Hinting); 177 rec->fMaskFormat = SkMask::kARGB32_Format; 178 } 179 180 SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics( 181 PerGlyphInfo info, 182 const uint32_t* glyphIDs, 183 uint32_t glyphIDsCount) const { 184 return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 185 } 186 187 SkStreamAsset* SkGTypeface::onOpenStream(int* ttcIndex) const { 188 return fProxy->openStream(ttcIndex); 189 } 190 191 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 192 bool* isLocal) const { 193 fProxy->getFontDescriptor(desc, isLocal); 194 } 195 196 int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding, 197 uint16_t glyphs[], int glyphCount) const { 198 return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount); 199 } 200 201 int SkGTypeface::onCountGlyphs() const { 202 return fProxy->countGlyphs(); 203 } 204 205 int SkGTypeface::onGetUPEM() const { 206 return fProxy->getUnitsPerEm(); 207 } 208 209 void SkGTypeface::onGetFamilyName(SkString* familyName) const { 210 fProxy->getFamilyName(familyName); 211 } 212 213 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { 214 return fProxy->createFamilyNameIterator(); 215 } 216 217 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { 218 return fProxy->getTableTags(tags); 219 } 220 221 size_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. 231 class SkGFont : public SkRefCnt { 232 public: 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 249 private: 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 262 class SkGFontBuilder { 263 public: 264 265 }; 266 #endif 267