1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2013 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkGScalerContext.h"
943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkGlyph.h"
1043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkPath.h"
1143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkCanvas.h"
1243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
132b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.comclass SkGScalerContext : public SkScalerContext {
142b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.compublic:
1543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkGScalerContext(SkGTypeface*, const SkDescriptor*);
1643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    virtual ~SkGScalerContext();
172b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com
18cefc8650905f25bcb3a722dfadfca59651202726djsollen@google.comprotected:
1943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    virtual unsigned generateGlyphCount() SK_OVERRIDE;
2043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    virtual uint16_t generateCharToGlyph(SkUnichar) SK_OVERRIDE;
2143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    virtual void generateAdvance(SkGlyph*) SK_OVERRIDE;
2243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    virtual void generateMetrics(SkGlyph*) SK_OVERRIDE;
23c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com    virtual void generateImage(const SkGlyph&) SK_OVERRIDE;
2443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    virtual void generatePath(const SkGlyph&, SkPath*) SK_OVERRIDE;
252b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
26cefc8650905f25bcb3a722dfadfca59651202726djsollen@google.com
2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comprivate:
2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkGTypeface*     fFace;
2943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkScalerContext* fProxy;
3043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkMatrix         fMatrix;
3143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com};
3243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
3343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#define STD_SIZE    1
3443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
3543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#include "SkDescriptor.h"
3643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
3743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comSkGScalerContext::SkGScalerContext(SkGTypeface* face, const SkDescriptor* desc)
3843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        : SkScalerContext(face, desc)
3943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        , fFace(face)
4043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com{
4143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
4243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    size_t  descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec);
4343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkAutoDescriptor ad(descSize);
4443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkDescriptor*    newDesc = ad.getDesc();
4543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
4643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    newDesc->init();
4743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    void* entry = newDesc->addEntry(kRec_SkDescriptorTag,
4843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com                                    sizeof(SkScalerContext::Rec), &fRec);
4943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    {
5043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        SkScalerContext::Rec* rec = (SkScalerContext::Rec*)entry;
5143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        rec->fTextSize = STD_SIZE;
5243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        rec->fPreScaleX = SK_Scalar1;
5343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        rec->fPreSkewX = 0;
5443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
5543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com        rec->fPost2x2[1][0] = rec->fPost2x2[0][1] = 0;
5643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    }
5743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkASSERT(descSize == newDesc->getLength());
5843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    newDesc->computeChecksum();
5943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
6043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fProxy = face->proxy()->createScalerContext(newDesc);
6143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
6243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fRec.getSingleMatrix(&fMatrix);
6343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE);
6443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
6543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
6643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comSkGScalerContext::~SkGScalerContext() {
6743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkDELETE(fProxy);
6843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
6943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
7043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comunsigned SkGScalerContext::generateGlyphCount() {
7143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    return fProxy->getGlyphCount();
7243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
7343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
7443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comuint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) {
7543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    return fProxy->charToGlyphID(uni);
7643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
7743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
7843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comvoid SkGScalerContext::generateAdvance(SkGlyph* glyph) {
7943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fProxy->getAdvance(glyph);
8043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
8143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkVector advance;
8243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
8343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com                  SkFixedToScalar(glyph->fAdvanceY), &advance);
8443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    glyph->fAdvanceX = SkScalarToFixed(advance.fX);
8543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    glyph->fAdvanceY = SkScalarToFixed(advance.fY);
8643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com}
8743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
8843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comvoid SkGScalerContext::generateMetrics(SkGlyph* glyph) {
8943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fProxy->getMetrics(glyph);
9043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
9143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    SkVector advance;
9243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
9343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com                  SkFixedToScalar(glyph->fAdvanceY), &advance);
9443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    glyph->fAdvanceX = SkScalarToFixed(advance.fX);
9543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    glyph->fAdvanceY = SkScalarToFixed(advance.fY);
9643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com
9743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com    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
115void 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
135void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
136    fProxy->getPath(glyph, path);
137    path->transform(fMatrix);
138}
139
140void 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
160SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
161    : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false)
162    , fProxy(SkRef(proxy))
163    , fPaint(paint) {}
164
165SkGTypeface::~SkGTypeface() {
166    fProxy->unref();
167}
168
169SkScalerContext* SkGTypeface::onCreateScalerContext(
170                                            const SkDescriptor* desc) const {
171    return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc));
172}
173
174void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
175    fProxy->filterRec(rec);
176    rec->setHinting(SkPaint::kNo_Hinting);
177    rec->fMaskFormat = SkMask::kARGB32_Format;
178}
179
180SkAdvancedTypefaceMetrics* 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
187SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const {
188    return fProxy->openStream(ttcIndex);
189}
190
191void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
192                                      bool* isLocal) const {
193    fProxy->getFontDescriptor(desc, isLocal);
194}
195
196int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
197                                 uint16_t glyphs[], int glyphCount) const {
198    return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
199}
200
201int SkGTypeface::onCountGlyphs() const {
202    return fProxy->countGlyphs();
203}
204
205int SkGTypeface::onGetUPEM() const {
206    return fProxy->getUnitsPerEm();
207}
208
209void SkGTypeface::onGetFamilyName(SkString* familyName) const {
210    fProxy->getFamilyName(familyName);
211}
212
213SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
214    return fProxy->createFamilyNameIterator();
215}
216
217int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
218    return fProxy->getTableTags(tags);
219}
220
221size_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.
231class SkGFont : public SkRefCnt {
232public:
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
249private:
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
262class SkGFontBuilder {
263public:
264
265};
266#endif
267