Flutter Engine
The Flutter Engine
PathOpsTightBoundsTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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 */
11#include "include/core/SkPath.h"
12#include "include/core/SkRect.h"
15#include "src/base/SkRandom.h"
18#include "tests/Test.h"
19
20#include <algorithm>
21#include <cstdint>
22
24 SkRandom ran;
25 for (int index = 0; index < 1000; ++index) {
27 int contourCount = ran.nextRangeU(1, 10);
28 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
29 int lineCount = ran.nextRangeU(1, 10);
30 path.moveTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000));
31 for (int lIndex = 0; lIndex < lineCount; ++lIndex) {
32 path.lineTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000));
33 }
34 if (ran.nextBool()) {
35 path.close();
36 }
37 }
38 SkRect classicBounds = path.getBounds();
39 SkRect tightBounds;
40 REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds));
41 REPORTER_ASSERT(data->fReporter, classicBounds == tightBounds);
42 }
43}
44
45DEF_TEST(PathOpsTightBoundsLines, reporter) {
46 initializeTests(reporter, "tightBoundsLines");
48 int outerCount = reporter->allowExtendedTest() ? 100 : 1;
49 for (int index = 0; index < outerCount; ++index) {
50 for (int idx2 = 0; idx2 < 10; ++idx2) {
51 *testRunner.fRunnables.append() =
52 new PathOpsThreadedRunnable(&testTightBoundsLines, 0, 0, 0, 0, &testRunner);
53 }
54 }
55 testRunner.render();
56}
57
59 SkRandom ran;
60 const int bitWidth = 32;
61 const int bitHeight = 32;
62 const float pathMin = 1;
63 const float pathMax = (float) (bitHeight - 2);
64 SkBitmap& bits = *data->fBitmap;
65 if (bits.width() == 0) {
66 bits.allocN32Pixels(bitWidth, bitHeight);
67 }
68 SkCanvas canvas(bits);
70 for (int index = 0; index < 100; ++index) {
72 int contourCount = ran.nextRangeU(1, 10);
73 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
74 int lineCount = ran.nextRangeU(1, 10);
75 path.moveTo(ran.nextRangeF(1, pathMax), ran.nextRangeF(pathMin, pathMax));
76 for (int lIndex = 0; lIndex < lineCount; ++lIndex) {
77 if (ran.nextBool()) {
78 path.lineTo(ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax));
79 } else {
80 path.quadTo(ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax),
81 ran.nextRangeF(pathMin, pathMax), ran.nextRangeF(pathMin, pathMax));
82 }
83 }
84 if (ran.nextBool()) {
85 path.close();
86 }
87 }
88 SkRect classicBounds = path.getBounds();
89 SkRect tightBounds;
90 REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds));
91 REPORTER_ASSERT(data->fReporter, classicBounds.contains(tightBounds));
93 canvas.drawPath(path, paint);
94 SkIRect bitsWritten = {31, 31, 0, 0};
95 for (int y = 0; y < bitHeight; ++y) {
96 uint32_t* addr1 = data->fBitmap->getAddr32(0, y);
97 bool lineWritten = false;
98 for (int x = 0; x < bitWidth; ++x) {
99 if (addr1[x] == (uint32_t) -1) {
100 continue;
101 }
102 lineWritten = true;
103 bitsWritten.fLeft = std::min(bitsWritten.fLeft, x);
104 bitsWritten.fRight = std::max(bitsWritten.fRight, x);
105 }
106 if (!lineWritten) {
107 continue;
108 }
109 bitsWritten.fTop = std::min(bitsWritten.fTop, y);
110 bitsWritten.fBottom = std::max(bitsWritten.fBottom, y);
111 }
112 if (!bitsWritten.isEmpty()) {
113 SkIRect tightOut;
114 tightBounds.roundOut(&tightOut);
115 REPORTER_ASSERT(data->fReporter, tightOut.contains(bitsWritten));
116 }
117 }
118}
119
120DEF_TEST(PathOpsTightBoundsQuads, reporter) {
121 initializeTests(reporter, "tightBoundsQuads");
123 int outerCount = reporter->allowExtendedTest() ? 100 : 1;
124 for (int index = 0; index < outerCount; ++index) {
125 for (int idx2 = 0; idx2 < 10; ++idx2) {
126 *testRunner.fRunnables.append() =
127 new PathOpsThreadedRunnable(&testTightBoundsQuads, 0, 0, 0, 0, &testRunner);
128 }
129 }
130 testRunner.render();
131}
132
133DEF_TEST(PathOpsTightBoundsMove, reporter) {
134 SkPath path;
135 path.moveTo(10, 10);
136 path.close();
137 path.moveTo(20, 20);
138 path.lineTo(20, 20);
139 path.close();
140 path.moveTo(15, 15);
141 path.lineTo(15, 15);
142 path.close();
143 const SkRect& bounds = path.getBounds();
144 SkRect tight;
147}
148
149DEF_TEST(PathOpsTightBoundsMoveOne, reporter) {
150 SkPath path;
151 path.moveTo(20, 20);
152 const SkRect& bounds = path.getBounds();
153 SkRect tight;
156}
157
158DEF_TEST(PathOpsTightBoundsMoveTwo, reporter) {
159 SkPath path;
160 path.moveTo(20, 20);
161 path.moveTo(40, 40);
162 const SkRect& bounds = path.getBounds();
163 SkRect tight;
166}
167
168DEF_TEST(PathOpsTightBoundsTiny, reporter) {
169 SkPath path;
170 path.moveTo(1, 1);
171 path.quadTo(1.000001f, 1, 1, 1);
172 const SkRect& bounds = path.getBounds();
173 SkRect tight;
175 SkRect moveBounds = {1, 1, 1, 1};
177 REPORTER_ASSERT(reporter, moveBounds == tight);
178}
179
180DEF_TEST(PathOpsTightBoundsWellBehaved, reporter) {
181 SkPath path;
182 path.moveTo(1, 1);
183 path.quadTo(2, 3, 4, 5);
184 const SkRect& bounds = path.getBounds();
185 SkRect tight;
188}
189
190DEF_TEST(PathOpsTightBoundsIllBehaved, reporter) {
191 SkPath path;
192 path.moveTo(1, 1);
193 path.quadTo(4, 3, 2, 2);
194 const SkRect& bounds = path.getBounds();
195 SkRect tight;
198}
199
200DEF_TEST(PathOpsTightBoundsIllBehavedScaled, reporter) {
201 SkPath path;
202 path.moveTo(0, 0);
203 path.quadTo(1048578, 1048577, 1048576, 1048576);
204 const SkRect& bounds = path.getBounds();
205 SkRect tight;
208 REPORTER_ASSERT(reporter, tight.right() == 1048576);
209 REPORTER_ASSERT(reporter, tight.bottom() == 1048576);
210}
reporter
Definition: FontMgrTest.cpp:39
void initializeTests(skiatest::Reporter *reporter, const char *test)
static void testTightBoundsQuads(PathOpsThreadState *data)
static void testTightBoundsLines(PathOpsThreadState *data)
DEF_TEST(PathOpsTightBoundsLines, reporter)
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
bool SK_API TightBounds(const SkPath &path, SkRect *result)
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
SkTDArray< PathOpsThreadedRunnable * > fRunnables
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
Definition: SkPath.h:59
bool nextBool()
Definition: SkRandom.h:117
float nextRangeF(float min, float max)
Definition: SkRandom.h:64
uint32_t nextRangeU(uint32_t min, uint32_t max)
Definition: SkRandom.h:80
T * append()
Definition: SkTDArray.h:191
const Paint & paint
Definition: color_source.cc:38
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
double y
double x
Optional< SkRect > bounds
Definition: SkRecords.h:189
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
Definition: SkRect.h:32
int32_t fBottom
larger y-axis bounds
Definition: SkRect.h:36
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
bool isEmpty() const
Definition: SkRect.h:202
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
bool contains(int32_t x, int32_t y) const
Definition: SkRect.h:463
int32_t fRight
larger x-axis bounds
Definition: SkRect.h:35
bool contains(SkScalar x, SkScalar y) const
Definition: extension.cpp:19
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
constexpr float right() const
Definition: SkRect.h:748
constexpr float bottom() const
Definition: SkRect.h:755
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63