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.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
    266