1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2013 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkGScalerContext.h" 943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkGlyph.h" 1043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkPath.h" 1143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkCanvas.h" 1243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 132b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.comclass SkGScalerContext : public SkScalerContext { 142b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.compublic: 1543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkGScalerContext(SkGTypeface*, const SkDescriptor*); 1643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com virtual ~SkGScalerContext(); 172b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com 18cefc8650905f25bcb3a722dfadfca59651202726djsollen@google.comprotected: 1943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com virtual unsigned generateGlyphCount() SK_OVERRIDE; 2043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com virtual uint16_t generateCharToGlyph(SkUnichar) SK_OVERRIDE; 2143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com virtual void generateAdvance(SkGlyph*) SK_OVERRIDE; 2243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com virtual void generateMetrics(SkGlyph*) SK_OVERRIDE; 23c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com virtual void generateImage(const SkGlyph&) SK_OVERRIDE; 2443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com virtual void generatePath(const SkGlyph&, SkPath*) SK_OVERRIDE; 252b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE; 26cefc8650905f25bcb3a722dfadfca59651202726djsollen@google.com 2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comprivate: 2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkGTypeface* fFace; 2943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkScalerContext* fProxy; 3043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkMatrix fMatrix; 3143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}; 3243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 3343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#define STD_SIZE 1 3443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 3543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkDescriptor.h" 3643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 3743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comSkGScalerContext::SkGScalerContext(SkGTypeface* face, const SkDescriptor* desc) 3843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com : SkScalerContext(face, desc) 3943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com , fFace(face) 4043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com{ 4143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 4243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com size_t descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec); 4343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkAutoDescriptor ad(descSize); 4443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkDescriptor* newDesc = ad.getDesc(); 4543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 4643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com newDesc->init(); 4743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com void* entry = newDesc->addEntry(kRec_SkDescriptorTag, 4843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com sizeof(SkScalerContext::Rec), &fRec); 4943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com { 5043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkScalerContext::Rec* rec = (SkScalerContext::Rec*)entry; 5143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com rec->fTextSize = STD_SIZE; 5243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com rec->fPreScaleX = SK_Scalar1; 5343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com rec->fPreSkewX = 0; 5443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 5543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com rec->fPost2x2[1][0] = rec->fPost2x2[0][1] = 0; 5643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 5743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkASSERT(descSize == newDesc->getLength()); 5843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com newDesc->computeChecksum(); 5943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 6043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fProxy = face->proxy()->createScalerContext(newDesc); 6143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 6243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fRec.getSingleMatrix(&fMatrix); 6343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE); 6443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 6543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 6643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comSkGScalerContext::~SkGScalerContext() { 6743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkDELETE(fProxy); 6843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 6943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 7043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comunsigned SkGScalerContext::generateGlyphCount() { 7143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return fProxy->getGlyphCount(); 7243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 7343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 7443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comuint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) { 7543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return fProxy->charToGlyphID(uni); 7643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 7743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 7843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comvoid SkGScalerContext::generateAdvance(SkGlyph* glyph) { 7943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fProxy->getAdvance(glyph); 8043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 8143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkVector advance; 8243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), 8343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkFixedToScalar(glyph->fAdvanceY), &advance); 8443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com glyph->fAdvanceX = SkScalarToFixed(advance.fX); 8543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com glyph->fAdvanceY = SkScalarToFixed(advance.fY); 8643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 8743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 8843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comvoid SkGScalerContext::generateMetrics(SkGlyph* glyph) { 8943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fProxy->getMetrics(glyph); 9043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 9143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkVector advance; 9243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), 9343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkFixedToScalar(glyph->fAdvanceY), &advance); 9443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com glyph->fAdvanceX = SkScalarToFixed(advance.fX); 9543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com glyph->fAdvanceY = SkScalarToFixed(advance.fY); 9643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 9743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 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