| /* | |
| * 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); | |
| } | |
| virtual int getNumPaths() SK_OVERRIDE { | |
| return fScalerContext->getGlyphCount(); | |
| } | |
| virtual void generatePath(int glyphID, SkPath* out) SK_OVERRIDE { | |
| SkGlyph skGlyph; | |
| skGlyph.init(SkGlyph::MakeID(glyphID)); | |
| fScalerContext->getMetrics(&skGlyph); | |
| fScalerContext->getPath(skGlyph, out); | |
| out->transform(fFlipMatrix); // Load glyphs with the inverted y-direction. | |
| } | |
| virtual bool isEqualTo(const SkDescriptor& desc) const SK_OVERRIDE { | |
| return fDesc->equals(desc); | |
| } | |
| private: | |
| SkDescriptor* const fDesc; | |
| const SkAutoTDelete<SkScalerContext> 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<GlyphGenerator> 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<GlyphGenerator> generator(SkNEW_ARGS(GlyphGenerator, (*typeface, *genericDesc))); | |
| return this->createPathRange(generator, stroke); | |
| } |