Flutter Engine
The Flutter Engine
SkCornerPathEffect.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2006 The Android Open Source Project
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
11#include "include/core/SkPath.h"
21
22class SkMatrix;
23class SkStrokeRec;
24struct SkRect;
25
26static bool ComputeStep(const SkPoint& a, const SkPoint& b, SkScalar radius,
27 SkPoint* step) {
29
30 *step = b - a;
31 if (dist <= radius * 2) {
33 return false;
34 } else {
35 *step *= radius / dist;
36 return true;
37 }
38}
39
41public:
42 explicit SkCornerPathEffectImpl(SkScalar radius) : fRadius(radius) {
43 SkASSERT(radius > 0);
44 }
45
47 const SkMatrix&) const override {
48 if (fRadius <= 0) {
49 return false;
50 }
51
52 SkPath::Iter iter(src, false);
53 SkPath::Verb verb, prevVerb = SkPath::kDone_Verb;
54 SkPoint pts[4];
55
56 bool closed;
57 SkPoint moveTo, lastCorner;
58 SkVector firstStep, step;
59 bool prevIsValid = true;
60
61 // to avoid warnings
62 step.set(0, 0);
63 moveTo.set(0, 0);
64 firstStep.set(0, 0);
65 lastCorner.set(0, 0);
66
67 for (;;) {
68 switch (verb = iter.next(pts)) {
70 // close out the previous (open) contour
71 if (SkPath::kLine_Verb == prevVerb) {
72 dst->lineTo(lastCorner);
73 }
74 closed = iter.isClosedContour();
75 if (closed) {
76 moveTo = pts[0];
77 prevIsValid = false;
78 } else {
79 dst->moveTo(pts[0]);
80 prevIsValid = true;
81 }
82 break;
83 case SkPath::kLine_Verb: {
84 bool drawSegment = ComputeStep(pts[0], pts[1], fRadius, &step);
85 // prev corner
86 if (!prevIsValid) {
87 dst->moveTo(moveTo + step);
88 prevIsValid = true;
89 } else {
90 dst->quadTo(pts[0].fX, pts[0].fY, pts[0].fX + step.fX,
91 pts[0].fY + step.fY);
92 }
93 if (drawSegment) {
94 dst->lineTo(pts[1].fX - step.fX, pts[1].fY - step.fY);
95 }
96 lastCorner = pts[1];
97 prevIsValid = true;
98 break;
99 }
101 // TBD - just replicate the curve for now
102 if (!prevIsValid) {
103 dst->moveTo(pts[0]);
104 prevIsValid = true;
105 }
106 dst->quadTo(pts[1], pts[2]);
107 lastCorner = pts[2];
108 firstStep.set(0, 0);
109 break;
111 // TBD - just replicate the curve for now
112 if (!prevIsValid) {
113 dst->moveTo(pts[0]);
114 prevIsValid = true;
115 }
116 dst->conicTo(pts[1], pts[2], iter.conicWeight());
117 lastCorner = pts[2];
118 firstStep.set(0, 0);
119 break;
121 if (!prevIsValid) {
122 dst->moveTo(pts[0]);
123 prevIsValid = true;
124 }
125 // TBD - just replicate the curve for now
126 dst->cubicTo(pts[1], pts[2], pts[3]);
127 lastCorner = pts[3];
128 firstStep.set(0, 0);
129 break;
131 if (firstStep.fX || firstStep.fY) {
132 dst->quadTo(lastCorner.fX, lastCorner.fY,
133 lastCorner.fX + firstStep.fX,
134 lastCorner.fY + firstStep.fY);
135 }
136 dst->close();
137 prevIsValid = false;
138 break;
140 if (prevIsValid) {
141 dst->lineTo(lastCorner);
142 }
143 return true;
144 default:
145 SkDEBUGFAIL("default should not be reached");
146 return false;
147 }
148
149 if (SkPath::kMove_Verb == prevVerb) {
150 firstStep = step;
151 }
152 prevVerb = verb;
153 }
154 }
155
156 bool computeFastBounds(SkRect*) const override {
157 // Rounding sharp corners within a path produces a new path that is still contained within
158 // the original's bounds, so leave 'bounds' unmodified.
159 return true;
160 }
161
163 return SkCornerPathEffect::Make(buffer.readScalar());
164 }
165
166 void flatten(SkWriteBuffer& buffer) const override {
167 buffer.writeScalar(fRadius);
168 }
169
170 Factory getFactory() const override { return CreateProc; }
171 const char* getTypeName() const override { return "SkCornerPathEffect"; }
172
173private:
174 const SkScalar fRadius;
175
176 using INHERITED = SkPathEffectBase;
177};
178
179//////////////////////////////////////////////////////////////////////////////////////////////////
180
182 return SkIsFinite(radius) && (radius > 0) ?
183 sk_sp<SkPathEffect>(new SkCornerPathEffectImpl(radius)) : nullptr;
184}
185
188}
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
#define SkASSERT(cond)
Definition: SkAssert.h:116
static bool ComputeStep(const SkPoint &a, const SkPoint &b, SkScalar radius, SkPoint *step)
static bool SkIsFinite(T x, Pack... values)
#define SK_ScalarHalf
Definition: SkScalar.h:19
SkCornerPathEffectImpl(SkScalar radius)
Factory getFactory() const override
const char * getTypeName() const override
bool computeFastBounds(SkRect *) const override
static sk_sp< SkFlattenable > CreateProc(SkReadBuffer &buffer)
bool onFilterPath(SkPath *dst, const SkPath &src, SkStrokeRec *, const SkRect *, const SkMatrix &) const override
void flatten(SkWriteBuffer &buffer) const override
static void RegisterFlattenables()
static sk_sp< SkPathEffect > Make(SkScalar radius)
sk_sp< SkFlattenable >(* Factory)(SkReadBuffer &)
Definition: SkFlattenable.h:41
static void Register(const char name[], Factory)
bool isClosedContour() const
Definition: SkPath.cpp:1851
Verb next(SkPoint pts[4])
Definition: SkPath.cpp:1901
SkScalar conicWeight() const
Definition: SkPath.h:1535
Definition: SkPath.h:59
@ kClose_Verb
Definition: SkPath.h:1471
@ kMove_Verb
Definition: SkPath.h:1466
@ kConic_Verb
Definition: SkPath.h:1469
@ kDone_Verb
Definition: SkPath.h:1472
@ kCubic_Verb
Definition: SkPath.h:1470
@ kQuad_Verb
Definition: SkPath.h:1468
@ kLine_Verb
Definition: SkPath.h:1467
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
dst
Definition: cp.py:12
float fX
x-axis value
Definition: SkPoint_impl.h:164
void set(float x, float y)
Definition: SkPoint_impl.h:200
static float Distance(const SkPoint &a, const SkPoint &b)
Definition: SkPoint_impl.h:508
float fY
y-axis value
Definition: SkPoint_impl.h:165