Flutter Engine
The Flutter Engine
overstroke.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 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
9/*
10 * This GM exercises stroking of paths with large stroke lengths, which is
11 * referred to as "overstroke" for brevity. In Skia as of 8/2016 we offset
12 * each part of the curve the request amount even if it makes the offsets
13 * overlap and create holes. There is not a really great algorithm for this
14 * and several other 2D graphics engines have the same bug.
15 *
16 * The old Nvidia Path Renderer used to yield correct results, so a possible
17 * direction of attack is to use the GPU and a completely different algorithm.
18 *
19 * See crbug.com/589769 skbug.com/5405 skbug.com/5406
20 */
21
22#include "gm/gm.h"
30#include "include/core/SkRect.h"
33
34#include <cstddef>
35
38
39//////// path and paint builders
40
42 SkPaint p;
43 p.setAntiAlias(true);
44 p.setStyle(SkPaint::kStroke_Style);
45 p.setStrokeWidth(NORMALSTROKE_WIDTH);
46 p.setColor(SK_ColorBLUE);
47
48 return p;
49}
50
52 SkPaint p;
53 p.setAntiAlias(true);
54 p.setStyle(SkPaint::kStroke_Style);
55 p.setStrokeWidth(OVERSTROKE_WIDTH);
56
57 return p;
58}
59
61 return SkPathBuilder().moveTo(0, 0)
62 .lineTo(100, 0)
63 .quadTo(50, -40, 0, 0)
64 .close()
65 .detach();
66}
67
70 path.moveTo(0, 0);
71 path.cubicTo(25, 75,
72 75, -50,
73 100, 0);
74
75 return path;
76}
77
79 SkRect oval = SkRect::MakeXYWH(0, -25, 100, 50);
80
81 return SkPathBuilder().arcTo(oval, 0, 359, true).close().detach();
82}
83
85 SkPath ribs;
86
87 const SkScalar spacing = 5.0f;
88 float accum = 0.0f;
89
90 SkPathMeasure meas(path, false);
91 SkScalar length = meas.getLength();
93 SkVector tan;
94 while (accum < length) {
95 if (meas.getPosTan(accum, &pos, &tan)) {
96 tan.scale(radius);
98
99 ribs.moveTo(pos.x() + tan.x(), pos.y() + tan.y());
100 ribs.lineTo(pos.x() - tan.x(), pos.y() - tan.y());
101 }
102 accum += spacing;
103 }
104
105 return ribs;
106}
107
111 p.setStrokeWidth(1);
112 p.setColor(SK_ColorBLUE);
113 p.setColor(SK_ColorGREEN);
114
115 canvas->drawPath(ribs, p);
116}
117
118///////// quads
119
121 // scaled so it's visible
122 // canvas->scale(8, 8);
123
126
127 draw_ribs(canvas, path);
128 canvas->drawPath(path, p);
129}
130
134
135 canvas->drawPath(path, p);
136 draw_ribs(canvas, path);
137}
138
142
143 SkPaint fillp = make_normal_paint();
145
146 SkPath fillpath;
148
149 canvas->drawPath(fillpath, fillp);
150}
151
153 canvas->translate(400, 0);
154 draw_large_quad(canvas);
155 draw_quad_fillpath(canvas);
156}
157
158////////// cubics
159
163
164 draw_ribs(canvas, path);
165 canvas->drawPath(path, p);
166}
167
171
172 canvas->drawPath(path, p);
173 draw_ribs(canvas, path);
174}
175
179
180 SkPaint fillp = make_normal_paint();
182
183 SkPath fillpath;
185
186 canvas->drawPath(fillpath, fillp);
187}
188
190 canvas->translate(400, 0);
191 draw_large_cubic(canvas);
192 draw_cubic_fillpath(canvas);
193}
194
195////////// ovals
196
199
201
202 draw_ribs(canvas, path);
203 canvas->drawPath(path, p);
204}
205
209
210 canvas->drawPath(path, p);
211 draw_ribs(canvas, path);
212}
213
217
218 SkPaint fillp = make_normal_paint();
220
221 SkPath fillpath;
223
224 canvas->drawPath(fillpath, fillp);
225}
226
228 canvas->translate(400, 0);
229 draw_large_oval(canvas);
230 draw_oval_fillpath(canvas);
231}
232
233////////// gm
234
235void (*examples[])(SkCanvas *canvas) = {
238};
239
240DEF_SIMPLE_GM(OverStroke, canvas, 500, 500) {
241 const size_t length = sizeof(examples) / sizeof(examples[0]);
242 const size_t width = 2;
243
244 for (size_t i = 0; i < length; i++) {
245 int x = (int)(i % width);
246 int y = (int)(i / width);
247
248 canvas->save();
249 canvas->translate(150.0f * x, 150.0f * y);
250 canvas->scale(0.2f, 0.2f);
251 canvas->translate(300.0f, 400.0f);
252
253 examples[i](canvas);
254
255 canvas->restore();
256 }
257}
SkPoint pos
constexpr SkColor SK_ColorMAGENTA
Definition: SkColor.h:147
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void setColor(SkColor color)
Definition: SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
SkPathBuilder & close()
SkPathBuilder & arcTo(const SkRect &oval, SkScalar startAngleDeg, SkScalar sweepAngleDeg, bool forceMoveTo)
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & quadTo(SkPoint pt1, SkPoint pt2)
SkScalar getLength()
bool getPosTan(SkScalar distance, SkPoint *position, SkVector *tangent)
Definition: SkPath.h:59
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
static void RotateCCW(const SkPoint &src, SkPoint *dst)
Definition: SkPointPriv.h:72
float SkScalar
Definition: extension.cpp:12
size_t length
double y
double x
SkRect oval
Definition: SkRecords.h:249
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
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23
void draw_ribs(SkCanvas *canvas, SkPath path)
Definition: overstroke.cpp:108
SkPaint make_normal_paint()
Definition: overstroke.cpp:41
DEF_SIMPLE_GM(OverStroke, canvas, 500, 500)
Definition: overstroke.cpp:240
void draw_large_quad(SkCanvas *canvas)
Definition: overstroke.cpp:131
const SkScalar OVERSTROKE_WIDTH
Definition: overstroke.cpp:36
SkPath quad_path()
Definition: overstroke.cpp:60
SkPath cubic_path()
Definition: overstroke.cpp:68
void(* examples[])(SkCanvas *canvas)
Definition: overstroke.cpp:235
SkPath ribs_path(SkPath path, SkScalar radius)
Definition: overstroke.cpp:84
void draw_stroked_quad(SkCanvas *canvas)
Definition: overstroke.cpp:152
void draw_quad_fillpath(SkCanvas *canvas)
Definition: overstroke.cpp:139
void draw_oval_fillpath(SkCanvas *canvas)
Definition: overstroke.cpp:214
SkPath oval_path()
Definition: overstroke.cpp:78
void draw_stroked_oval(SkCanvas *canvas)
Definition: overstroke.cpp:227
const SkScalar NORMALSTROKE_WIDTH
Definition: overstroke.cpp:37
SkPaint make_overstroke_paint()
Definition: overstroke.cpp:51
void draw_small_quad(SkCanvas *canvas)
Definition: overstroke.cpp:120
void draw_large_cubic(SkCanvas *canvas)
Definition: overstroke.cpp:168
void draw_small_oval(SkCanvas *canvas)
Definition: overstroke.cpp:197
void draw_stroked_cubic(SkCanvas *canvas)
Definition: overstroke.cpp:189
void draw_large_oval(SkCanvas *canvas)
Definition: overstroke.cpp:206
void draw_small_cubic(SkCanvas *canvas)
Definition: overstroke.cpp:160
void draw_cubic_fillpath(SkCanvas *canvas)
Definition: overstroke.cpp:176
int32_t width
void scale(float scale, SkPoint *dst) const
Definition: SkPoint.cpp:17
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659