• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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() { delete fProxy; }
67 
generateGlyphCount()68 unsigned SkGScalerContext::generateGlyphCount() {
69     return fProxy->getGlyphCount();
70 }
71 
generateCharToGlyph(SkUnichar uni)72 uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) {
73     return fProxy->charToGlyphID(uni);
74 }
75 
generateAdvance(SkGlyph * glyph)76 void 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 
generateMetrics(SkGlyph * glyph)86 void 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 
generateImage(const SkGlyph & glyph)113 void 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 
generatePath(const SkGlyph & glyph,SkPath * path)133 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
134     fProxy->getPath(glyph, path);
135     path->transform(fMatrix);
136 }
137 
generateFontMetrics(SkPaint::FontMetrics * metrics)138 void 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 
SkGTypeface(SkTypeface * proxy,const SkPaint & paint)158 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
159     : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false)
160     , fProxy(SkRef(proxy))
161     , fPaint(paint) {}
162 
~SkGTypeface()163 SkGTypeface::~SkGTypeface() {
164     fProxy->unref();
165 }
166 
onCreateScalerContext(const SkDescriptor * desc) const167 SkScalerContext* SkGTypeface::onCreateScalerContext(
168                                             const SkDescriptor* desc) const {
169     return new SkGScalerContext(const_cast<SkGTypeface*>(this), desc);
170 }
171 
onFilterRec(SkScalerContextRec * rec) const172 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
173     fProxy->filterRec(rec);
174     rec->setHinting(SkPaint::kNo_Hinting);
175     rec->fMaskFormat = SkMask::kARGB32_Format;
176 }
177 
onGetAdvancedTypefaceMetrics(PerGlyphInfo info,const uint32_t * glyphIDs,uint32_t glyphIDsCount) const178 SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics(
179                                 PerGlyphInfo info,
180                                 const uint32_t* glyphIDs,
181                                 uint32_t glyphIDsCount) const {
182     return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
183 }
184 
onOpenStream(int * ttcIndex) const185 SkStreamAsset* SkGTypeface::onOpenStream(int* ttcIndex) const {
186     return fProxy->openStream(ttcIndex);
187 }
188 
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const189 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
190                                       bool* isLocal) const {
191     fProxy->getFontDescriptor(desc, isLocal);
192 }
193 
onCharsToGlyphs(const void * chars,Encoding encoding,uint16_t glyphs[],int glyphCount) const194 int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
195                                  uint16_t glyphs[], int glyphCount) const {
196     return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
197 }
198 
onCountGlyphs() const199 int SkGTypeface::onCountGlyphs() const {
200     return fProxy->countGlyphs();
201 }
202 
onGetUPEM() const203 int SkGTypeface::onGetUPEM() const {
204     return fProxy->getUnitsPerEm();
205 }
206 
onGetFamilyName(SkString * familyName) const207 void SkGTypeface::onGetFamilyName(SkString* familyName) const {
208     fProxy->getFamilyName(familyName);
209 }
210 
onCreateFamilyNameIterator() const211 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
212     return fProxy->createFamilyNameIterator();
213 }
214 
onGetTableTags(SkFontTableTag tags[]) const215 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
216     return fProxy->getTableTags(tags);
217 }
218 
onGetTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const219 size_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.
229 class SkGFont : public SkRefCnt {
230 public:
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 
247 private:
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 
260 class SkGFontBuilder {
261 public:
262 
263 };
264 #endif
265