Flutter Engine
The Flutter Engine
ClipperTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 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
13#include "include/core/SkRect.h"
19#include "tests/Test.h"
20
21#include <array>
22#include <cstring>
23
25 SkBitmap bm;
26 bm.allocN32Pixels(4, 4);
28
30 paint.setAntiAlias(true);
31
32 SkCanvas canvas(bm);
34 canvas.drawLine(1.5f, 1.5f,
35 3.5f, 3.5f, paint);
36
37 /**
38 * We had a bug where we misinterpreted the bottom of the clip, and
39 * would draw another pixel (to the right in this case) on the same
40 * last scanline. i.e. we would draw to [2,1], even though this hairline
41 * should just draw to [1,1], [2,2], [3,3] modulo the clip.
42 *
43 * The result of this entire draw should be that we only draw to [1,1]
44 *
45 * Fixed in rev. 3366
46 */
47 for (int y = 0; y < 4; ++y) {
48 for (int x = 0; x < 4; ++x) {
49 bool nonWhite = (1 == y) && (1 == x);
50 SkPMColor c = *bm.getAddr32(x, y);
51 if (nonWhite) {
52 REPORTER_ASSERT(reporter, 0xFFFFFFFF != c);
53 } else {
54 REPORTER_ASSERT(reporter, 0xFFFFFFFF == c);
55 }
56 }
57 }
58}
59
60static void test_edgeclipper() {
61 SkEdgeClipper clipper(false);
62
63 const SkPoint pts[] = {
64 { 3.0995476e+010f, 42.929779f },
65 { -3.0995163e+010f, 51.050385f },
66 { -3.0995157e+010f, 51.050392f },
67 { -3.0995134e+010f, 51.050400f },
68 };
69
70 const SkRect clip = { 0, 0, SkIntToScalar(300), SkIntToScalar(200) };
71
72 // this should not assert, even though our choppers do a poor numerical
73 // job when computing their t values.
74 // http://code.google.com/p/skia/issues/detail?id=444
75 clipper.clipCubic(pts, clip);
76}
77
79 static const SkScalar L = 0;
80 static const SkScalar T = 0;
81 static const SkScalar R = SkIntToScalar(100);
82 static const SkScalar B = SkIntToScalar(100);
83 static const SkScalar CX = SkScalarHalf(L + R);
84 static const SkScalar CY = SkScalarHalf(T + B);
85 static const SkRect gR = { L, T, R, B };
86
87 size_t i;
88 SkPoint dst[2];
89
90 static const SkPoint gEmpty[] = {
91 // sides
92 { L, CY }, { L - 10, CY },
93 { R, CY }, { R + 10, CY },
94 { CX, T }, { CX, T - 10 },
95 { CX, B }, { CX, B + 10 },
96 // corners
97 { L, T }, { L - 10, T - 10 },
98 { L, B }, { L - 10, B + 10 },
99 { R, T }, { R + 10, T - 10 },
100 { R, B }, { R + 10, B + 10 },
101 };
102 for (i = 0; i < std::size(gEmpty); i += 2) {
103 bool valid = SkLineClipper::IntersectLine(&gEmpty[i], gR, dst);
104 if (valid) {
105 SkDebugf("----- [%zu] %g %g -> %g %g\n",
106 i/2, dst[0].fX, dst[0].fY, dst[1].fX, dst[1].fY);
107 }
108 REPORTER_ASSERT(reporter, !valid);
109 }
110
111 static const SkPoint gFull[] = {
112 // diagonals, chords
113 { L, T }, { R, B },
114 { L, B }, { R, T },
115 { CX, T }, { CX, B },
116 { L, CY }, { R, CY },
117 { CX, T }, { R, CY },
118 { CX, T }, { L, CY },
119 { L, CY }, { CX, B },
120 { R, CY }, { CX, B },
121 // edges
122 { L, T }, { L, B },
123 { R, T }, { R, B },
124 { L, T }, { R, T },
125 { L, B }, { R, B },
126 };
127 for (i = 0; i < std::size(gFull); i += 2) {
128 bool valid = SkLineClipper::IntersectLine(&gFull[i], gR, dst);
129 if (!valid || 0 != memcmp(&gFull[i], dst, sizeof(dst))) {
130 SkDebugf("++++ [%zu] %g %g -> %g %g\n",
131 i/2, dst[0].fX, dst[0].fY, dst[1].fX, dst[1].fY);
132 }
133 REPORTER_ASSERT(reporter, valid && !memcmp(&gFull[i], dst, sizeof(dst)));
134 }
135
136 static const SkPoint gPartial[] = {
137 { L - 10, CY }, { CX, CY }, { L, CY }, { CX, CY },
138 { CX, T - 10 }, { CX, CY }, { CX, T }, { CX, CY },
139 { R + 10, CY }, { CX, CY }, { R, CY }, { CX, CY },
140 { CX, B + 10 }, { CX, CY }, { CX, B }, { CX, CY },
141 // extended edges
142 { L, T - 10 }, { L, B + 10 }, { L, T }, { L, B },
143 { R, T - 10 }, { R, B + 10 }, { R, T }, { R, B },
144 { L - 10, T }, { R + 10, T }, { L, T }, { R, T },
145 { L - 10, B }, { R + 10, B }, { L, B }, { R, B },
146 };
147 for (i = 0; i < std::size(gPartial); i += 4) {
148 bool valid = SkLineClipper::IntersectLine(&gPartial[i], gR, dst);
149 if (!valid || 0 != memcmp(&gPartial[i+2], dst, sizeof(dst))) {
150 SkDebugf("++++ [%zu] %g %g -> %g %g\n",
151 i/2, dst[0].fX, dst[0].fY, dst[1].fX, dst[1].fY);
152 }
153 REPORTER_ASSERT(reporter, valid &&
154 !memcmp(&gPartial[i+2], dst, sizeof(dst)));
155 }
156
157}
158
163}
164
165DEF_TEST(LineClipper_skbug_7981, r) {
166 SkPoint src[] = {{ -5.77698802E+17f, -1.81758057E+23f}, {38127, 2}};
167 SkPoint dst[2];
168 SkRect clip = { -32767, -32767, 32767, 32767 };
169
171}
172
DEF_TEST(Clipper, reporter)
static void test_edgeclipper()
Definition: ClipperTest.cpp:60
static void test_hairclipping(skiatest::Reporter *reporter)
Definition: ClipperTest.cpp:24
static void test_intersectline(skiatest::Reporter *reporter)
Definition: ClipperTest.cpp:78
#define CX
#define CY
reporter
Definition: FontMgrTest.cpp:39
uint32_t SkPMColor
Definition: SkColor.h:205
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPathRef * gEmpty
Definition: SkPathRef.cpp:75
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
#define SkScalarHalf(a)
Definition: SkScalar.h:75
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
uint32_t * getAddr32(int x, int y) const
Definition: SkBitmap.h:1260
void eraseColor(SkColor4f) const
Definition: SkBitmap.cpp:442
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
bool clipCubic(const SkPoint pts[4], const SkRect &clip)
static bool IntersectLine(const SkPoint src[2], const SkRect &clip, SkPoint dst[2])
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
#define R(r)
double y
double x
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
#define T
Definition: precompiler.cc:65
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609