diff options
author | rmistry <rmistry@google.com> | 2014-06-23 06:59:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-06-23 06:59:15 -0700 |
commit | c4b84aef1adeb68bc853f35abb85b79fa1fcaac6 (patch) | |
tree | 54b63d339f397610f8bde7efb17c10ce3acbbbe5 /gm/glyph_pos.cpp | |
parent | 05ead8afe5e4db21f9004334ac339bdad48d5057 (diff) |
Revert of Revert of Fix SkPaint::measureText for stroked hairline text (https://codereview.chromium.org/354433002/)
Reason for revert:
Rebaseline CL is ready to be submitted
Original issue's description:
> Revert of Fix SkPaint::measureText for stroked hairline text (https://codereview.chromium.org/335603003/)
>
> Reason for revert:
> Caused many shadertext GM failures
>
> Original issue's description:
> > Fix SkPaint::measureText for stroked hairline text
> >
> > SkPaint::measureText and text drawing used different criteria for
> > determining whether text should be drawn as paths or not.
> >
> > Adds tests glyph_pos_(h/n)_(s/f/b) to test the text rendering and the glyph
> > positioning in the rendering. Mainly added in order to define what is the
> > expected text rendering when hairline stroke is used with various transform
> > options.
> >
> > The testcase also tries to note or highlight the fact that SkPaint::measureText
> > is not expected to produce intuitively matching results when compared to a
> > rendering, if the rendering is done so that the device ends up having a device
> > transform.
> >
> > This fixes the glyph_pos_h_s (hairline, stroked) test-case.
> >
> > Ignore shadertext2_pdf-poppler.png gm on
> > Test-Ubuntu13.10-ShuttleA-NoGPU-x86_64-Debug temporarily, as that fails.
> >
> > Committed: https://skia.googlesource.com/skia/+/196af738027c5e18c3eb792dbcaf90ef27821793
>
> TBR=jvanverth@google.com,reed@google.com,kkinnunen@nvidia.com
> NOTREECHECKS=true
> NOTRY=true
>
> Committed: https://skia.googlesource.com/skia/+/abc9bb55ddfeb4b1a7acc335a34841fddcd22d27
R=jvanverth@google.com, reed@google.com, kkinnunen@nvidia.com
TBR=jvanverth@google.com, kkinnunen@nvidia.com, reed@google.com
NOTREECHECKS=true
NOTRY=true
Author: rmistry@google.com
Review URL: https://codereview.chromium.org/349153005
Diffstat (limited to 'gm/glyph_pos.cpp')
-rw-r--r-- | gm/glyph_pos.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/gm/glyph_pos.cpp b/gm/glyph_pos.cpp new file mode 100644 index 0000000000..b0451016ac --- /dev/null +++ b/gm/glyph_pos.cpp @@ -0,0 +1,204 @@ +/* + * 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 "gm.h" +#include "SkCanvas.h" +#include "SkTypeface.h" + +/* This test tries to define the effect of using hairline strokes on text. + * Provides non-hairline images for reference and consistency checks. + * glyph_pos_(h/n)_(s/f/b) + * -> test hairline/non-hairline stroke/fill/stroke+fill. + */ +static const SkScalar kTextHeight = 14.0f; +static const char kText[] = "Proportional Hamburgefons #% fi"; + +namespace skiagm { + +class GlyphPosGM : public GM { +public: + GlyphPosGM(SkScalar strokeWidth, SkPaint::Style strokeStyle) + : fStrokeWidth(strokeWidth) + , fStrokeStyle(strokeStyle) { + } + +protected: + virtual uint32_t onGetFlags() const SK_OVERRIDE { + return kSkipTiled_Flag; + } + + virtual SkString onShortName() SK_OVERRIDE { + SkString str("glyph_pos"); + if (fStrokeWidth == 0.0f) { + str.append("_h"); // h == Hairline. + } else { + str.append("_n"); // n == Normal. + } + if (fStrokeStyle == SkPaint::kStroke_Style) { + str.append("_s"); + } else if (fStrokeStyle == SkPaint::kFill_Style) { + str.append("_f"); + } else { + str.append("_b"); // b == Both. + } + return str; + } + + virtual SkISize onISize() { return SkISize::Make(800, 600); } + + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { + if (!fProp) { + fProp.reset(SkTypeface::CreateFromName("Helvetica", SkTypeface::kNormal)); + } + + // There's a black pixel at 40, 40 for reference. + canvas->drawPoint(40.0f, 40.0f, SK_ColorBLACK); + + // Two reference images. + canvas->translate(50.0f, 50.0f); + drawTestCase(canvas, 1.0f); + + canvas->translate(0.0f, 50.0f); + drawTestCase(canvas, 3.0f); + + // Uniform scaling test. + canvas->translate(0.0f, 100.0f); + canvas->save(); + canvas->scale(3.0f, 3.0f); + drawTestCase(canvas, 1.0f); + canvas->restore(); + + // Non-uniform scaling test. + canvas->translate(0.0f, 100.0f); + canvas->save(); + canvas->scale(3.0f, 6.0f); + drawTestCase(canvas, 1.0f); + canvas->restore(); + + // Skew test. + canvas->translate(0.0f, 80.0f); + canvas->save(); + canvas->scale(3.0f, 3.0f); + SkMatrix skew; + skew.setIdentity(); + skew.setSkewX(SkScalarDiv(8.0f, + 25.0f)); + skew.setSkewY(SkScalarDiv(2.0f, + 25.0f)); + canvas->concat(skew); + drawTestCase(canvas, 1.0f); + canvas->restore(); + + // Perspective test. + canvas->translate(0.0f, 80.0f); + canvas->save(); + SkMatrix perspective; + perspective.setIdentity(); + perspective.setPerspX(-SkScalarDiv(SK_Scalar1, 340.0f)); + perspective.setSkewX(SkScalarDiv(8.0f, + 25.0f)); + perspective.setSkewY(SkScalarDiv(2.0f, + 25.0f)); + + + canvas->concat(perspective); + drawTestCase(canvas, 1.0f); + canvas->restore(); + } + + void drawTestCase(SkCanvas* canvas, SkScalar textScale) { + SkPaint paint; + paint.setColor(SK_ColorBLACK); + paint.setAntiAlias(true); + paint.setTextSize(kTextHeight * textScale); + paint.setTypeface(fProp); + paint.setDevKernText(true); + paint.setStrokeWidth(fStrokeWidth); + paint.setStyle(fStrokeStyle); + + // This demonstrates that we can not measure the text if there's a device transform. The + // canvas total matrix will end up being a device transform. + bool drawRef = !(canvas->getTotalMatrix().getType() & + ~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask)); + + SkRect bounds; + if (drawRef) { + SkScalar advance = paint.measureText(kText, sizeof(kText) - 1, &bounds); + + paint.setStrokeWidth(0.0f); + paint.setStyle(SkPaint::kStroke_Style); + + // Green box is the measured text bounds. + paint.setColor(SK_ColorGREEN); + canvas->drawRect(bounds, paint); + + // Red line is the measured advance from the 0,0 of the text position. + paint.setColor(SK_ColorRED); + canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint); + } + + // Black text is the testcase, eg. the text. + paint.setColor(SK_ColorBLACK); + paint.setStrokeWidth(fStrokeWidth); + paint.setStyle(fStrokeStyle); + canvas->drawText(kText, sizeof(kText) - 1, 0.0f, 0.0f, paint); + + if (drawRef) { + SkScalar widths[sizeof(kText) - 1]; + paint.getTextWidths(kText, sizeof(kText) - 1, widths, NULL); + + paint.setStrokeWidth(0.0f); + paint.setStyle(SkPaint::kStroke_Style); + + // Magenta lines are the positions for the characters. + paint.setColor(SK_ColorMAGENTA); + SkScalar w = bounds.x(); + for (size_t i = 0; i < sizeof(kText) - 1; ++i) { + canvas->drawLine(w, 0.0f, w, 5.0f, paint); + w += widths[i]; + } + } + } + +private: + SkAutoTUnref<SkTypeface> fProp; + SkScalar fStrokeWidth; + SkPaint::Style fStrokeStyle; + + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* GlyphPosHairlineStrokeAndFillFactory(void*) { + return new GlyphPosGM(0.0f, SkPaint::kStrokeAndFill_Style); +} +static GM* GlyphPosStrokeAndFillFactory(void*) { + return new GlyphPosGM(1.2f, SkPaint::kStrokeAndFill_Style); +} +static GM* GlyphPosHairlineStrokeFactory(void*) { + return new GlyphPosGM(0.0f, SkPaint::kStroke_Style); +} +static GM* GlyphPosStrokeFactory(void*) { + return new GlyphPosGM(1.2f, SkPaint::kStroke_Style); +} +static GM* GlyphPosHairlineFillFactory(void*) { + return new GlyphPosGM(0.0f, SkPaint::kFill_Style); +} +static GM* GlyphPosFillFactory(void*) { + return new GlyphPosGM(1.2f, SkPaint::kFill_Style); +} + +static GMRegistry reg1(GlyphPosHairlineStrokeAndFillFactory); +static GMRegistry reg2(GlyphPosStrokeAndFillFactory); +static GMRegistry reg3(GlyphPosHairlineStrokeFactory); +static GMRegistry reg4(GlyphPosStrokeFactory); +static GMRegistry reg5(GlyphPosHairlineFillFactory); +static GMRegistry reg6(GlyphPosFillFactory); + + +} |