diff options
Diffstat (limited to 'src/gpu')
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 7 | ||||
-rw-r--r-- | src/gpu/GrTextStrike.cpp | 70 | ||||
-rw-r--r-- | src/gpu/SkGrFontScaler.cpp | 40 | ||||
-rwxr-xr-x | src/gpu/effects/GrDistanceFieldTextureEffect.cpp | 18 |
4 files changed, 64 insertions, 71 deletions
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 568f09563f..448e709805 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -239,10 +239,11 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, } GrContext::AutoMatrix am; - SkMatrix translate; - translate.setTranslate(sx, sy); + SkMatrix ctm; + ctm.setScale(fTextRatio, fTextRatio); + ctm.postTranslate(sx, sy); GrPaint tmpPaint(fPaint); - am.setPreConcat(fContext, translate, &tmpPaint); + am.setPreConcat(fContext, ctm, &tmpPaint); SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); fContext->drawPath(tmpPaint, *glyph->fPath, stroke); return; diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp index 65ead0f0bb..29d1b91e8e 100644 --- a/src/gpu/GrTextStrike.cpp +++ b/src/gpu/GrTextStrike.cpp @@ -214,10 +214,6 @@ void GrFontCache::dump() const { static int gCounter; #endif -// this acts as the max magnitude for the distance field, -// as well as the pad we need around the glyph -#define DISTANCE_FIELD_RANGE 4 - /* The text strike is specific to a given font/style/matrix setup, which is represented by the GrHostFontScaler object we are given in getGlyph(). @@ -260,20 +256,17 @@ GrTextStrike::~GrTextStrike() { GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) { SkIRect bounds; - if (!scaler->getPackedGlyphBounds(packed, &bounds)) { - return NULL; + if (fUseDistanceField) { + if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) { + return NULL; + } + } else { + if (!scaler->getPackedGlyphBounds(packed, &bounds)) { + return NULL; + } } GrGlyph* glyph = fPool.alloc(); - // expand bounds to hold full distance field data - // + room for bilerp - int pad = DISTANCE_FIELD_RANGE+1; - if (fUseDistanceField) { - bounds.fLeft -= pad; - bounds.fRight += pad; - bounds.fTop -= pad; - bounds.fBottom += pad; - } glyph->init(packed, bounds); fCache.insert(packed, glyph); return glyph; @@ -306,56 +299,27 @@ bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) { int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); - GrPlot* plot; + size_t size = glyph->fBounds.area() * bytesPerPixel; + SkAutoSMalloc<1024> storage(size); if (fUseDistanceField) { - // we've already expanded the glyph dimensions to match the final size - // but must shrink back down to get the packed glyph data - int dfWidth = glyph->width(); - int dfHeight = glyph->height(); - int pad = DISTANCE_FIELD_RANGE+1; - int width = dfWidth - 2*pad; - int height = dfHeight - 2*pad; - int stride = width*bytesPerPixel; - - size_t size = width * height * bytesPerPixel; - SkAutoSMalloc<1024> storage(size); - if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride, storage.get())) { + if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(), + glyph->height(), + storage.get())) { return false; } - - // alloc storage for distance field glyph - size_t dfSize = dfWidth * dfHeight * bytesPerPixel; - SkAutoSMalloc<1024> dfStorage(dfSize); - - if (1 == bytesPerPixel) { - (void) SkGenerateDistanceFieldFromImage((unsigned char*)dfStorage.get(), - (unsigned char*)storage.get(), - width, height, DISTANCE_FIELD_RANGE); - } else { - // distance fields should only be used to represent alpha masks - SkASSERT(false); - return false; - } - - // copy to atlas - plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get(), - &glyph->fAtlasLocation); - } else { - size_t size = glyph->fBounds.area() * bytesPerPixel; - SkAutoSMalloc<1024> storage(size); if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), glyph->height(), glyph->width() * bytesPerPixel, storage.get())) { return false; } - - plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), - glyph->height(), storage.get(), - &glyph->fAtlasLocation); } + GrPlot* plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), + glyph->height(), storage.get(), + &glyph->fAtlasLocation); + if (NULL == plot) { return false; } diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp index 8fdae48a2a..c0be4ff78e 100644 --- a/src/gpu/SkGrFontScaler.cpp +++ b/src/gpu/SkGrFontScaler.cpp @@ -10,6 +10,7 @@ #include "GrTemplates.h" #include "SkGr.h" #include "SkDescriptor.h" +#include "SkDistanceFieldGen.h" #include "SkGlyphCache.h" class SkGrDescKey : public GrKey { @@ -102,14 +103,23 @@ const GrKey* SkGrFontScaler::getKey() { return fKey; } -bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, - SkIRect* bounds) { +bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) { const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), - GrGlyph::UnpackFixedX(packed), - GrGlyph::UnpackFixedY(packed)); + GrGlyph::UnpackFixedX(packed), + GrGlyph::UnpackFixedY(packed)); bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight); + return true; +} + +bool SkGrFontScaler::getPackedGlyphDFBounds(GrGlyph::PackedID packed, SkIRect* bounds) { + const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), + GrGlyph::UnpackFixedX(packed), + GrGlyph::UnpackFixedY(packed)); + bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight); + bounds->outset(SK_DistanceFieldPad, SK_DistanceFieldPad); + return true; } namespace { @@ -142,8 +152,8 @@ bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed, int width, int height, int dstRB, void* dst) { const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), - GrGlyph::UnpackFixedX(packed), - GrGlyph::UnpackFixedY(packed)); + GrGlyph::UnpackFixedX(packed), + GrGlyph::UnpackFixedY(packed)); SkASSERT(glyph.fWidth == width); SkASSERT(glyph.fHeight == height); const void* src = fStrike->findImage(glyph); @@ -190,6 +200,24 @@ bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed, return true; } +bool SkGrFontScaler::getPackedGlyphDFImage(GrGlyph::PackedID packed, + int width, int height, + void* dst) { + const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), + GrGlyph::UnpackFixedX(packed), + GrGlyph::UnpackFixedY(packed)); + SkASSERT(glyph.fWidth + 2*SK_DistanceFieldPad == width); + SkASSERT(glyph.fHeight + 2*SK_DistanceFieldPad == height); + const void* src = fStrike->findDistanceField(glyph); + if (NULL == src) { + return false; + } + + memcpy(dst, src, width * height); + + return true; +} + // we should just return const SkPath* (NULL means false) bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) { diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp index 8a023cd1d0..b332c7d2cf 100755 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp @@ -13,10 +13,7 @@ #include "GrTBackendEffectFactory.h" #include "GrTexture.h" -// The distance field is constructed as unsigned char values, so that the zero value is at 128, -// and the range is [-4, 4 - 1/255). Hence our multiplier is 8 - 1/32 and zero threshold is 128/255. -#define MULTIPLIER "7.96875" -#define THRESHOLD "0.50196078431" +#include "SkDistanceFieldGen.h" class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { public: @@ -58,7 +55,8 @@ public: fsCoordName.c_str(), kVec2f_GrSLType); builder->fsCodeAppend(";\n"); - builder->fsCodeAppend("\tfloat distance = " MULTIPLIER "*(texColor.r - " THRESHOLD ");\n"); + builder->fsCodeAppend("\tfloat distance = " + SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");\n"); // we adjust for the effect of the transformation on the distance by using // the length of the gradient of the texture coordinates. We use st coordinates @@ -239,20 +237,22 @@ public: builder->fsAppendTextureLookup(samplers[0], "uv", kVec2f_GrSLType); builder->fsCodeAppend(";\n"); builder->fsCodeAppend("\tvec3 distance;\n"); - builder->fsCodeAppend("\tdistance.y = " MULTIPLIER "*(texColor.r - " THRESHOLD ");\n"); + builder->fsCodeAppend("\tdistance.y = " + SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");\n"); // red is distance to left offset builder->fsCodeAppend("\tvec2 uv_adjusted = uv - offset;\n"); builder->fsCodeAppend("\ttexColor = "); builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); builder->fsCodeAppend(";\n"); - builder->fsCodeAppend("\tdistance.x = " MULTIPLIER "*(texColor.r - " THRESHOLD ");\n"); + builder->fsCodeAppend("\tdistance.x = " + SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");\n"); // blue is distance to right offset builder->fsCodeAppend("\tuv_adjusted = uv + offset;\n"); builder->fsCodeAppend("\ttexColor = "); builder->fsAppendTextureLookup(samplers[0], "uv_adjusted", kVec2f_GrSLType); builder->fsCodeAppend(";\n"); - builder->fsCodeAppend("\tdistance.z = " MULTIPLIER "*(texColor.r - " THRESHOLD ");\n"); - + builder->fsCodeAppend("\tdistance.z = " + SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");\n"); // we adjust for the effect of the transformation on the distance by using // the length of the gradient of the texture coordinates. We use st coordinates // to ensure we're mapping 1:1 from texel space to pixel space. |