@@ -114,30 +114,72 @@ DlPath DlPath::MakeArc(const DlRect& bounds,
114114}
115115
116116const SkPath& DlPath::GetSkPath () const {
117- auto & sk_path = data_->sk_path ;
118- if (sk_path.has_value ()) {
119- return sk_path.value ();
120- }
121- sk_path.emplace ();
122- return sk_path.value ();
117+ return data_->sk_path ;
123118}
124119
125120void DlPath::Dispatch (DlPathReceiver& receiver) const {
126- auto & sk_path = data_->sk_path ;
127- FML_DCHECK (sk_path. has_value ());
128- if (sk_path. has_value ()) {
129- DispatchFromSkiaPath (sk_path. value (), receiver) ;
121+ const SkPath& path = data_->sk_path ;
122+ if (path. isEmpty ()) {
123+ receiver. PathEnd ();
124+ return ;
130125 }
126+
127+ auto iterator = SkPath::Iter (path, false );
128+
129+ struct PathData {
130+ union {
131+ SkPoint points[4 ];
132+ };
133+ };
134+
135+ PathData data;
136+
137+ auto verb = SkPath::Verb::kDone_Verb ;
138+ do {
139+ verb = iterator.next (data.points );
140+ switch (verb) {
141+ case SkPath::kMove_Verb :
142+ receiver.MoveTo (ToDlPoint (data.points [0 ]), iterator.isClosedContour ());
143+ break ;
144+ case SkPath::kLine_Verb :
145+ receiver.LineTo (ToDlPoint (data.points [1 ]));
146+ break ;
147+ case SkPath::kQuad_Verb :
148+ receiver.QuadTo (ToDlPoint (data.points [1 ]), ToDlPoint (data.points [2 ]));
149+ break ;
150+ case SkPath::kConic_Verb :
151+ if (!receiver.ConicTo (ToDlPoint (data.points [1 ]),
152+ ToDlPoint (data.points [2 ]),
153+ iterator.conicWeight ())) {
154+ ReduceConic (receiver, //
155+ ToDlPoint (data.points [0 ]), //
156+ ToDlPoint (data.points [1 ]), //
157+ ToDlPoint (data.points [2 ]), //
158+ iterator.conicWeight ());
159+ }
160+ break ;
161+ case SkPath::kCubic_Verb :
162+ receiver.CubicTo (ToDlPoint (data.points [1 ]), //
163+ ToDlPoint (data.points [2 ]), //
164+ ToDlPoint (data.points [3 ]));
165+ break ;
166+ case SkPath::kClose_Verb :
167+ receiver.Close ();
168+ break ;
169+ case SkPath::kDone_Verb :
170+ break ;
171+ }
172+ } while (verb != SkPath::Verb::kDone_Verb );
173+ receiver.PathEnd ();
131174}
132175
133176void DlPath::WillRenderSkPath () const {
134- if ( data_->render_count >= kMaxVolatileUses ) {
135- auto & sk_path = data_-> sk_path ;
136- if (sk_path. has_value () ) {
137- sk_path. value () .setIsVolatile (false );
177+ uint32_t count = data_->render_count ;
178+ if (count <= kMaxVolatileUses ) {
179+ if (count == kMaxVolatileUses ) {
180+ data_-> sk_path .setIsVolatile (false );
138181 }
139- } else {
140- data_->render_count ++;
182+ data_->render_count = ++count;
141183 }
142184}
143185
@@ -148,27 +190,19 @@ void DlPath::WillRenderSkPath() const {
148190 if (!offset.IsFinite ()) {
149191 return DlPath ();
150192 }
151- auto & sk_path = data_->sk_path ;
152- if (sk_path.has_value ()) {
153- SkPath path = sk_path.value ();
154- path = path.offset (offset.x , offset.y );
155- return DlPath (path);
156- }
157- return *this ;
193+ SkPath path = data_->sk_path ;
194+ path = path.offset (offset.x , offset.y );
195+ return DlPath (path);
158196}
159197
160198[[nodiscard]] DlPath DlPath::WithFillType (DlPathFillType type) const {
161- auto & sk_path = data_->sk_path ;
162- if (sk_path.has_value ()) {
163- SkPathFillType sk_type = ToSkFillType (type);
164- if (sk_path.value ().getFillType () == sk_type) {
165- return *this ;
166- }
167- SkPath path = sk_path.value ();
168- path.setFillType (sk_type);
169- return DlPath (path);
199+ SkPathFillType sk_type = ToSkFillType (type);
200+ if (data_->sk_path .getFillType () == sk_type) {
201+ return *this ;
170202 }
171- return *this ;
203+ SkPath path = data_->sk_path ;
204+ path.setFillType (sk_type);
205+ return DlPath (path);
172206}
173207
174208bool DlPath::IsEmpty () const {
@@ -223,9 +257,7 @@ bool DlPath::IsVolatile() const {
223257}
224258
225259bool DlPath::IsConvex () const {
226- auto & sk_path = data_->sk_path ;
227- FML_DCHECK (sk_path.has_value ());
228- return sk_path.has_value () && sk_path->isConvex ();
260+ return data_->sk_path .isConvex ();
229261}
230262
231263DlPath DlPath::operator +(const DlPath& other) const {
@@ -234,11 +266,11 @@ DlPath DlPath::operator+(const DlPath& other) const {
234266 return DlPath (path);
235267}
236268
237- static void ReduceConic (DlPathReceiver& receiver,
238- const DlPoint& p1,
239- const DlPoint& cp,
240- const DlPoint& p2,
241- DlScalar weight) {
269+ void DlPath:: ReduceConic (DlPathReceiver& receiver,
270+ const DlPoint& p1,
271+ const DlPoint& cp,
272+ const DlPoint& p2,
273+ DlScalar weight) {
242274 // We might eventually have conic conversion math that deals with
243275 // degenerate conics gracefully (or have all receivers just handle
244276 // them directly). But, until then, we will just convert them to a
@@ -287,59 +319,4 @@ static void ReduceConic(DlPathReceiver& receiver,
287319 }
288320}
289321
290- void DlPath::DispatchFromSkiaPath (const SkPath& path,
291- DlPathReceiver& receiver) {
292- if (path.isEmpty ()) {
293- return ;
294- }
295-
296- auto iterator = SkPath::Iter (path, false );
297-
298- struct PathData {
299- union {
300- SkPoint points[4 ];
301- };
302- };
303-
304- PathData data;
305-
306- auto verb = SkPath::Verb::kDone_Verb ;
307- do {
308- verb = iterator.next (data.points );
309- switch (verb) {
310- case SkPath::kMove_Verb :
311- receiver.MoveTo (ToDlPoint (data.points [0 ]), iterator.isClosedContour ());
312- break ;
313- case SkPath::kLine_Verb :
314- receiver.LineTo (ToDlPoint (data.points [1 ]));
315- break ;
316- case SkPath::kQuad_Verb :
317- receiver.QuadTo (ToDlPoint (data.points [1 ]), ToDlPoint (data.points [2 ]));
318- break ;
319- case SkPath::kConic_Verb :
320- if (!receiver.ConicTo (ToDlPoint (data.points [1 ]),
321- ToDlPoint (data.points [2 ]),
322- iterator.conicWeight ())) {
323- ReduceConic (receiver, //
324- ToDlPoint (data.points [0 ]), //
325- ToDlPoint (data.points [1 ]), //
326- ToDlPoint (data.points [2 ]), //
327- iterator.conicWeight ());
328- }
329- break ;
330- case SkPath::kCubic_Verb :
331- receiver.CubicTo (ToDlPoint (data.points [1 ]), //
332- ToDlPoint (data.points [2 ]), //
333- ToDlPoint (data.points [3 ]));
334- break ;
335- case SkPath::kClose_Verb :
336- receiver.Close ();
337- break ;
338- case SkPath::kDone_Verb :
339- break ;
340- }
341- } while (verb != SkPath::Verb::kDone_Verb );
342- receiver.PathEnd ();
343- }
344-
345322} // namespace flutter
0 commit comments