Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
EmptyPathTest.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
12#include "include/core/SkPath.h"
17#include "tests/Test.h"
18
19#include <array>
20#include <cstddef>
21
22#define DIMENSION 32
23
25 const SkPaint& paint, bool shouldDraw) {
26 SkBitmap bm;
28 SkASSERT(DIMENSION*4 == bm.rowBytes()); // ensure no padding on each row
30
31 SkCanvas canvas(bm);
32 SkPaint p(paint);
33 p.setColor(SK_ColorWHITE);
34
35 canvas.drawPath(path, p);
36
37 size_t count = DIMENSION * DIMENSION;
38 const SkPMColor* ptr = bm.getAddr32(0, 0);
39
40 SkPMColor andValue = ~0U;
41 SkPMColor orValue = 0;
42 for (size_t i = 0; i < count; ++i) {
43 SkPMColor c = ptr[i];
44 andValue &= c;
45 orValue |= c;
46 }
47
48 // success means we drew everywhere or nowhere (depending on shouldDraw)
49 bool success = shouldDraw ? (~0U == andValue) : (0 == orValue);
50
51 if (!success) {
52 const char* str;
53 if (shouldDraw) {
54 str = "Path expected to draw everywhere, but didn't. ";
55 } else {
56 str = "Path expected to draw nowhere, but did. ";
57 }
58 ERRORF(reporter, "%s style[%d] cap[%d] join[%d] antialias[%d]"
59 " filltype[%d] ptcount[%d]", str, paint.getStyle(),
60 paint.getStrokeCap(), paint.getStrokeJoin(),
61 paint.isAntiAlias(), (int)path.getFillType(), path.countPoints());
62// uncomment this if you want to step in to see the failure
63// canvas.drawPath(path, p);
64 }
65}
66
71
72static void iter_paint(skiatest::Reporter* reporter, const SkPath& path, bool shouldDraw,
73 DrawCaps drawCaps) {
74 static const SkPaint::Cap gCaps[] = {
78 };
79 static const SkPaint::Join gJoins[] = {
83 };
84 static const SkPaint::Style gStyles[] = {
88 };
89 for (size_t cap = 0; cap < std::size(gCaps); ++cap) {
90 for (size_t join = 0; join < std::size(gJoins); ++join) {
91 for (size_t style = 0; style < std::size(gStyles); ++style) {
92 if (drawCaps && SkPaint::kButt_Cap != gCaps[cap]
93 && SkPaint::kFill_Style != gStyles[style]) {
94 continue;
95 }
96
98 paint.setStrokeWidth(SkIntToScalar(10));
99
100 paint.setStrokeCap(gCaps[cap]);
101 paint.setStrokeJoin(gJoins[join]);
102 paint.setStyle(gStyles[style]);
103
104 paint.setAntiAlias(false);
105 drawAndTest(reporter, path, paint, shouldDraw);
106 paint.setAntiAlias(true);
107 drawAndTest(reporter, path, paint, shouldDraw);
108 }
109 }
110 }
111}
112
113#define CX (SkIntToScalar(DIMENSION) / 2)
114#define CY (SkIntToScalar(DIMENSION) / 2)
115
116static void make_empty(SkPath*) {}
117static void make_M(SkPath* path) { path->moveTo(CX, CY); }
118static void make_MM(SkPath* path) { path->moveTo(CX, CY).moveTo(CX, CY); }
119static void make_MZM(SkPath* path) { path->moveTo(CX, CY).close().moveTo(CX, CY); }
120static void make_L(SkPath* path) { path->moveTo(CX, CY).lineTo(CX, CY); }
121static void make_Q(SkPath* path) { path->moveTo(CX, CY).quadTo(CX, CY, CX, CY); }
122static void make_C(SkPath* path) { path->moveTo(CX, CY).cubicTo(CX, CY, CX, CY, CX, CY); }
123
124/* Two invariants are tested: How does an empty/degenerate path draw?
125 * - if the path is drawn inverse, it should draw everywhere
126 * - if the path is drawn non-inverse, it should draw nowhere
127 *
128 * Things to iterate on:
129 * - path (empty, degenerate line/quad/cubic w/ and w/o close
130 * - paint style
131 * - path filltype
132 * - path stroke variants (e.g. caps, joins, width)
133 */
135 static void (*gMakeProc[])(SkPath*) = {
137 };
138 static SkPathFillType gFills[] = {
143 };
144 for (int doClose = 0; doClose < 2; ++doClose) {
145 for (size_t i = 0; i < std::size(gMakeProc); ++i) {
146 SkPath path;
147 gMakeProc[i](&path);
148 if (doClose) {
149 path.close();
150 }
151 /* zero length segments and close following moves draw round and square caps */
152 bool allowCaps = make_L == gMakeProc[i] || make_Q == gMakeProc[i]
153 || make_C == gMakeProc[i] || make_MZM == gMakeProc[i];
154 allowCaps |= SkToBool(doClose);
155 for (size_t fill = 0; fill < std::size(gFills); ++fill) {
156 path.setFillType(gFills[fill]);
157 bool shouldDraw = path.isInverseFillType();
158 iter_paint(reporter, path, shouldDraw, allowCaps ? kDrawCaps : kDontDrawCaps);
159 }
160 }
161 }
162}
163
#define CX
static void make_C(SkPath *path)
static void make_empty(SkPath *)
static void make_Q(SkPath *path)
static void make_L(SkPath *path)
static void iter_paint(skiatest::Reporter *reporter, const SkPath &path, bool shouldDraw, DrawCaps drawCaps)
static void test_emptydrawing(skiatest::Reporter *reporter)
#define DIMENSION
#define CY
DrawCaps
@ kDrawCaps
@ kDontDrawCaps
static void make_M(SkPath *path)
static void make_MM(SkPath *path)
static void make_MZM(SkPath *path)
static void drawAndTest(skiatest::Reporter *reporter, const SkPath &path, const SkPaint &paint, bool shouldDraw)
reporter
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr SkColor SK_ColorTRANSPARENT
Definition SkColor.h:99
uint32_t SkPMColor
Definition SkColor.h:205
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
SkPathFillType
Definition SkPathTypes.h:11
#define SkIntToScalar(x)
Definition SkScalar.h:57
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define ERRORF(r,...)
Definition Test.h:293
size_t rowBytes() const
Definition SkBitmap.h:238
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 drawPath(const SkPath &path, const SkPaint &paint)
@ kRound_Cap
adds circle
Definition SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
@ kSquare_Cap
adds square
Definition SkPaint.h:336
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition SkPaint.h:195
@ kRound_Join
adds circle
Definition SkPaint.h:360
@ kMiter_Join
extends to miter limit
Definition SkPaint.h:359
@ kBevel_Join
connects outside edges
Definition SkPaint.h:361
const Paint & paint
static constexpr SkFontStyle gStyles[]
Definition typeface.cpp:89