Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | List of all members
OpAsWinding Class Reference

Public Types

enum class  Edge { kInitial , kCompare }
 

Public Member Functions

 OpAsWinding (const SkPath &path)
 
void contourBounds (vector< Contour > *containers)
 
Contour::Direction getDirection (Contour &contour)
 
int nextEdge (Contour &contour, Edge edge)
 
bool containerContains (Contour &contour, Contour &test)
 
void inParent (Contour &contour, Contour &parent)
 
bool checkContainerChildren (Contour *parent, Contour *child)
 
bool markReverse (Contour *parent, Contour *child)
 
SkPath reverseMarkedContours (vector< Contour > &contours, SkPathFillType fillType)
 

Detailed Description

Definition at line 170 of file SkPathOpsAsWinding.cpp.

Member Enumeration Documentation

◆ Edge

enum class OpAsWinding::Edge
strong
Enumerator
kInitial 
kCompare 

Definition at line 172 of file SkPathOpsAsWinding.cpp.

172 {
173 kInitial,
174 kCompare,
175 };

Constructor & Destructor Documentation

◆ OpAsWinding()

OpAsWinding::OpAsWinding ( const SkPath path)
inline

Definition at line 177 of file SkPathOpsAsWinding.cpp.

178 : fPath(path) {
179 }
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

Member Function Documentation

◆ checkContainerChildren()

bool OpAsWinding::checkContainerChildren ( Contour parent,
Contour child 
)
inline

Definition at line 328 of file SkPathOpsAsWinding.cpp.

328 {
329 for (auto grandChild : child->fChildren) {
330 if (!checkContainerChildren(child, grandChild)) {
331 return false;
332 }
333 }
334 if (parent) {
335 if (!containerContains(*parent, *child)) {
336 return false;
337 }
338 }
339 return true;
340 }
bool containerContains(Contour &contour, Contour &test)
bool checkContainerChildren(Contour *parent, Contour *child)
vector< Contour * > fChildren

◆ containerContains()

bool OpAsWinding::containerContains ( Contour contour,
Contour test 
)
inline

Definition at line 291 of file SkPathOpsAsWinding.cpp.

291 {
292 // find outside point on lesser contour
293 // arbitrarily, choose non-horizontal edge where point <= bounds left
294 // note that if leftmost point is control point, may need tight bounds
295 // to find edge with minimum-x
296 if (SK_ScalarMax == test.fMinXY.fX) {
297 this->nextEdge(test, Edge::kInitial);
298 }
299 // find all edges on greater equal or to the left of one on lesser
300 contour.fMinXY = test.fMinXY;
301 int winding = this->nextEdge(contour, Edge::kCompare);
302 // if edge is up, mark contour cw, otherwise, ccw
303 // sum of greater edges direction should be cw, 0, ccw
304 test.fContained = winding != 0;
305 return -1 <= winding && winding <= 1;
306 }
#define SK_ScalarMax
Definition: SkScalar.h:24
int nextEdge(Contour &contour, Edge edge)

◆ contourBounds()

void OpAsWinding::contourBounds ( vector< Contour > *  containers)
inline

Definition at line 181 of file SkPathOpsAsWinding.cpp.

181 {
183 bounds.setEmpty();
184 int lastStart = 0;
185 int verbStart = 0;
186 for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) {
187 if (SkPathVerb::kMove == verb) {
188 if (!bounds.isEmpty()) {
189 containers->emplace_back(bounds, lastStart, verbStart);
190 lastStart = verbStart;
191 }
193 }
194 if (SkPathVerb::kLine <= verb && verb <= SkPathVerb::kCubic) {
195 SkRect verbBounds;
196 verbBounds.setBounds(&pts[kPtIndex[(int)verb]], kPtCount[(int)verb]);
197 bounds.joinPossiblyEmptyRect(verbBounds);
198 }
199 ++verbStart;
200 }
201 if (!bounds.isEmpty()) {
202 containers->emplace_back(bounds, lastStart, ++verbStart);
203 }
204 }
static const int kPtIndex[]
static const int kPtCount[]
@ kCubic
SkPath::RawIter returns 4 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
@ kMove_Verb
Definition: SkPath.h:1466
Optional< SkRect > bounds
Definition: SkRecords.h:189
SkScalar w
void setBounds(const SkPoint pts[], int count)
Definition: SkRect.h:881

◆ getDirection()

Contour::Direction OpAsWinding::getDirection ( Contour contour)
inline

Definition at line 206 of file SkPathOpsAsWinding.cpp.

206 {
207 SkPath::Iter iter(fPath, true);
208 int verbCount = -1;
209 SkPath::Verb verb;
210 SkPoint pts[4];
211
212 SkScalar total_signed_area = 0;
213 do {
214 verb = iter.next(pts);
215 if (++verbCount < contour.fVerbStart) {
216 continue;
217 }
218 if (verbCount >= contour.fVerbEnd) {
219 continue;
220 }
221 if (SkPath::kLine_Verb > verb || verb > SkPath::kCubic_Verb) {
222 continue;
223 }
224
225 switch (verb)
226 {
228 total_signed_area += (pts[0].fY - pts[1].fY) * (pts[0].fX + pts[1].fX);
229 break;
232 total_signed_area += (pts[0].fY - pts[2].fY) * (pts[0].fX + pts[2].fX);
233 break;
235 total_signed_area += (pts[0].fY - pts[3].fY) * (pts[0].fX + pts[3].fX);
236 break;
237 default:
238 break;
239 }
240 } while (SkPath::kDone_Verb != verb);
241
242 return total_signed_area < 0 ? Contour::Direction::kCCW: Contour::Direction::kCW;
243 }
@ 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
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ inParent()

void OpAsWinding::inParent ( Contour contour,
Contour parent 
)
inline

Definition at line 308 of file SkPathOpsAsWinding.cpp.

308 {
309 // move contour into sibling list contained by parent
310 for (auto test : parent.fChildren) {
311 if (test->fBounds.contains(contour.fBounds)) {
313 return;
314 }
315 }
316 // move parent's children into contour's children if contained by contour
317 for (auto iter = parent.fChildren.begin(); iter != parent.fChildren.end(); ) {
318 if (contour.fBounds.contains((*iter)->fBounds)) {
319 contour.fChildren.push_back(*iter);
320 iter = parent.fChildren.erase(iter);
321 continue;
322 }
323 ++iter;
324 }
325 parent.fChildren.push_back(&contour);
326 }
void inParent(Contour &contour, Contour &parent)

◆ markReverse()

bool OpAsWinding::markReverse ( Contour parent,
Contour child 
)
inline

Definition at line 342 of file SkPathOpsAsWinding.cpp.

342 {
343 bool reversed = false;
344 for (auto grandChild : child->fChildren) {
345 reversed |= markReverse(grandChild->fContained ? child : parent, grandChild);
346 }
347
348 child->fDirection = getDirection(*child);
349 if (parent && parent->fDirection == child->fDirection) {
350 child->fReverse = true;
351 child->fDirection = (Contour::Direction) -(int) child->fDirection;
352 return true;
353 }
354 return reversed;
355 }
Contour::Direction getDirection(Contour &contour)
bool markReverse(Contour *parent, Contour *child)
Direction fDirection

◆ nextEdge()

int OpAsWinding::nextEdge ( Contour contour,
Edge  edge 
)
inline

Definition at line 245 of file SkPathOpsAsWinding.cpp.

245 {
246 SkPath::Iter iter(fPath, true);
247 SkPoint pts[4];
248 SkPath::Verb verb;
249 int verbCount = -1;
250 int winding = 0;
251 do {
252 verb = iter.next(pts);
253 if (++verbCount < contour.fVerbStart) {
254 continue;
255 }
256 if (verbCount >= contour.fVerbEnd) {
257 continue;
258 }
259 if (SkPath::kLine_Verb > verb || verb > SkPath::kCubic_Verb) {
260 continue;
261 }
262 bool horizontal = true;
263 for (int index = 1; index <= kPtCount[verb]; ++index) {
264 if (pts[0].fY != pts[index].fY) {
265 horizontal = false;
266 break;
267 }
268 }
269 if (horizontal) {
270 continue;
271 }
272 if (edge == Edge::kCompare) {
273 winding += contains_edge(pts, verb, conic_weight(iter, verb), contour.fMinXY);
274 continue;
275 }
276 SkASSERT(edge == Edge::kInitial);
277 SkPoint minXY = left_edge(pts, verb, conic_weight(iter, verb));
278 if (minXY.fX > contour.fMinXY.fX) {
279 continue;
280 }
281 if (minXY.fX == contour.fMinXY.fX) {
282 if (minXY.fY != contour.fMinXY.fY) {
283 continue;
284 }
285 }
286 contour.fMinXY = minXY;
287 } while (SkPath::kDone_Verb != verb);
288 return winding;
289 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
static SkPoint left_edge(SkPoint pts[4], SkPath::Verb verb, SkScalar weight)
static SkScalar conic_weight(const SkPath::Iter &iter, SkPath::Verb verb)
static int contains_edge(SkPoint pts[4], SkPath::Verb verb, SkScalar weight, const SkPoint &edge)
float fX
x-axis value
Definition: SkPoint_impl.h:164

◆ reverseMarkedContours()

SkPath OpAsWinding::reverseMarkedContours ( vector< Contour > &  contours,
SkPathFillType  fillType 
)
inline

Definition at line 357 of file SkPathOpsAsWinding.cpp.

357 {
358 SkPathPriv::Iterate iterate(fPath);
359 auto iter = iterate.begin();
360 int verbCount = 0;
361
363 result.setFillType(fillType);
364 for (const Contour& contour : contours) {
366 SkPathBuilder* temp = contour.fReverse ? &reverse : &result;
367 for (; iter != iterate.end() && verbCount < contour.fVerbEnd; ++iter, ++verbCount) {
368 auto [verb, pts, w] = *iter;
369 switch (verb) {
371 temp->moveTo(pts[0]);
372 break;
374 temp->lineTo(pts[1]);
375 break;
377 temp->quadTo(pts[1], pts[2]);
378 break;
380 temp->conicTo(pts[1], pts[2], *w);
381 break;
383 temp->cubicTo(pts[1], pts[2], pts[3]);
384 break;
386 temp->close();
387 break;
388 }
389 }
390 if (contour.fReverse) {
391 SkASSERT(temp == &reverse);
393 }
394 }
395 return result.detach();
396 }
@ kClose
SkPath::RawIter returns 0 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
SkPathBuilder & conicTo(SkPoint pt1, SkPoint pt2, SkScalar w)
SkPathBuilder & close()
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & cubicTo(SkPoint pt1, SkPoint pt2, SkPoint pt3)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & quadTo(SkPoint pt1, SkPoint pt2)
static void ReverseAddPath(SkPathBuilder *builder, const SkPath &reverseMe)
Definition: SkPathPriv.h:421
GAsyncResult * result

The documentation for this class was generated from the following file: