Flutter Engine
The Flutter Engine
SkSGGeometryEffect.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 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
9
13#include "include/core/SkPath.h"
26#include "src/core/SkPathPriv.h"
27
28#include <algorithm>
29#include <cmath>
30
31using namespace skia_private;
32
33namespace sksg {
34
36 : fChild(std::move(child)) {
37 SkASSERT(fChild);
38
39 this->observeInval(fChild);
40}
41
43 this->unobserveInval(fChild);
44}
45
46void GeometryEffect::onClip(SkCanvas* canvas, bool antiAlias) const {
47 canvas->clipPath(fPath, SkClipOp::kIntersect, antiAlias);
48}
49
50void GeometryEffect::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
51 canvas->drawPath(fPath, paint);
52}
53
55 return fPath.contains(p.x(), p.y());
56}
57
59 return fPath;
60}
61
63 SkASSERT(this->hasInval());
64
65 fChild->revalidate(ic, ctm);
66
67 fPath = this->onRevalidateEffect(fChild);
69
70 return fPath.computeTightBounds();
71}
72
73SkPath TrimEffect::onRevalidateEffect(const sk_sp<GeometryNode>& child) {
74 SkPath path = child->asPath();
75
76 if (const auto trim = SkTrimPathEffect::Make(fStart, fStop, fMode)) {
78 SkASSERT(!trim->needsCTM());
79 SkAssertResult(trim->filterPath(&path, path, &rec, nullptr));
80 }
81
82 return path;
83}
84
85GeometryTransform::GeometryTransform(sk_sp<GeometryNode> child, sk_sp<Transform> transform)
86 : INHERITED(std::move(child))
87 , fTransform(std::move(transform)) {
88 SkASSERT(fTransform);
89 this->observeInval(fTransform);
90}
91
93 this->unobserveInval(fTransform);
94}
95
96SkPath GeometryTransform::onRevalidateEffect(const sk_sp<GeometryNode>& child) {
97 fTransform->revalidate(nullptr, SkMatrix::I());
98 const auto m = TransformPriv::As<SkMatrix>(fTransform);
99
100 SkPath path = child->asPath();
101 path.transform(m);
102
103 return path;
104}
105
106namespace {
107
108sk_sp<SkPathEffect> make_dash(const std::vector<float>& intervals, float phase) {
109 if (intervals.empty()) {
110 return nullptr;
111 }
112
113 const auto* intervals_ptr = intervals.data();
114 auto intervals_count = intervals.size();
115
117 if (intervals_count & 1) {
118 intervals_count *= 2;
119 storage.resize(intervals_count);
120 intervals_ptr = storage.data();
121
122 std::copy(intervals.begin(), intervals.end(), storage.begin());
123 std::copy(intervals.begin(), intervals.end(), storage.begin() + intervals.size());
124 }
125
126 return SkDashPathEffect::Make(intervals_ptr, SkToInt(intervals_count), phase);
127}
128
129} // namespace
130
131SkPath DashEffect::onRevalidateEffect(const sk_sp<GeometryNode>& child) {
132 SkPath path = child->asPath();
133
134 if (const auto dash_patheffect = make_dash(fIntervals, fPhase)) {
136 SkASSERT(!dash_patheffect->needsCTM());
137 dash_patheffect->filterPath(&path, path, &rec, nullptr);
138 }
139
140 return path;
141}
142
143SkPath RoundEffect::onRevalidateEffect(const sk_sp<GeometryNode>& child) {
144 SkPath path = child->asPath();
145
146 if (const auto round = SkCornerPathEffect::Make(fRadius)) {
148 SkASSERT(!round->needsCTM());
149 SkAssertResult(round->filterPath(&path, path, &rec, nullptr));
150 }
151
152 return path;
153}
154
155SkPath OffsetEffect::onRevalidateEffect(const sk_sp<GeometryNode>& child) {
156 SkPath path = child->asPath();
157
158 if (!SkScalarNearlyZero(fOffset)) {
161 paint.setStrokeWidth(std::abs(fOffset) * 2);
162 paint.setStrokeMiter(fMiterLimit);
163 paint.setStrokeJoin(fJoin);
164
165 SkPath fill_path;
166 skpathutils::FillPathWithPaint(path, paint, &fill_path, nullptr);
167
168 if (fOffset > 0) {
169 Op(path, fill_path, kUnion_SkPathOp, &path);
170 } else {
171 Op(path, fill_path, kDifference_SkPathOp, &path);
172 }
173
174 // TODO: this seems to break path combining (winding mismatch?)
175 // Simplify(path, &path);
176 }
177
178 return path;
179}
180
181} // namespace sksg
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static sk_sp< SkPathEffect > make_dash()
static void round(SkPoint *p)
#define SkASSERT(cond)
Definition: SkAssert.h:116
static SkCanvas * trim(SkCanvas *canvas, SkScalar width, SkScalar height, const SkRect *content)
Definition: SkDocument.cpp:19
@ kDifference_SkPathOp
subtract the op path from the first path
Definition: SkPathOps.h:23
@ kUnion_SkPathOp
union (inclusive-or) the two paths
Definition: SkPathOps.h:25
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:101
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
Definition: SkSwizzler.cpp:31
constexpr int SkToInt(S x)
Definition: SkTo.h:29
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1456
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
static sk_sp< SkPathEffect > Make(SkScalar radius)
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
static void ShrinkToFit(SkPath *path)
Definition: SkPathPriv.h:130
Definition: SkPath.h:59
SkRect computeTightBounds() const
Definition: SkPath.cpp:3446
bool contains(SkScalar x, SkScalar y) const
Definition: SkPath.cpp:3118
@ kHairline_InitStyle
Definition: SkStrokeRec.h:25
static sk_sp< SkPathEffect > Make(SkScalar startT, SkScalar stopT, Mode=Mode::kNormal)
void resize(size_t count)
Definition: SkTArray.h:423
void onDraw(SkCanvas *, const SkPaint &) const final
bool onContains(const SkPoint &) const final
virtual SkPath onRevalidateEffect(const sk_sp< GeometryNode > &)=0
void onClip(SkCanvas *, bool antiAlias) const final
GeometryEffect(sk_sp< GeometryNode >)
SkRect onRevalidate(InvalidationController *, const SkMatrix &) final
SkPath onAsPath() const final
void observeInval(const sk_sp< Node > &)
Definition: SkSGNode.cpp:61
void unobserveInval(const sk_sp< Node > &)
Definition: SkSGNode.cpp:84
bool hasInval() const
Definition: SkSGNode.h:60
const Paint & paint
Definition: color_source.cc:38
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
Definition: Skottie.h:32
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition: SkVx.h:707
Definition: ref_ptr.h:256
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47