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     unsigned generateGlyphCount() override;
     20     uint16_t generateCharToGlyph(SkUnichar) override;
     21     void generateAdvance(SkGlyph*) override;
     22     void generateMetrics(SkGlyph*) override;
     23     void generateImage(const SkGlyph&) override;
     24     void generatePath(const SkGlyph&, SkPath*) override;
     25     void generateFontMetrics(SkPaint::FontMetrics*) 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->fontStyle(), 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                                 PerGlyphInfo info,
    182                                 const uint32_t* glyphIDs,
    183                                 uint32_t glyphIDsCount) const {
    184     return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
    185 }
    186 
    187 SkStreamAsset* 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 void SkGTypeface::onGetFamilyName(SkString* familyName) const {
    210     fProxy->getFamilyName(familyName);
    211 }
    212 
    213 SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const {
    214     return fProxy->createFamilyNameIterator();
    215 }
    216 
    217 int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
    218     return fProxy->getTableTags(tags);
    219 }
    220 
    221 size_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.
    231 class SkGFont : public SkRefCnt {
    232 public:
    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 
    249 private:
    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 
    262 class SkGFontBuilder {
    263 public:
    264 
    265 };
    266 #endif
    267