aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xgm/dftext.cpp165
-rw-r--r--gm/fontscaler.cpp2
-rw-r--r--gyp/gmslides.gypi1
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp31
-rw-r--r--src/gpu/GrDistanceFieldTextContext.h1
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp9
6 files changed, 197 insertions, 12 deletions
diff --git a/gm/dftext.cpp b/gm/dftext.cpp
new file mode 100755
index 0000000000..65e64a9093
--- /dev/null
+++ b/gm/dftext.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gm.h"
+#include "SkSurface.h"
+#include "SkTypeface.h"
+
+namespace skiagm {
+
+class DFTextGM : public GM {
+public:
+ DFTextGM() {
+ this->setBGColor(0xFFFFFFFF);
+ }
+
+ virtual ~DFTextGM() {
+ }
+
+protected:
+ virtual uint32_t onGetFlags() const SK_OVERRIDE {
+ return kGPUOnly_Flag;
+ }
+
+ virtual SkString onShortName() {
+ return SkString("dftext");
+ }
+
+ virtual SkISize onISize() {
+ return SkISize::Make(1024, 768);
+ }
+
+ static void rotate_about(SkCanvas* canvas,
+ SkScalar degrees,
+ SkScalar px, SkScalar py) {
+ canvas->translate(px, py);
+ canvas->rotate(degrees);
+ canvas->translate(-px, -py);
+ }
+
+ virtual void onDraw(SkCanvas* inputCanvas) {
+ SkScalar textSizes[] = { 11.0f, 11.0f*2.0f, 11.0f*5.0f, 11.0f*2.0f*5.0f };
+ SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };
+
+ // set up offscreen rendering with distance field text
+#if SK_SUPPORT_GPU
+ GrContext* ctx = inputCanvas->getGrContext();
+ SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, info, 0,
+ SkSurface::kDistanceField_TextRenderMode));
+ SkCanvas* canvas = surface->getCanvas();
+#else
+ SkCanvas* canvas = inputCanvas;
+#endif
+ canvas->clear(0xffffffff);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setSubpixelText(true);
+#if !SK_SUPPORT_GPU
+ paint.setDistanceFieldTextTEMP(true);
+#endif
+ sk_tool_utils::set_portable_typeface(&paint, "Times New Roman", SkTypeface::kNormal);
+
+ const char* text = "Hamburgefons";
+ const size_t textLen = strlen(text);
+
+ // check scaling up
+ SkScalar x = SkIntToScalar(0);
+ SkScalar y = SkIntToScalar(78);
+ for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->translate(x, y);
+ canvas->scale(scales[i], scales[i]);
+ paint.setTextSize(textSizes[i]);
+ canvas->drawText(text, textLen, 0, 0, paint);
+ y += paint.getFontMetrics(NULL)*scales[i];
+ }
+
+ // check rotation
+ for (size_t i = 0; i < 5; ++i) {
+ SkScalar rotX = SkIntToScalar(10);
+ SkScalar rotY = y;
+
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->translate(SkIntToScalar(10 + i * 200), -80);
+ rotate_about(canvas, SkIntToScalar(i * 5), rotX, rotY);
+ for (int ps = 6; ps <= 32; ps += 3) {
+ paint.setTextSize(SkIntToScalar(ps));
+ canvas->drawText(text, textLen, rotX, rotY, paint);
+ rotY += paint.getFontMetrics(NULL);
+ }
+ }
+
+ // check scaling down
+ paint.setLCDRenderText(true);
+ x = SkIntToScalar(700);
+ y = SkIntToScalar(20);
+ size_t arraySize = SK_ARRAY_COUNT(textSizes);
+ for (size_t i = 0; i < arraySize; ++i) {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->translate(x, y);
+ SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]);
+ canvas->scale(scaleFactor, scaleFactor);
+ paint.setTextSize(textSizes[i]);
+ canvas->drawText(text, textLen, 0, 0, paint);
+ y += paint.getFontMetrics(NULL)*scaleFactor;
+ }
+
+ // check gamma-corrected blending
+ const SkColor fg[] = {
+ 0xFFFFFFFF,
+ 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
+ 0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
+ 0xFF000000,
+ };
+
+ paint.setColor(0xFFF1F1F1);
+ SkRect r = SkRect::MakeLTRB(690, 250, 840, 460);
+ canvas->drawRect(r, paint);
+
+ x = SkIntToScalar(700);
+ y = SkIntToScalar(270);
+ paint.setTextSize(SkIntToScalar(22));
+ for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
+ paint.setColor(fg[i]);
+
+ canvas->drawText(text, textLen, x, y, paint);
+ y += paint.getFontMetrics(NULL);
+ }
+
+ paint.setColor(0xFF1F1F1F);
+ r = SkRect::MakeLTRB(840, 250, 990, 460);
+ canvas->drawRect(r, paint);
+
+ x = SkIntToScalar(850);
+ y = SkIntToScalar(270);
+ paint.setTextSize(SkIntToScalar(22));
+ for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
+ paint.setColor(fg[i]);
+
+ canvas->drawText(text, textLen, x, y, paint);
+ y += paint.getFontMetrics(NULL);
+ }
+
+#if SK_SUPPORT_GPU
+ // render offscreen buffer
+ SkImage* image = surface->newImageSnapshot();
+ image->draw(inputCanvas, 0, 0, NULL);
+ image->unref();
+#endif
+ }
+
+private:
+ typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new DFTextGM; }
+static GMRegistry reg(MyFactory);
+
+}
diff --git a/gm/fontscaler.cpp b/gm/fontscaler.cpp
index 8aef8f0ebe..eb38013cb1 100644
--- a/gm/fontscaler.cpp
+++ b/gm/fontscaler.cpp
@@ -72,12 +72,10 @@ protected:
canvas->drawRect(r, p);
}
- int index = 0;
for (int ps = 6; ps <= 22; ps++) {
paint.setTextSize(SkIntToScalar(ps));
canvas->drawText(text, textLen, x, y, paint);
y += paint.getFontMetrics(NULL);
- index += 1;
}
}
canvas->translate(0, SkIntToScalar(360));
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index f3d7b80a7b..1ee94db929 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -63,6 +63,7 @@
'../gm/dashing.cpp',
'../gm/deviceproperties.cpp',
'../gm/distantclip.cpp',
+ '../gm/dftext.cpp',
'../gm/displacement.cpp',
'../gm/downsamplebitmap.cpp',
'../gm/drawbitmaprect.cpp',
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index d32dcb9c21..18058be17f 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -127,9 +127,9 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
// set up any flags
uint32_t flags = 0;
- flags |= fContext->getMatrix().isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ flags |= fTextMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0;
- flags |= fUseLCDText && fContext->getMatrix().rectStaysRect() ?
+ flags |= fUseLCDText && fTextMatrix.rectStaysRect() ?
kRectToRect_DistanceFieldEffectFlag : 0;
bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
fDeviceProperties.fGeometry.getLayout();
@@ -176,7 +176,8 @@ void GrDistanceFieldTextContext::flushGlyphs() {
GrDrawState* drawState = fDrawTarget->drawState();
GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
+
+ drawState->setFromPaint(fPaint, fTextMatrix, fContext->getRenderTarget());
if (fCurrVertex > 0) {
// setup our sampler state for our text texture/atlas
@@ -443,18 +444,32 @@ inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint
fStrike = NULL;
+ fTextMatrix = fContext->getMatrix();
+
+ // getMaxScale doesn't support perspective, so neither do we at the moment
+ SkASSERT(!fTextMatrix.hasPerspective());
+ SkScalar maxScale = fTextMatrix.getMaxScale();
+ SkScalar textSize = fSkPaint.getTextSize();
+ // if we have non-unity scale, we need to adjust our text size accordingly
+ // to avoid aliasing, and prescale the matrix by the inverse to end up with the same size
+ // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
+ if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
+ textSize *= maxScale;
+ fTextMatrix.preScale(SK_Scalar1 / maxScale, SK_Scalar1 / maxScale);
+ }
+
fCurrVertex = 0;
fVertices = NULL;
- if (fSkPaint.getTextSize() <= kSmallDFFontLimit) {
- fTextRatio = fSkPaint.getTextSize()/kSmallDFFontSize;
+ if (textSize <= kSmallDFFontLimit) {
+ fTextRatio = textSize / kSmallDFFontSize;
fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
- } else if (fSkPaint.getTextSize() <= kMediumDFFontLimit) {
- fTextRatio = fSkPaint.getTextSize()/kMediumDFFontSize;
+ } else if (textSize <= kMediumDFFontLimit) {
+ fTextRatio = textSize / kMediumDFFontSize;
fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
} else {
- fTextRatio = fSkPaint.getTextSize()/kLargeDFFontSize;
+ fTextRatio = textSize / kLargeDFFontSize;
fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
}
diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h
index 75a13b385b..15ff6d9d78 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -31,6 +31,7 @@ public:
private:
GrTextStrike* fStrike;
+ SkMatrix fTextMatrix;
SkScalar fTextRatio;
bool fUseLCDText;
bool fEnableDFRendering;
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index ee7dd61387..b689c8f6a1 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -34,7 +34,11 @@ public:
GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
: INHERITED (factory)
- , fTextureSize(SkISize::Make(-1,-1)) {}
+ , fTextureSize(SkISize::Make(-1,-1))
+#ifdef SK_GAMMA_APPLY_TO_A8
+ , fLuminance(-1.0f)
+#endif
+ {}
virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,
@@ -262,7 +266,8 @@ public:
GrGLDistanceFieldLCDTextureEffect(const GrBackendEffectFactory& factory,
const GrDrawEffect& drawEffect)
: INHERITED (factory)
- , fTextureSize(SkISize::Make(-1,-1)) {}
+ , fTextureSize(SkISize::Make(-1,-1))
+ , fTextColor(GrColor_ILLEGAL) {}
virtual void emitCode(GrGLFullProgramBuilder* builder,
const GrDrawEffect& drawEffect,