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