diff options
-rwxr-xr-x | gm/dftext.cpp | 165 | ||||
-rw-r--r-- | gm/fontscaler.cpp | 2 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 31 | ||||
-rw-r--r-- | src/gpu/GrDistanceFieldTextContext.h | 1 | ||||
-rwxr-xr-x | src/gpu/effects/GrDistanceFieldTextureEffect.cpp | 9 |
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, |