aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp7
-rw-r--r--src/gpu/GrTextStrike.cpp70
-rw-r--r--src/gpu/SkGrFontScaler.cpp40
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp18
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.