blob: 88fa58a755eb6ad034350ca796da1be0d0b36cba [file] [log] [blame]
bsalomon87cbcf32015-04-22 08:51:38 -07001/*
2 * Copyright 2015 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"
Mike Klein33d20552017-03-22 13:47:51 -04009#include "sk_tool_utils.h"
bsalomon87cbcf32015-04-22 08:51:38 -070010
11#include "SkShader.h"
12
13// This class of GMs test how edges/verts snap near rounding boundaries in device space without
14// anti-aliaing.
15class PixelSnapGM : public skiagm::GM {
16public:
17 PixelSnapGM() {}
18
19protected:
20 // kTrans should be even or checkboards wont agree in different test cases.
mtkleindbfd7ab2016-09-01 11:24:54 -070021 static constexpr int kTrans = 14;
22 static constexpr int kLabelPad = 4;
bsalomon87cbcf32015-04-22 08:51:38 -070023 // The inverse of this value should be a perfect SkScalar.
mtkleindbfd7ab2016-09-01 11:24:54 -070024 static constexpr int kSubPixelSteps = 8;
25 static constexpr int kLabelTextSize = 9;
bsalomon87cbcf32015-04-22 08:51:38 -070026
bungeman99fe8222015-08-20 07:57:51 -070027 static_assert(kSubPixelSteps < 99, "label_offset_too_small");
mtkleindbfd7ab2016-09-01 11:24:54 -070028 static constexpr int kLabelOffsetX = 2 * kLabelTextSize + kLabelPad;
29 static constexpr int kLabelOffsetY = kLabelTextSize + kLabelPad;
bsalomonc6534a22015-04-22 11:34:46 -070030
bsalomon87cbcf32015-04-22 08:51:38 -070031 SkISize onISize() override {
bsalomonc6534a22015-04-22 11:34:46 -070032 return SkISize::Make((kSubPixelSteps + 1) * kTrans + kLabelOffsetX + kLabelPad,
33 (kSubPixelSteps + 1) * kTrans + kLabelOffsetY + kLabelPad);
bsalomon87cbcf32015-04-22 08:51:38 -070034 }
35
36 void onDraw(SkCanvas* canvas) override {
37 SkPaint bgPaint;
38 bgPaint.setShader(
Mike Kleind46dce32018-08-16 10:17:03 -040039 sk_tool_utils::create_checkerboard_shader(0xFFAAAAAA, 0xFF777777, 1));
bsalomon87cbcf32015-04-22 08:51:38 -070040 canvas->drawPaint(bgPaint);
41
42 SkString offset;
43 SkPaint labelPaint;
44 labelPaint.setAntiAlias(true);
45 labelPaint.setColor(SK_ColorWHITE);
46 labelPaint.setTextSize(SkIntToScalar(kLabelTextSize));
caryclarkf597c422015-07-28 10:37:53 -070047 sk_tool_utils::set_portable_typeface(&labelPaint);
bsalomon87cbcf32015-04-22 08:51:38 -070048 SkPaint linePaint;
49 linePaint.setColor(SK_ColorWHITE);
50
caryclarkf597c422015-07-28 10:37:53 -070051 // Draw row labels
52 canvas->save();
53 canvas->translate(0, SkIntToScalar(kLabelOffsetY));
54 for (int i = 0; i <= kSubPixelSteps; ++i) {
55 offset.printf("%d", i);
Cary Clark2a475ea2017-04-28 15:35:12 -040056 canvas->drawString(offset,
caryclarkf597c422015-07-28 10:37:53 -070057 0, i * kTrans + labelPaint.getTextSize(),
58 labelPaint);
59 }
60 canvas->restore();
bsalomon87cbcf32015-04-22 08:51:38 -070061
caryclarkf597c422015-07-28 10:37:53 -070062 // Draw col labels
63 canvas->save();
64 canvas->translate(SkIntToScalar(kLabelOffsetX), 0);
65 for (int i = 0; i <= kSubPixelSteps; ++i) {
66 offset.printf("%d", i);
Cary Clark2a475ea2017-04-28 15:35:12 -040067 canvas->drawString(offset,
caryclarkf597c422015-07-28 10:37:53 -070068 i * SkIntToScalar(kTrans), labelPaint.getTextSize(),
69 labelPaint);
70 }
71 canvas->restore();
bsalomon87cbcf32015-04-22 08:51:38 -070072
bsalomonc6534a22015-04-22 11:34:46 -070073 canvas->translate(SkIntToScalar(kLabelOffsetX), SkIntToScalar(kLabelOffsetY));
bsalomon87cbcf32015-04-22 08:51:38 -070074
75 // Draw test case grid lines (Draw them all at pixel centers to hopefully avoid any
76 // snapping issues).
77 for (int i = 0; i <= kSubPixelSteps + 1; ++i) {
78 canvas->drawLine(0.5f,
79 i * SkIntToScalar(kTrans) + 0.5f,
80 SkIntToScalar(kTrans) * (kSubPixelSteps + 1) + 0.5f,
81 i * SkIntToScalar(kTrans) + 0.5f,
82 linePaint);
83 canvas->drawLine(i * SkIntToScalar(kTrans) + 0.5f,
84 0.5f,
85 i * SkIntToScalar(kTrans) + 0.5f,
86 SkIntToScalar(kTrans) * (kSubPixelSteps + 1) + 0.5f,
87 linePaint);
88 }
89
90 for (int i = 0; i <= kSubPixelSteps; ++i) {
91 for (int j = 0; j <= kSubPixelSteps; ++j) {
92 canvas->save();
93 // +1's account for the grid lines around each test case.
94 canvas->translate(j * (kTrans + 1.f/kSubPixelSteps) + 1,
95 i * (kTrans + 1.f/kSubPixelSteps) + 1);
96 this->drawElement(canvas);
97 canvas->restore();
98 }
99 }
100 }
101
102 virtual void drawElement(SkCanvas*) = 0;
103
104private:
105 typedef skiagm::GM INHERITED;
106};
107
108class PointSnapGM : public PixelSnapGM {
109protected:
110 SkString onShortName() override { return SkString("pixel_snap_point"); }
Mike Reed3661bc92017-02-22 13:21:42 -0500111 void drawElement(SkCanvas* canvas) override {
112 const SkPoint pt = { 1, 1 };
113 SkPaint paint;
114 paint.setColor(SK_ColorBLUE);
115 canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, &pt, paint);
116 }
bsalomon87cbcf32015-04-22 08:51:38 -0700117
118private:
119 typedef PixelSnapGM INHERITED;
120};
121
122class LineSnapGM : public PixelSnapGM {
123protected:
124 SkString onShortName() override { return SkString("pixel_snap_line"); }
125 void drawElement(SkCanvas* canvas) override {
126 SkPaint paint;
127 paint.setColor(SK_ColorGREEN);
128 // Draw a horizontal and vertical line, each length 3.
129 canvas->drawLine(1, 1, 4, 1, paint);
130 canvas->drawLine(6, 1, 6, 4, paint);
131 }
132
133private:
134 typedef PixelSnapGM INHERITED;
135};
136
137class RectSnapGM : public PixelSnapGM {
138protected:
139 SkString onShortName() override { return SkString("pixel_snap_rect"); }
140 void drawElement(SkCanvas* canvas) override {
141 SkPaint paint;
142 paint.setColor(SK_ColorRED);
143 canvas->drawRect(SkRect::MakeXYWH(1, 1, 3, 3), paint);
144 }
145
146private:
147 typedef PixelSnapGM INHERITED;
148};
149
150class ComboSnapGM : public PixelSnapGM {
151protected:
152 SkString onShortName() override { return SkString("pixel_snap_combo"); }
153 void drawElement(SkCanvas* canvas) override {
154 SkPaint paint;
155 paint.setAntiAlias(false);
156 // A rectangle that exactly covers a pixel, a point at each corner, 8 horiz/vert lines
157 // at rect corners (two at each corner, extending away from rect). They are drawn in this
158 // order lines (green), points (blue), rect(red).
159 SkRect rect = SkRect::MakeXYWH(3, 3, 1, 1);
160 paint.setColor(SK_ColorGREEN);
Mike Reed3661bc92017-02-22 13:21:42 -0500161 const SkPoint lines[] = {
162 { 3, 3 }, { 0, 3 },
163 { 3, 3 }, { 3, 0 },
164 { 4, 3 }, { 7, 3 },
165 { 4, 3 }, { 4, 0 },
166 { 3, 4 }, { 0, 4 },
167 { 3, 4 }, { 3, 7 },
168 { 4, 4 }, { 7, 4 },
169 { 4, 4 }, { 4, 7 },
170 };
171 canvas->drawPoints(SkCanvas::kLines_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
172
173 const SkPoint pts[] = {
174 { 4, 3 }, { 4, 4, }, { 3, 3 }, { 3, 4 },
175 };
176 paint.setColor(SK_ColorBLUE);
177 canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(pts), pts, paint);
178
bsalomon87cbcf32015-04-22 08:51:38 -0700179 paint.setColor(SK_ColorRED);
180 canvas->drawRect(rect, paint);
181 }
182
183private:
184 typedef PixelSnapGM INHERITED;
185};
186
187//////////////////////////////////////////////////////////////////////////////
halcanary385fe4d2015-08-26 13:07:48 -0700188DEF_GM(return new PointSnapGM;)
189DEF_GM(return new LineSnapGM;)
190DEF_GM(return new RectSnapGM;)
191DEF_GM(return new ComboSnapGM;)