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 "SkCanvas.h"
9 #include "SkDescriptor.h"
10 #include "SkGScalerContext.h"
11 #include "SkGlyph.h"
12 #include "SkPaintPriv.h"
13 #include "SkPath.h"
14 #include "SkMakeUnique.h"
15 
16 #define STD_SIZE    1
17 
18 class SkGScalerContext : public SkScalerContext {
19 public:
SkGScalerContext(sk_sp<SkGTypeface> face,const SkScalerContextEffects & effects,const SkDescriptor * desc)20     SkGScalerContext(sk_sp<SkGTypeface> face, const SkScalerContextEffects& effects,
21                      const SkDescriptor* desc)
22         : SkScalerContext(std::move(face), effects, desc)
23     {
24 
25         size_t  descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec);
26         SkAutoDescriptor ad(descSize);
27         SkDescriptor*    newDesc = ad.getDesc();
28 
29         newDesc->init();
30         void* entry = newDesc->addEntry(kRec_SkDescriptorTag,
31                                         sizeof(SkScalerContext::Rec), &fRec);
32         {
33             SkScalerContext::Rec* rec = (SkScalerContext::Rec*)entry;
34             rec->fTextSize = STD_SIZE;
35             rec->fPreScaleX = SK_Scalar1;
36             rec->fPreSkewX = 0;
37             rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
38             rec->fPost2x2[1][0] = rec->fPost2x2[0][1] = 0;
39         }
40         SkASSERT(descSize == newDesc->getLength());
41         newDesc->computeChecksum();
42 
43         fProxy = this->getGTypeface()->proxy()->createScalerContext(effects, newDesc);
44 
45         fRec.getSingleMatrix(&fMatrix);
46         fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE);
47     }
48 
49 protected:
getGTypeface()50     SkGTypeface* getGTypeface() { return static_cast<SkGTypeface*>(this->getTypeface()); }
51 
52     unsigned generateGlyphCount() override;
53     uint16_t generateCharToGlyph(SkUnichar) override;
54     void generateAdvance(SkGlyph*) override;
55     void generateMetrics(SkGlyph*) override;
56     void generateImage(const SkGlyph&) override;
57     void generatePath(SkGlyphID, SkPath*) override;
58     void generateFontMetrics(SkPaint::FontMetrics*) override;
59 
60 private:
61     std::unique_ptr<SkScalerContext> fProxy;
62     SkMatrix         fMatrix;
63 };
64 
generateGlyphCount()65 unsigned SkGScalerContext::generateGlyphCount() {
66     return fProxy->getGlyphCount();
67 }
68 
generateCharToGlyph(SkUnichar uni)69 uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) {
70     return fProxy->charToGlyphID(uni);
71 }
72 
generateAdvance(SkGlyph * glyph)73 void SkGScalerContext::generateAdvance(SkGlyph* glyph) {
74     fProxy->getAdvance(glyph);
75 
76     SkVector advance;
77     fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX),
78                   SkFloatToScalar(glyph->fAdvanceY), &advance);
79     glyph->fAdvanceX = SkScalarToFloat(advance.fX);
80     glyph->fAdvanceY = SkScalarToFloat(advance.fY);
81 }
82 
generateMetrics(SkGlyph * glyph)83 void SkGScalerContext::generateMetrics(SkGlyph* glyph) {
84     fProxy->getMetrics(glyph);
85 
86     SkVector advance;
87     fMatrix.mapXY(SkFloatToScalar(glyph->fAdvanceX),
88                   SkFloatToScalar(glyph->fAdvanceY), &advance);
89     glyph->fAdvanceX = SkScalarToFloat(advance.fX);
90     glyph->fAdvanceY = SkScalarToFloat(advance.fY);
91 
92     SkPath path;
93     fProxy->getPath(glyph->getPackedID(), &path);
94     path.transform(fMatrix);
95 
96     SkRect storage;
97     const SkPaint& paint = this->getGTypeface()->paint();
98     const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
99                                                         &storage,
100                                                         SkPaint::kFill_Style);
101     SkIRect ibounds;
102     newBounds.roundOut(&ibounds);
103     glyph->fLeft = ibounds.fLeft;
104     glyph->fTop = ibounds.fTop;
105     glyph->fWidth = ibounds.width();
106     glyph->fHeight = ibounds.height();
107     glyph->fMaskFormat = SkMask::kARGB32_Format;
108 }
109 
generateImage(const SkGlyph & glyph)110 void SkGScalerContext::generateImage(const SkGlyph& glyph) {
111     if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
112         SkPath path;
113         fProxy->getPath(glyph.getPackedID(), &path);
114 
115         SkBitmap bm;
116         bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
117                          glyph.fImage, glyph.rowBytes());
118         bm.eraseColor(0);
119 
120         SkCanvas canvas(bm);
121         canvas.translate(-SkIntToScalar(glyph.fLeft),
122                          -SkIntToScalar(glyph.fTop));
123         canvas.concat(fMatrix);
124         canvas.drawPath(path, this->getGTypeface()->paint());
125     } else {
126         fProxy->getImage(glyph);
127     }
128 }
129 
generatePath(SkGlyphID glyph,SkPath * path)130 void SkGScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
131     fProxy->getPath(SkPackedGlyphID(glyph), path);
132     path->transform(fMatrix);
133 }
134 
generateFontMetrics(SkPaint::FontMetrics * metrics)135 void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) {
136     fProxy->getFontMetrics(metrics);
137     SkPaintPriv::ScaleFontMetrics(metrics, fMatrix.getScaleY());
138 }
139 
140 ///////////////////////////////////////////////////////////////////////////////
141 
142 #include "SkTypefaceCache.h"
143 
SkGTypeface(sk_sp<SkTypeface> proxy,const SkPaint & paint)144 SkGTypeface::SkGTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint)
145     : SkTypeface(proxy->fontStyle(), false)
146     , fProxy(std::move(proxy))
147     , fPaint(paint)
148 {}
149 
onCreateScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const150 SkScalerContext* SkGTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
151                                                     const SkDescriptor* desc) const {
152     return new SkGScalerContext(sk_ref_sp(const_cast<SkGTypeface*>(this)), effects, desc);
153 }
154 
onFilterRec(SkScalerContextRec * rec) const155 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
156     fProxy->filterRec(rec);
157     rec->setHinting(SkPaint::kNo_Hinting);
158     rec->fMaskFormat = SkMask::kARGB32_Format;
159 }
160 
onGetAdvancedTypefaceMetrics(PerGlyphInfo info,const uint32_t * glyphIDs,uint32_t glyphIDsCount) const161 SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics(
162                                 PerGlyphInfo info,
163                                 const uint32_t* glyphIDs,
164                                 uint32_t glyphIDsCount) const {
165     return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
166 }
167 
onOpenStream(int * ttcIndex) const168 SkStreamAsset* SkGTypeface::onOpenStream(int* ttcIndex) const {
169     return fProxy->openStream(ttcIndex);
170 }
171 
onGetFontDescriptor(SkFontDescriptor * desc,bool * isLocal) const172 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
173                                       bool* isLocal) const {
174     fProxy->getFontDescriptor(desc, isLocal);
175 }
176 
onCharsToGlyphs(const void * chars,Encoding encoding,uint16_t glyphs[],int glyphCount) const177 int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
178                                  uint16_t glyphs[], int glyphCount) const {
179     return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
180 }
181 
onCountGlyphs() const182 int SkGTypeface::onCountGlyphs() const {
183     return fProxy->countGlyphs();
184 }
185 
onGetUPEM() const186 int SkGTypeface::onGetUPEM() const {
187     return fProxy->getUnitsPerEm();
188 }
189 
onGetFamilyName(SkString * familyName) const190 void SkGTypeface::onGetFamilyName(SkString* familyName) const {
191     fProxy->getFamilyName(familyName);
192 }
193 
onCreateFamilyNameIterator() const194 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
195     return fProxy->createFamilyNameIterator();
196 }
197 
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const198 int SkGTypeface::onGetVariationDesignPosition(
199         SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
200 {
201     return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount);
202 }
203 
onGetTableTags(SkFontTableTag tags[]) const204 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
205     return fProxy->getTableTags(tags);
206 }
207 
onGetTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const208 size_t SkGTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
209                                     size_t length, void* data) const {
210     return fProxy->getTableData(tag, offset, length, data);
211 }
212 
213 ///////////////////////////////////////////////////////////////////////////////
214 
215 #if 0
216 // under construction -- defining a font purely in terms of skia primitives
217 // ala an SVG-font.
218 class SkGFont : public SkRefCnt {
219 public:
220     virtual ~SkGFont();
221 
222     int unicharToGlyph(SkUnichar) const;
223 
224     int countGlyphs() const { return fCount; }
225 
226     float getAdvance(int index) const {
227         SkASSERT((unsigned)index < (unsigned)fCount);
228         return fGlyphs[index].fAdvance;
229     }
230 
231     const SkPath& getPath(int index) const {
232         SkASSERT((unsigned)index < (unsigned)fCount);
233         return fGlyphs[index].fPath;
234     }
235 
236 private:
237     struct Glyph {
238         SkUnichar   fUni;
239         float       fAdvance;
240         SkPath      fPath;
241     };
242     int fCount;
243     Glyph* fGlyphs;
244 
245     friend class SkGFontBuilder;
246     SkGFont(int count, Glyph* array);
247 };
248 
249 class SkGFontBuilder {
250 public:
251 
252 };
253 #endif
254