Flutter Engine
The Flutter Engine
Classes | Enumerations | Functions
SkPathOps.h File Reference
#include "include/core/SkPath.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"

Go to the source code of this file.

Classes

class  SkOpBuilder
 

Enumerations

enum  SkPathOp {
  kDifference_SkPathOp , kIntersect_SkPathOp , kUnion_SkPathOp , kXOR_SkPathOp ,
  kReverseDifference_SkPathOp
}
 

Functions

bool SK_API Op (const SkPath &one, const SkPath &two, SkPathOp op, SkPath *result)
 
bool SK_API Simplify (const SkPath &path, SkPath *result)
 
bool SK_API TightBounds (const SkPath &path, SkRect *result)
 
bool SK_API AsWinding (const SkPath &path, SkPath *result)
 

Enumeration Type Documentation

◆ SkPathOp

enum SkPathOp

The logical operations that can be performed when combining two paths.

Enumerator
kDifference_SkPathOp 

subtract the op path from the first path

kIntersect_SkPathOp 

intersect the two paths

kUnion_SkPathOp 

union (inclusive-or) the two paths

kXOR_SkPathOp 

exclusive-or the two paths

kReverseDifference_SkPathOp 

subtract the first path from the op path

Definition at line 22 of file SkPathOps.h.

22 {
23 kDifference_SkPathOp, //!< subtract the op path from the first path
24 kIntersect_SkPathOp, //!< intersect the two paths
25 kUnion_SkPathOp, //!< union (inclusive-or) the two paths
26 kXOR_SkPathOp, //!< exclusive-or the two paths
27 kReverseDifference_SkPathOp, //!< subtract the first path from the op path
28};
@ kReverseDifference_SkPathOp
subtract the first path from the op path
Definition: SkPathOps.h:27
@ kDifference_SkPathOp
subtract the op path from the first path
Definition: SkPathOps.h:23
@ kIntersect_SkPathOp
intersect the two paths
Definition: SkPathOps.h:24
@ kUnion_SkPathOp
union (inclusive-or) the two paths
Definition: SkPathOps.h:25
@ kXOR_SkPathOp
exclusive-or the two paths
Definition: SkPathOps.h:26

Function Documentation

◆ AsWinding()

bool SK_API AsWinding ( const SkPath path,
SkPath result 
)

Set the result with fill type winding to area equivalent to path. Returns true if successful. Does not detect if path contains contours which contain self-crossings or cross other contours; in these cases, may return true even though result does not fill same area as path.

Returns true if operation was able to produce a result; otherwise, result is unmodified. The result may be the input.

Parameters
pathThe path typically with fill type set to even odd.
resultThe equivalent path with fill type set to winding.
Returns
True if winding path was set.

Definition at line 408 of file SkPathOpsAsWinding.cpp.

408 {
409 if (!path.isFinite()) {
410 return false;
411 }
412 SkPathFillType fillType = path.getFillType();
413 if (fillType == SkPathFillType::kWinding
414 || fillType == SkPathFillType::kInverseWinding ) {
415 return set_result_path(result, path, fillType);
416 }
417 fillType = path.isInverseFillType() ? SkPathFillType::kInverseWinding :
419 if (path.isEmpty() || path.isConvex()) {
420 return set_result_path(result, path, fillType);
421 }
422 // count contours
423 vector<Contour> contours; // one per contour
424 OpAsWinding winder(path);
425 winder.contourBounds(&contours);
426 if (contours.size() <= 1) {
427 return set_result_path(result, path, fillType);
428 }
429 // create contour bounding box tree
430 Contour sorted(SkRect(), 0, 0);
431 for (auto& contour : contours) {
432 winder.inParent(contour, sorted);
433 }
434 // if sorted has no grandchildren, no child has to fix its children's winding
435 if (std::all_of(sorted.fChildren.begin(), sorted.fChildren.end(),
436 [](const Contour* contour) -> bool { return contour->fChildren.empty(); } )) {
437 return set_result_path(result, path, fillType);
438 }
439 // starting with outermost and moving inward, see if one path contains another
440 for (auto contour : sorted.fChildren) {
441 winder.nextEdge(*contour, OpAsWinding::Edge::kInitial);
442 contour->fDirection = winder.getDirection(*contour);
443 if (!winder.checkContainerChildren(nullptr, contour)) {
444 return false;
445 }
446 }
447 // starting with outermost and moving inward, mark paths to reverse
448 bool reversed = false;
449 for (auto contour : sorted.fChildren) {
450 reversed |= winder.markReverse(nullptr, contour);
451 }
452 if (!reversed) {
453 return set_result_path(result, path, fillType);
454 }
455 *result = winder.reverseMarkedContours(contours, fillType);
456 return true;
457}
static bool set_result_path(SkPath *result, const SkPath &path, SkPathFillType fillType)
SkPathFillType
Definition: SkPathTypes.h:11
GAsyncResult * result
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

◆ Op()

bool SK_API Op ( const SkPath one,
const SkPath two,
SkPathOp  op,
SkPath result 
)

Set this path to the result of applying the Op to this path and the specified path: this = (this op operand). The resulting path will be constructed from non-overlapping contours. The curve order is reduced where possible so that cubics may be turned into quadratics, and quadratics maybe turned into lines.

Returns true if operation was able to produce a result; otherwise, result is unmodified.

Parameters
oneThe first operand (for difference, the minuend)
twoThe second operand (for difference, the subtrahend)
opThe operator to apply.
resultThe product of the operands. The result may be one of the inputs.
Returns
True if the operation succeeded.

Definition at line 383 of file SkPathOpsOp.cpp.

383 {
384#if DEBUG_DUMP_VERIFY
385 if (SkPathOpsDebug::gVerifyOp) {
386 if (!OpDebug(one, two, op, result SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr))) {
387 ReportOpFail(one, two, op);
388 return false;
389 }
390 VerifyOp(one, two, op, *result);
391 return true;
392 }
393#endif
394 return OpDebug(one, two, op, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullptr));
395}
#define SkDEBUGPARAMS(...)
bool OpDebug(const SkPath &one, const SkPath &two, SkPathOp op, SkPath *result SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char *testName))

◆ Simplify()

bool SK_API Simplify ( const SkPath path,
SkPath result 
)

Set this path to a set of non-overlapping contours that describe the same area as the original path. The curve order is reduced where possible so that cubics may be turned into quadratics, and quadratics maybe turned into lines.

Returns true if operation was able to produce a result; otherwise, result is unmodified.

Parameters
pathThe path to simplify.
resultThe simplified path. The result may be the input.
Returns
True if simplification succeeded.

Definition at line 283 of file SkPathOpsSimplify.cpp.

283 {
284#if DEBUG_DUMP_VERIFY
285 if (SkPathOpsDebug::gVerifyOp) {
286 if (!SimplifyDebug(path, result SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr))) {
287 ReportSimplifyFail(path);
288 return false;
289 }
290 VerifySimplify(path, *result);
291 return true;
292 }
293#endif
294 return SimplifyDebug(path, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullptr));
295}
bool SimplifyDebug(const SkPath &path, SkPath *result SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char *testName))

◆ TightBounds()

bool SK_API TightBounds ( const SkPath path,
SkRect result 
)

Set the resulting rectangle to the tight bounds of the path.

Parameters
pathThe path measured.
resultThe tight bounds of the path.
Returns
True if the bounds could be computed.

Definition at line 23 of file SkPathOpsTightBounds.cpp.

23 {
25 bool wellBehaved = true;
26 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
27 switch (verb) {
29 moveBounds.fLeft = std::min(moveBounds.fLeft, pts[0].fX);
30 moveBounds.fTop = std::min(moveBounds.fTop, pts[0].fY);
31 moveBounds.fRight = std::max(moveBounds.fRight, pts[0].fX);
32 moveBounds.fBottom = std::max(moveBounds.fBottom, pts[0].fY);
33 break;
36 if (!wellBehaved) {
37 break;
38 }
39 wellBehaved &= between(pts[0].fX, pts[1].fX, pts[2].fX);
40 wellBehaved &= between(pts[0].fY, pts[1].fY, pts[2].fY);
41 break;
43 if (!wellBehaved) {
44 break;
45 }
46 wellBehaved &= between(pts[0].fX, pts[1].fX, pts[3].fX);
47 wellBehaved &= between(pts[0].fY, pts[1].fY, pts[3].fY);
48 wellBehaved &= between(pts[0].fX, pts[2].fX, pts[3].fX);
49 wellBehaved &= between(pts[0].fY, pts[2].fY, pts[3].fY);
50 break;
51 default:
52 break;
53 }
54 }
55 if (wellBehaved) {
56 *result = path.getBounds();
57 return true;
58 }
59 SkSTArenaAlloc<4096> allocator; // FIXME: constant-ize, tune
61 SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
62 SkOpGlobalState globalState(contourList, &allocator SkDEBUGPARAMS(false)
63 SkDEBUGPARAMS(nullptr));
64 // turn path into list of segments
65 SkOpEdgeBuilder builder(path, contourList, &globalState);
66 if (!builder.finish()) {
67 return false;
68 }
69 if (!SortContourList(&contourList, false, false)) {
70 *result = moveBounds;
71 return true;
72 }
73 SkOpContour* current = contourList;
74 SkPathOpsBounds bounds = current->bounds();
75 while ((current = current->next())) {
76 bounds.add(current->bounds());
77 }
78 *result = bounds;
79 if (!moveBounds.isEmpty()) {
80 result->join(moveBounds);
81 }
82 return true;
83}
bool SortContourList(SkOpContourHead **contourList, bool evenOdd, bool oppEvenOdd)
bool between(double a, double b, double c)
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
#define SK_ScalarMin
Definition: SkScalar.h:25
#define SK_ScalarMax
Definition: SkScalar.h:24
const SkPathOpsBounds & bounds() const
Definition: SkOpContour.h:68
SkOpContour * next()
Definition: SkOpContour.h:266
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
Optional< SkRect > bounds
Definition: SkRecords.h:189
SkScalar w
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
bool isEmpty() const
Definition: SkRect.h:693
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15