Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / fonts / SkGScalerContext.cpp
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*) SK_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
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
66 SkGScalerContext::~SkGScalerContext() {
67     SkDELETE(fProxy);
68 }
69
70 unsigned SkGScalerContext::generateGlyphCount() {
71     return fProxy->getGlyphCount();
72 }
73
74 uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) {
75     return fProxy->charToGlyphID(uni);
76 }
77
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
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
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
135 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
136     fProxy->getPath(glyph, path);
137     path->transform(fMatrix);
138 }
139
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
160 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
161     : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false)
162     , fProxy(SkRef(proxy))
163     , fPaint(paint) {}
164
165 SkGTypeface::~SkGTypeface() {
166     fProxy->unref();
167 }
168
169 SkScalerContext* SkGTypeface::onCreateScalerContext(
170                                             const SkDescriptor* desc) const {
171     return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc));
172 }
173
174 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
175     fProxy->filterRec(rec);
176     rec->setHinting(SkPaint::kNo_Hinting);
177     rec->fMaskFormat = SkMask::kARGB32_Format;
178 }
179
180 SkAdvancedTypefaceMetrics* 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
187 SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const {
188     return fProxy->openStream(ttcIndex);
189 }
190
191 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
192                                       bool* isLocal) const {
193     fProxy->getFontDescriptor(desc, isLocal);
194 }
195
196 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
201 int SkGTypeface::onCountGlyphs() const {
202     return fProxy->countGlyphs();
203 }
204
205 int SkGTypeface::onGetUPEM() const {
206     return fProxy->getUnitsPerEm();
207 }
208
209 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
210     return fProxy->createFamilyNameIterator();
211 }
212
213 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
214     return fProxy->getTableTags(tags);
215 }
216
217 size_t SkGTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
218                                     size_t length, void* data) const {
219     return fProxy->getTableData(tag, offset, length, data);
220 }
221
222 ///////////////////////////////////////////////////////////////////////////////
223
224 #if 0
225 // under construction -- defining a font purely in terms of skia primitives
226 // ala an SVG-font.
227 class SkGFont : public SkRefCnt {
228 public:
229     virtual ~SkGFont();
230
231     int unicharToGlyph(SkUnichar) const;
232
233     int countGlyphs() const { return fCount; }
234
235     float getAdvance(int index) const {
236         SkASSERT((unsigned)index < (unsigned)fCount);
237         return fGlyphs[index].fAdvance;
238     }
239
240     const SkPath& getPath(int index) const {
241         SkASSERT((unsigned)index < (unsigned)fCount);
242         return fGlyphs[index].fPath;
243     }
244
245 private:
246     struct Glyph {
247         SkUnichar   fUni;
248         float       fAdvance;
249         SkPath      fPath;
250     };
251     int fCount;
252     Glyph* fGlyphs;
253
254     friend class SkGFontBuilder;
255     SkGFont(int count, Glyph* array);
256 };
257
258 class SkGFontBuilder {
259 public:
260
261 };
262 #endif