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 15class GlyphGenerator : public GrPathRange::PathGenerator { 16public: 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 virtual int getNumPaths() { 28 return fScalerContext->getGlyphCount(); 29 } 30 31 virtual void generatePath(int glyphID, SkPath* out) { 32 SkGlyph skGlyph; 33 skGlyph.init(SkGlyph::MakeID(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 virtual bool isEqualTo(const SkDescriptor& desc) const { 41 return fDesc->equals(desc); 42 } 43 44private: 45 SkDescriptor* const fDesc; 46 const SkAutoTDelete<SkScalerContext> fScalerContext; 47 SkMatrix fFlipMatrix; 48}; 49 50GrPathRange* 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