blob: b1373b6e4b4e37996f1ef1324bb93602905a2c50 [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;
bsalomon87cbcf32015-04-22 08:51:38 -070044 labelPaint.setColor(SK_ColorWHITE);
Hal Canarydf2d27e2019-01-08 09:38:02 -050045 SkFont font(sk_tool_utils::create_portable_typeface(), SkIntToScalar(kLabelTextSize));
bsalomon87cbcf32015-04-22 08:51:38 -070046 SkPaint linePaint;
47 linePaint.setColor(SK_ColorWHITE);
48
caryclarkf597c422015-07-28 10:37:53 -070049 // Draw row labels
50 canvas->save();
51 canvas->translate(0, SkIntToScalar(kLabelOffsetY));
52 for (int i = 0; i <= kSubPixelSteps; ++i) {
53 offset.printf("%d", i);
Hal Canarydf2d27e2019-01-08 09:38:02 -050054 canvas->drawString(offset, 0, i * kTrans + SkIntToScalar(kLabelTextSize),
55 font, labelPaint);
caryclarkf597c422015-07-28 10:37:53 -070056 }
57 canvas->restore();
bsalomon87cbcf32015-04-22 08:51:38 -070058
caryclarkf597c422015-07-28 10:37:53 -070059 // Draw col labels
60 canvas->save();
61 canvas->translate(SkIntToScalar(kLabelOffsetX), 0);
62 for (int i = 0; i <= kSubPixelSteps; ++i) {
63 offset.printf("%d", i);
Hal Canarydf2d27e2019-01-08 09:38:02 -050064 canvas->drawString(offset, i * SkIntToScalar(kTrans), SkIntToScalar(kLabelTextSize),
65 font, labelPaint);
caryclarkf597c422015-07-28 10:37:53 -070066 }
67 canvas->restore();
bsalomon87cbcf32015-04-22 08:51:38 -070068
bsalomonc6534a22015-04-22 11:34:46 -070069 canvas->translate(SkIntToScalar(kLabelOffsetX), SkIntToScalar(kLabelOffsetY));
bsalomon87cbcf32015-04-22 08:51:38 -070070
71 // Draw test case grid lines (Draw them all at pixel centers to hopefully avoid any
72 // snapping issues).
73 for (int i = 0; i <= kSubPixelSteps + 1; ++i) {
74 canvas->drawLine(0.5f,
75 i * SkIntToScalar(kTrans) + 0.5f,
76 SkIntToScalar(kTrans) * (kSubPixelSteps + 1) + 0.5f,
77 i * SkIntToScalar(kTrans) + 0.5f,
78 linePaint);
79 canvas->drawLine(i * SkIntToScalar(kTrans) + 0.5f,
80 0.5f,
81 i * SkIntToScalar(kTrans) + 0.5f,
82 SkIntToScalar(kTrans) * (kSubPixelSteps + 1) + 0.5f,
83 linePaint);
84 }
85
86 for (int i = 0; i <= kSubPixelSteps; ++i) {
87 for (int j = 0; j <= kSubPixelSteps; ++j) {
88 canvas->save();
89 // +1's account for the grid lines around each test case.
90 canvas->translate(j * (kTrans + 1.f/kSubPixelSteps) + 1,
91 i * (kTrans + 1.f/kSubPixelSteps) + 1);
92 this->drawElement(canvas);
93 canvas->restore();
94 }
95 }
96 }
97
98 virtual void drawElement(SkCanvas*) = 0;
99
100private:
101 typedef skiagm::GM INHERITED;
102};
103
104class PointSnapGM : public PixelSnapGM {
105protected:
106 SkString onShortName() override { return SkString("pixel_snap_point"); }
Mike Reed3661bc92017-02-22 13:21:42 -0500107 void drawElement(SkCanvas* canvas) override {
108 const SkPoint pt = { 1, 1 };
109 SkPaint paint;
110 paint.setColor(SK_ColorBLUE);
111 canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, &pt, paint);
112 }
bsalomon87cbcf32015-04-22 08:51:38 -0700113
114private:
115 typedef PixelSnapGM INHERITED;
116};
117
118class LineSnapGM : public PixelSnapGM {
119protected:
120 SkString onShortName() override { return SkString("pixel_snap_line"); }
121 void drawElement(SkCanvas* canvas) override {
122 SkPaint paint;
123 paint.setColor(SK_ColorGREEN);
124 // Draw a horizontal and vertical line, each length 3.
125 canvas->drawLine(1, 1, 4, 1, paint);
126 canvas->drawLine(6, 1, 6, 4, paint);
127 }
128
129private:
130 typedef PixelSnapGM INHERITED;
131};
132
133class RectSnapGM : public PixelSnapGM {
134protected:
135 SkString onShortName() override { return SkString("pixel_snap_rect"); }
136 void drawElement(SkCanvas* canvas) override {
137 SkPaint paint;
138 paint.setColor(SK_ColorRED);
139 canvas->drawRect(SkRect::MakeXYWH(1, 1, 3, 3), paint);
140 }
141
142private:
143 typedef PixelSnapGM INHERITED;
144};
145
146class ComboSnapGM : public PixelSnapGM {
147protected:
148 SkString onShortName() override { return SkString("pixel_snap_combo"); }
149 void drawElement(SkCanvas* canvas) override {
150 SkPaint paint;
151 paint.setAntiAlias(false);
152 // A rectangle that exactly covers a pixel, a point at each corner, 8 horiz/vert lines
153 // at rect corners (two at each corner, extending away from rect). They are drawn in this
154 // order lines (green), points (blue), rect(red).
155 SkRect rect = SkRect::MakeXYWH(3, 3, 1, 1);
156 paint.setColor(SK_ColorGREEN);
Mike Reed3661bc92017-02-22 13:21:42 -0500157 const SkPoint lines[] = {
158 { 3, 3 }, { 0, 3 },
159 { 3, 3 }, { 3, 0 },
160 { 4, 3 }, { 7, 3 },
161 { 4, 3 }, { 4, 0 },
162 { 3, 4 }, { 0, 4 },
163 { 3, 4 }, { 3, 7 },
164 { 4, 4 }, { 7, 4 },
165 { 4, 4 }, { 4, 7 },
166 };
167 canvas->drawPoints(SkCanvas::kLines_PointMode, SK_ARRAY_COUNT(lines), lines, paint);
168
169 const SkPoint pts[] = {
170 { 4, 3 }, { 4, 4, }, { 3, 3 }, { 3, 4 },
171 };
172 paint.setColor(SK_ColorBLUE);
173 canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(pts), pts, paint);
174
bsalomon87cbcf32015-04-22 08:51:38 -0700175 paint.setColor(SK_ColorRED);
176 canvas->drawRect(rect, paint);
177 }
178
179private:
180 typedef PixelSnapGM INHERITED;
181};
182
183//////////////////////////////////////////////////////////////////////////////
halcanary385fe4d2015-08-26 13:07:48 -0700184DEF_GM(return new PointSnapGM;)
185DEF_GM(return new LineSnapGM;)
186DEF_GM(return new RectSnapGM;)
187DEF_GM(return new ComboSnapGM;)