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 
SkGScalerContext(SkGTypeface * face,const SkDescriptor * desc)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 
~SkGScalerContext()66 SkGScalerContext::~SkGScalerContext() {
67     SkDELETE(fProxy);
68 }
69 
generateGlyphCount()70 unsigned SkGScalerContext::generateGlyphCount() {
71     return fProxy->getGlyphCount();
72 }
73 
generateCharToGlyph(SkUnichar uni)74 uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) {
75     return fProxy->charToGlyphID(uni);
76 }
77 
generateAdvance(SkGlyph * glyph)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 
generateMetrics(SkGlyph * glyph)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 
generateImage(const SkGlyph & glyph)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 
generatePath(const SkGlyph & glyph,SkPath * path)135 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
136     fProxy->getPath(glyph, path);
137     path->transform(fMatrix);
138 }
139 
generateFontMetrics(SkPaint::FontMetrics * metrics)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 
SkGTypeface(SkTypeface * proxy,const SkPaint & paint)160 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
161     : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false)
162     , fProxy(SkRef(proxy))
163     , fPaint(paint) {}
164 
~SkGTypeface()165 SkGTypeface::~SkGTypeface() {
166     fProxy->unref();
167 }
168 
onCreateScalerContext(const SkDescriptor * desc) const169 SkScalerContext* SkGTypeface::onCreateScalerContext(
170                                             const SkDescriptor* desc) const {
171     return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc));
172 }
173 
onFilterRec(SkScalerContextRec * rec) const174 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
175     fProxy->filterRec(rec);
176     rec->setHinting(SkPaint::kNo_Hinting);
177     rec->fMaskFormat = SkMask::kARGB32_Format;
178 }
179 
onGetAdvancedTypefaceMetrics(PerGlyphInfo info,const uint32_t * glyphIDs,uint32_t glyphIDsCount) const180 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 
onOpenStream(int * ttcIndex) const187 SkStreamAsset* SkGTypeface::onOpenStream(int* ttcIndex) const {
188     return fProxy->openStream(ttcIndex);
189 }
190 
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const191 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
192                                       bool* isLocal) const {
193     fProxy->getFontDescriptor(desc, isLocal);
194 }
195 
onCharsToGlyphs(const void * chars,Encoding encoding,uint16_t glyphs[],int glyphCount) const196 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 
onCountGlyphs() const201 int SkGTypeface::onCountGlyphs() const {
202     return fProxy->countGlyphs();
203 }
204 
onGetUPEM() const205 int SkGTypeface::onGetUPEM() const {
206     return fProxy->getUnitsPerEm();
207 }
208 
onGetFamilyName(SkString * familyName) const209 void SkGTypeface::onGetFamilyName(SkString* familyName) const {
210     fProxy->getFamilyName(familyName);
211 }
212 
onCreateFamilyNameIterator() const213 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
214     return fProxy->createFamilyNameIterator();
215 }
216 
onGetTableTags(SkFontTableTag tags[]) const217 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
218     return fProxy->getTableTags(tags);
219 }
220 
onGetTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const221 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