Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2014 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 "GrPathRendering.h"
      9 #include "SkDescriptor.h"
     10 #include "SkGlyph.h"
     11 #include "SkMatrix.h"
     12 #include "SkTypeface.h"
     13 #include "GrPathRange.h"
     14 
     15 class GlyphGenerator : public GrPathRange::PathGenerator {
     16 public:
     17     GlyphGenerator(const SkTypeface& typeface, const SkDescriptor& desc)
     18         : fDesc(desc.copy()),
     19           fScalerContext(typeface.createScalerContext(fDesc)) {
     20         fFlipMatrix.setScale(1, -1);
     21     }
     22 
     23     virtual ~GlyphGenerator() {
     24         SkDescriptor::Free(fDesc);
     25     }
     26 
     27     int getNumPaths() override {
     28         return fScalerContext->getGlyphCount();
     29     }
     30 
     31     void generatePath(int glyphID, SkPath* out) override {
     32         SkGlyph skGlyph;
     33         skGlyph.initWithGlyphID(glyphID);
     34         fScalerContext->getMetrics(&skGlyph);
     35 
     36         fScalerContext->getPath(skGlyph, out);
     37         out->transform(fFlipMatrix); // Load glyphs with the inverted y-direction.
     38     }
     39 
     40     bool isEqualTo(const SkDescriptor& desc) const override {
     41         return fDesc->equals(desc);
     42     }
     43 
     44 private:
     45     SkDescriptor* const fDesc;
     46     const SkAutoTDelete<SkScalerContext> fScalerContext;
     47     SkMatrix fFlipMatrix;
     48 };
     49 
     50 GrPathRange* GrPathRendering::createGlyphs(const SkTypeface* typeface,
     51                                            const SkDescriptor* desc,
     52                                            const SkStrokeRec& stroke) {
     53     if (NULL == typeface) {
     54         typeface = SkTypeface::GetDefaultTypeface();
     55         SkASSERT(NULL != typeface);
     56     }
     57 
     58     if (desc) {
     59         SkAutoTUnref<GlyphGenerator> generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *desc)));
     60         return this->createPathRange(generator, stroke);
     61     }
     62 
     63     SkScalerContextRec rec;
     64     memset(&rec, 0, sizeof(rec));
     65     rec.fFontID = typeface->uniqueID();
     66     rec.fTextSize = SkPaint::kCanonicalTextSizeForPaths;
     67     rec.fPreScaleX = rec.fPost2x2[0][0] = rec.fPost2x2[1][1] = SK_Scalar1;
     68     // Don't bake stroke information into the glyphs, we'll let the GPU do the stroking.
     69 
     70     SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
     71     SkDescriptor*    genericDesc = ad.getDesc();
     72 
     73     genericDesc->init();
     74     genericDesc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
     75     genericDesc->computeChecksum();
     76 
     77     SkAutoTUnref<GlyphGenerator> generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *genericDesc)));
     78     return this->createPathRange(generator, stroke);
     79 }
     80