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