/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrPathRendering.h" #include "SkDescriptor.h" #include "SkGlyph.h" #include "SkMatrix.h" #include "SkTypeface.h" #include "GrPathRange.h" class GlyphGenerator : public GrPathRange::PathGenerator { public: GlyphGenerator(const SkTypeface& typeface, const SkDescriptor& desc) : fDesc(desc.copy()), fScalerContext(typeface.createScalerContext(fDesc)) { fFlipMatrix.setScale(1, -1); } virtual ~GlyphGenerator() { SkDescriptor::Free(fDesc); } int getNumPaths() override { return fScalerContext->getGlyphCount(); } void generatePath(int glyphID, SkPath* out) override { SkGlyph skGlyph; skGlyph.initWithGlyphID(glyphID); fScalerContext->getMetrics(&skGlyph); fScalerContext->getPath(skGlyph, out); out->transform(fFlipMatrix); // Load glyphs with the inverted y-direction. } bool isEqualTo(const SkDescriptor& desc) const override { return fDesc->equals(desc); } private: SkDescriptor* const fDesc; const SkAutoTDelete fScalerContext; SkMatrix fFlipMatrix; }; GrPathRange* GrPathRendering::createGlyphs(const SkTypeface* typeface, const SkDescriptor* desc, const SkStrokeRec& stroke) { if (NULL == typeface) { typeface = SkTypeface::GetDefaultTypeface(); SkASSERT(NULL != typeface); } if (desc) { SkAutoTUnref generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *desc))); return this->createPathRange(generator, stroke); } SkScalerContextRec rec; memset(&rec, 0, sizeof(rec)); rec.fFontID = typeface->uniqueID(); rec.fTextSize = SkPaint::kCanonicalTextSizeForPaths; rec.fPreScaleX = rec.fPost2x2[0][0] = rec.fPost2x2[1][1] = SK_Scalar1; // Don't bake stroke information into the glyphs, we'll let the GPU do the stroking. SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1)); SkDescriptor* genericDesc = ad.getDesc(); genericDesc->init(); genericDesc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); genericDesc->computeChecksum(); SkAutoTUnref generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *genericDesc))); return this->createPathRange(generator, stroke); }