Added isIntersectionOfRects to SkClipStack
http://codereview.appspot.com/6434050/
git-svn-id: http://skia.googlecode.com/svn/trunk@4745 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 2676f3b..7857bdf 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -38,13 +38,15 @@
// of the extensions to infinity when two inverse filled clips are
// Booleaned together.
SkClipStack::BoundsType fFiniteBoundType;
- SkRect fFiniteBound;
+ SkRect fFiniteBound;
+ bool fIsIntersectionOfRects;
Rec(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) : fRect(rect) {
fSaveCount = saveCount;
fOp = op;
fState = kRect_State;
fDoAA = doAA;
+ // bounding box members are updated in a following updateBound call
}
Rec(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) : fPath(path) {
@@ -53,6 +55,7 @@
fOp = op;
fState = kPath_State;
fDoAA = doAA;
+ // bounding box members are updated in a following updateBound call
}
bool operator==(const Rec& b) const {
@@ -273,9 +276,17 @@
// First, optimistically update the current Rec's bound information
// with the current clip's bound
+ fIsIntersectionOfRects = false;
if (kRect_State == fState) {
fFiniteBound = fRect;
fFiniteBoundType = kNormal_BoundsType;
+
+ if (SkRegion::kReplace_Op == fOp ||
+ (SkRegion::kIntersect_Op == fOp && NULL == prior) ||
+ (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects)) {
+ fIsIntersectionOfRects = true;
+ }
+
} else {
fFiniteBound = fPath.getBounds();
@@ -432,7 +443,9 @@
}
}
-void SkClipStack::getBounds(SkRect* finiteBound, BoundsType* boundType) const {
+void SkClipStack::getBounds(SkRect* finiteBound,
+ BoundsType* boundType,
+ bool* isIntersectionOfRects) const {
SkASSERT(NULL != finiteBound && NULL != boundType);
Rec* rec = (Rec*)fDeque.back();
@@ -441,36 +454,50 @@
// the clip is wide open - the infinite plane w/ no pixels un-writeable
finiteBound->setEmpty();
*boundType = kInsideOut_BoundsType;
+ if (NULL != isIntersectionOfRects) {
+ *isIntersectionOfRects = false;
+ }
return;
}
*finiteBound = rec->fFiniteBound;
*boundType = rec->fFiniteBoundType;
+ if (NULL != isIntersectionOfRects) {
+ *isIntersectionOfRects = rec->fIsIntersectionOfRects;
+ }
}
void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
- Rec* rec = (Rec*)fDeque.back();
+
+ SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart);
+ Rec* rec = (Rec*) iter.prev();
+
if (rec && rec->canBeIntersected(fSaveCount, op)) {
switch (rec->fState) {
case Rec::kEmpty_State:
SkASSERT(rec->fFiniteBound.isEmpty());
SkASSERT(kNormal_BoundsType == rec->fFiniteBoundType);
+ SkASSERT(!rec->fIsIntersectionOfRects);
return;
- case Rec::kRect_State:
+ case Rec::kRect_State: {
if (!rec->fRect.intersect(rect)) {
rec->fState = Rec::kEmpty_State;
rec->fFiniteBound.setEmpty();
rec->fFiniteBoundType = kNormal_BoundsType;
+ rec->fIsIntersectionOfRects = false;
return;
}
- rec->updateBound(NULL);
+ Rec* prev = (Rec*) iter.prev();
+ rec->updateBound(prev);
return;
+ }
case Rec::kPath_State:
if (!SkRect::Intersects(rec->fPath.getBounds(), rect)) {
rec->fState = Rec::kEmpty_State;
rec->fFiniteBound.setEmpty();
rec->fFiniteBoundType = kNormal_BoundsType;
+ rec->fIsIntersectionOfRects = false;
return;
}
break;
@@ -492,12 +519,14 @@
case Rec::kEmpty_State:
SkASSERT(rec->fFiniteBound.isEmpty());
SkASSERT(kNormal_BoundsType == rec->fFiniteBoundType);
+ SkASSERT(!rec->fIsIntersectionOfRects);
return;
case Rec::kRect_State:
if (!SkRect::Intersects(rec->fRect, pathBounds)) {
rec->fState = Rec::kEmpty_State;
rec->fFiniteBound.setEmpty();
rec->fFiniteBoundType = kNormal_BoundsType;
+ rec->fIsIntersectionOfRects = false;
return;
}
break;
@@ -506,6 +535,7 @@
rec->fState = Rec::kEmpty_State;
rec->fFiniteBound.setEmpty();
rec->fFiniteBoundType = kNormal_BoundsType;
+ rec->fIsIntersectionOfRects = false;
return;
}
break;
@@ -627,7 +657,8 @@
int offsetY,
int maxWidth,
int maxHeight,
- SkRect* bounds) const {
+ SkRect* bounds,
+ bool* isIntersectionOfRects) const {
SkASSERT(NULL != bounds);
bounds->setLTRB(0, 0,
@@ -636,7 +667,7 @@
SkRect temp;
SkClipStack::BoundsType boundType;
- this->getBounds(&temp, &boundType);
+ this->getBounds(&temp, &boundType, isIntersectionOfRects);
if (SkClipStack::kInsideOut_BoundsType == boundType) {
return;
}