blob: 7628fbe2983eeedcf879e5f803820c9251257c34 [file] [log] [blame]
rmistryc4b84ae2014-06-23 06:59:15 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkTypeface.h"
11
12/* This test tries to define the effect of using hairline strokes on text.
13 * Provides non-hairline images for reference and consistency checks.
14 * glyph_pos_(h/n)_(s/f/b)
15 * -> test hairline/non-hairline stroke/fill/stroke+fill.
16 */
mtkleindbfd7ab2016-09-01 11:24:54 -070017constexpr SkScalar kTextHeight = 14.0f;
18constexpr char kText[] = "Proportional Hamburgefons #% fi";
rmistryc4b84ae2014-06-23 06:59:15 -070019
halcanary2a243382015-09-09 08:16:41 -070020static void drawTestCase(SkCanvas* canvas,
21 SkScalar textScale,
22 SkScalar strokeWidth,
23 SkPaint::Style strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070024
halcanary2a243382015-09-09 08:16:41 -070025static void draw_gm(SkCanvas* canvas,
26 SkScalar strokeWidth,
27 SkPaint::Style strokeStyle) {
rmistryc4b84ae2014-06-23 06:59:15 -070028 // There's a black pixel at 40, 40 for reference.
29 canvas->drawPoint(40.0f, 40.0f, SK_ColorBLACK);
30
31 // Two reference images.
32 canvas->translate(50.0f, 50.0f);
halcanary2a243382015-09-09 08:16:41 -070033 drawTestCase(canvas, 1.0f, strokeWidth, strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070034
35 canvas->translate(0.0f, 50.0f);
halcanary2a243382015-09-09 08:16:41 -070036 drawTestCase(canvas, 3.0f, strokeWidth, strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070037
38 // Uniform scaling test.
39 canvas->translate(0.0f, 100.0f);
40 canvas->save();
41 canvas->scale(3.0f, 3.0f);
halcanary2a243382015-09-09 08:16:41 -070042 drawTestCase(canvas, 1.0f, strokeWidth, strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070043 canvas->restore();
44
45 // Non-uniform scaling test.
46 canvas->translate(0.0f, 100.0f);
47 canvas->save();
48 canvas->scale(3.0f, 6.0f);
halcanary2a243382015-09-09 08:16:41 -070049 drawTestCase(canvas, 1.0f, strokeWidth, strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070050 canvas->restore();
51
52 // Skew test.
53 canvas->translate(0.0f, 80.0f);
54 canvas->save();
55 canvas->scale(3.0f, 3.0f);
56 SkMatrix skew;
57 skew.setIdentity();
reed80ea19c2015-05-12 10:37:34 -070058 skew.setSkewX(8.0f / 25.0f);
59 skew.setSkewY(2.0f / 25.0f);
rmistryc4b84ae2014-06-23 06:59:15 -070060 canvas->concat(skew);
halcanary2a243382015-09-09 08:16:41 -070061 drawTestCase(canvas, 1.0f, strokeWidth, strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070062 canvas->restore();
63
64 // Perspective test.
65 canvas->translate(0.0f, 80.0f);
66 canvas->save();
67 SkMatrix perspective;
68 perspective.setIdentity();
reed80ea19c2015-05-12 10:37:34 -070069 perspective.setPerspX(-SkScalarInvert(340));
70 perspective.setSkewX(8.0f / 25.0f);
71 perspective.setSkewY(2.0f / 25.0f);
rmistryc4b84ae2014-06-23 06:59:15 -070072
rmistryc4b84ae2014-06-23 06:59:15 -070073 canvas->concat(perspective);
halcanary2a243382015-09-09 08:16:41 -070074 drawTestCase(canvas, 1.0f, strokeWidth, strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070075 canvas->restore();
halcanary2a243382015-09-09 08:16:41 -070076}
rmistryc4b84ae2014-06-23 06:59:15 -070077
halcanary2a243382015-09-09 08:16:41 -070078static void drawTestCase(SkCanvas* canvas,
79 SkScalar textScale,
80 SkScalar strokeWidth,
81 SkPaint::Style strokeStyle) {
rmistryc4b84ae2014-06-23 06:59:15 -070082 SkPaint paint;
83 paint.setColor(SK_ColorBLACK);
84 paint.setAntiAlias(true);
85 paint.setTextSize(kTextHeight * textScale);
caryclark1818acb2015-07-24 12:09:25 -070086 sk_tool_utils::set_portable_typeface(&paint);
halcanary2a243382015-09-09 08:16:41 -070087 paint.setStrokeWidth(strokeWidth);
88 paint.setStyle(strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -070089
halcanary2a243382015-09-09 08:16:41 -070090 // This demonstrates that we can not measure the text if
91 // there's a device transform. The canvas total matrix will
92 // end up being a device transform.
rmistryc4b84ae2014-06-23 06:59:15 -070093 bool drawRef = !(canvas->getTotalMatrix().getType() &
94 ~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask));
95
96 SkRect bounds;
97 if (drawRef) {
98 SkScalar advance = paint.measureText(kText, sizeof(kText) - 1, &bounds);
99
100 paint.setStrokeWidth(0.0f);
101 paint.setStyle(SkPaint::kStroke_Style);
102
103 // Green box is the measured text bounds.
104 paint.setColor(SK_ColorGREEN);
105 canvas->drawRect(bounds, paint);
106
107 // Red line is the measured advance from the 0,0 of the text position.
108 paint.setColor(SK_ColorRED);
109 canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint);
110 }
111
112 // Black text is the testcase, eg. the text.
113 paint.setColor(SK_ColorBLACK);
halcanary2a243382015-09-09 08:16:41 -0700114 paint.setStrokeWidth(strokeWidth);
115 paint.setStyle(strokeStyle);
rmistryc4b84ae2014-06-23 06:59:15 -0700116 canvas->drawText(kText, sizeof(kText) - 1, 0.0f, 0.0f, paint);
117
118 if (drawRef) {
119 SkScalar widths[sizeof(kText) - 1];
halcanary96fcdcc2015-08-27 07:41:13 -0700120 paint.getTextWidths(kText, sizeof(kText) - 1, widths, nullptr);
rmistryc4b84ae2014-06-23 06:59:15 -0700121
122 paint.setStrokeWidth(0.0f);
123 paint.setStyle(SkPaint::kStroke_Style);
124
125 // Magenta lines are the positions for the characters.
126 paint.setColor(SK_ColorMAGENTA);
127 SkScalar w = bounds.x();
128 for (size_t i = 0; i < sizeof(kText) - 1; ++i) {
129 canvas->drawLine(w, 0.0f, w, 5.0f, paint);
130 w += widths[i];
131 }
132 }
rmistryc4b84ae2014-06-23 06:59:15 -0700133}
134
halcanary2a243382015-09-09 08:16:41 -0700135DEF_SIMPLE_GM(glyph_pos_h_b, c, 800, 600) {
136 draw_gm(c, 0.0f, SkPaint::kStrokeAndFill_Style);
137}
138DEF_SIMPLE_GM(glyph_pos_n_b, c, 800, 600) {
139 draw_gm(c, 1.2f, SkPaint::kStrokeAndFill_Style);
140}
141DEF_SIMPLE_GM(glyph_pos_h_s, c, 800, 600) {
142 draw_gm(c, 0.0f, SkPaint::kStroke_Style);
143}
144DEF_SIMPLE_GM(glyph_pos_n_s, c, 800, 600) {
145 draw_gm(c, 1.2f, SkPaint::kStroke_Style);
146}
147DEF_SIMPLE_GM(glyph_pos_h_f, c, 800, 600) {
148 draw_gm(c, 0.0f, SkPaint::kFill_Style);
149}
150DEF_SIMPLE_GM(glyph_pos_n_f, c, 800, 600) {
151 draw_gm(c, 1.2f, SkPaint::kFill_Style);
rmistryc4b84ae2014-06-23 06:59:15 -0700152}