Home | History | Annotate | Download | only in fonts
      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.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
    123                          glyph.fImage, glyph.rowBytes());
    124         bm.eraseColor(0);
    125 
    126         SkCanvas canvas(bm);
    127         canvas.translate(-SkIntToScalar(glyph.fLeft),
    128                          -SkIntToScalar(glyph.fTop));
    129         canvas.concat(fMatrix);
    130         canvas.drawPath(path, fFace->paint());
    131     } else {
    132         fProxy->getImage(glyph);
    133     }
    134 }
    135 
    136 void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
    137     fProxy->getPath(glyph, path);
    138     path->transform(fMatrix);
    139 }
    140 
    141 void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics*,
    142                                            SkPaint::FontMetrics* metrics) {
    143     fProxy->getFontMetrics(metrics);
    144     if (metrics) {
    145         SkScalar scale = fMatrix.getScaleY();
    146         metrics->fTop = SkScalarMul(metrics->fTop, scale);
    147         metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
    148         metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
    149         metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
    150         metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
    151         metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
    152         metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
    153         metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
    154         metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
    155     }
    156 }
    157 
    158 ///////////////////////////////////////////////////////////////////////////////
    159 
    160 #include "SkTypefaceCache.h"
    161 
    162 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
    163     : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false)
    164     , fProxy(SkRef(proxy))
    165     , fPaint(paint) {}
    166 
    167 SkGTypeface::~SkGTypeface() {
    168     fProxy->unref();
    169 }
    170 
    171 SkScalerContext* SkGTypeface::onCreateScalerContext(
    172                                             const SkDescriptor* desc) const {
    173     return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc));
    174 }
    175 
    176 void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
    177     fProxy->filterRec(rec);
    178     rec->setHinting(SkPaint::kNo_Hinting);
    179     rec->fMaskFormat = SkMask::kARGB32_Format;
    180 }
    181 
    182 SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics(
    183                                 SkAdvancedTypefaceMetrics::PerGlyphInfo info,
    184                                 const uint32_t* glyphIDs,
    185                                 uint32_t glyphIDsCount) const {
    186     return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
    187 }
    188 
    189 SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const {
    190     return fProxy->openStream(ttcIndex);
    191 }
    192 
    193 void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
    194                                       bool* isLocal) const {
    195     fProxy->getFontDescriptor(desc, isLocal);
    196 }
    197 
    198 int SkGTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
    199                                  uint16_t glyphs[], int glyphCount) const {
    200     return fProxy->charsToGlyphs(chars, encoding, glyphs, glyphCount);
    201 }
    202 
    203 int SkGTypeface::onCountGlyphs() const {
    204     return fProxy->countGlyphs();
    205 }
    206 
    207 int SkGTypeface::onGetUPEM() const {
    208     return fProxy->getUnitsPerEm();
    209 }
    210 
    211 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
    212     return fProxy->createFamilyNameIterator();
    213 }
    214 
    215 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
    216     return fProxy->getTableTags(tags);
    217 }
    218 
    219 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