23#include <initializer_list>
126 while (iter.
next()) {
137 static const SkRect gRects[] = {
144 for (
size_t i = 0; i < std::size(gRects); i++) {
158 for (i = 0, element = iter.
next(); element; ++i, element = iter.
next()) {
174 for (i = 3, element = iter.
prev(); element; --i, element = iter.
prev()) {
199 static const int gNumCases = 8;
200 static const SkRect gAnswerRectsBW[gNumCases] = {
239 bool isIntersectionOfRects =
false;
243 for (
int invBits = 0; invBits < numBitTests; ++invBits) {
244 for (
size_t op = 0; op < std::size(gOps); ++op) {
247 bool doInvA =
SkToBool(invBits & 1);
248 bool doInvB =
SkToBool(invBits & 2);
258 SkDEBUGFAIL(
"Don't call this with kEmpty or kShader.");
278 &isIntersectionOfRects);
356 for (element = iter.
prev(); element; element = iter.
prev(), ++
count) {
368 path.toggleInverseFillType();
385 bool isIntersectionOfRects;
463 path.addCircle(50, 50, 50);
472 replacePath(&stack, path,
false);
474 replacePath(&stack, path,
false);
483 replacePath(&stack, path,
true);
500 bool isIntersectionOfRects;
590 SkPath intersectingCircle;
591 intersectingCircle.
addCircle(25, 40, 10);
594 SkPath nonIntersectingCircle;
595 nonIntersectingCircle.
addCircle(100, 100, 5);
692 path.addRect(outsideRect);
693 path.toggleInverseFillType();
701 path.addRect(insideRect);
702 path.toggleInverseFillType();
710 path.addRect(intersectingRect);
711 path.toggleInverseFillType();
719 path.addRect(nonIntersectingRect);
720 path.toggleInverseFillType();
728 SkPath path = outsideCircle;
729 path.toggleInverseFillType();
736 SkPath path = insideCircle;
737 path.toggleInverseFillType();
744 SkPath path = intersectingCircle;
745 path.toggleInverseFillType();
752 SkPath path = nonIntersectingCircle;
753 path.toggleInverseFillType();
767 switch (element->getDeviceSpaceType()) {
772 element->asDeviceSpacePath(&path);
773 elemRegion.
setPath(path, boundsRgn);
787 path.addRect({30, 10, 40, 20});
795 stack.
getBounds(&stackBounds, &stackBoundsType);
811 for (
bool aa : {
false,
true}) {
813 for (
int i = 0; i <= 100; ++i) {
822 if (stack.
isRRect(kTargetBounds, &rrect, &isAA)) {
831 for (
int i = 0; i <= 100; ++i) {
849 static const SkIRect gRects[] = {
851 { 25, 25, 125, 125 },
852 { 0, 0, 1000, 1000 },
855 for (
size_t i = 0; i < std::size(gRects); i++) {
863 answer.
setLTRB(25, 25, 75, 75);
static void assert_count(skiatest::Reporter *reporter, const SkClipStack &stack, int count)
static void test_rect_merging(skiatest::Reporter *reporter)
static void set_region_to_stack(const SkClipStack &stack, const SkIRect &bounds, SkRegion *region)
static void test_rect_inverse_fill(skiatest::Reporter *reporter)
static void test_bounds(skiatest::Reporter *reporter, SkClipStack::Element::DeviceSpaceType primType)
static void test_is_rrect_deep_rect_stack(skiatest::Reporter *reporter)
static void test_assign_and_comparison(skiatest::Reporter *reporter)
static void test_rect_replace(skiatest::Reporter *reporter)
static void test_isWideOpen(skiatest::Reporter *reporter)
static void test_iterators(skiatest::Reporter *reporter)
static void test_path_replace(skiatest::Reporter *reporter)
static void test_invfill_diff_bug(skiatest::Reporter *reporter)
static void test_quickContains(skiatest::Reporter *reporter)
#define SkDEBUGFAIL(message)
static constexpr bool SkToBool(const T &x)
#define DEF_TEST(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
@ kPath
This element does not have geometry, but applies a shader to the clip.
@ kEmpty
This element makes the clip empty (regardless of previous elements).
@ kRect
This element combines a device space round-rect with the current clip.
@ kRRect
This element combines a device space path with the current clip.
const SkRect & getDeviceSpaceRect() const
Call if getDeviceSpaceType() is kShader to get a reference to the clip shader.
DeviceSpaceType getDeviceSpaceType() const
Call to get the save count associated with this clip element.
const Element * skipToTopmost(SkClipOp op)
void clipRect(const SkRect &, const SkMatrix &matrix, SkClipOp, bool doAA)
bool isRRect(const SkRect &bounds, SkRRect *rrect, bool *aa) const
static const uint32_t kEmptyGenID
void clipRRect(const SkRRect &, const SkMatrix &matrix, SkClipOp, bool doAA)
bool quickContains(const SkRect &devRect) const
void getBounds(SkRect *canvFiniteBound, BoundsType *boundType, bool *isIntersectionOfRects=nullptr) const
void clipDevRect(const SkIRect &ir, SkClipOp op)
void getConservativeBounds(int offsetX, int offsetY, int maxWidth, int maxHeight, SkRect *devBounds, bool *isIntersectionOfRects=nullptr) const
uint32_t getTopmostGenID() const
static const uint32_t kWideOpenGenID
void clipPath(const SkPath &, const SkMatrix &matrix, SkClipOp, bool doAA)
void replaceClip(const SkRect &devRect, bool doAA)
static const SkMatrix & I()
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
void setFillType(SkPathFillType ft)
SkPath & addRoundRect(const SkRect &rect, SkScalar rx, SkScalar ry, SkPathDirection dir=SkPathDirection::kCW)
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
static SkRRect MakeRect(const SkRect &r)
void setOval(const SkRect &oval)
void setRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
@ kReplace_Op
replace target with operand
bool op(const SkIRect &rect, Op op)
bool setRect(const SkIRect &rect)
bool setPath(const SkPath &path, const SkRegion &clip)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
constexpr float height() const
void setLTRB(float left, float top, float right, float bottom)
constexpr float width() const
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)