Store SkRRects in SkClipStack
BUG=skia:2181
R=robertphillips@google.com
Author: bsalomon@google.com
Review URL: https://codereview.chromium.org/163683002
git-svn-id: http://skia.googlecode.com/svn/trunk@13465 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkClipStack.h b/include/core/SkClipStack.h
index 0d6cfb2..0896db4 100644
--- a/include/core/SkClipStack.h
+++ b/include/core/SkClipStack.h
@@ -11,6 +11,7 @@
#include "SkDeque.h"
#include "SkPath.h"
#include "SkRect.h"
+#include "SkRRect.h"
#include "SkRegion.h"
#include "SkTDArray.h"
@@ -41,6 +42,8 @@
kEmpty_Type,
//!< This element combines a rect with the current clip using a set operation
kRect_Type,
+ //!< This element combines a round-rect with the current clip using a set operation
+ kRRect_Type,
//!< This element combines a path with the current clip using a set operation
kPath_Type,
};
@@ -54,46 +57,35 @@
this->initRect(0, rect, op, doAA);
}
+ Element(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ this->initRRect(0, rrect, op, doAA);
+ }
+
Element(const SkPath& path, SkRegion::Op op, bool doAA) {
this->initPath(0, path, op, doAA);
}
- bool operator== (const Element& element) const {
- if (this == &element) {
- return true;
- }
- if (fOp != element.fOp ||
- fType != element.fType ||
- fDoAA != element.fDoAA ||
- fSaveCount != element.fSaveCount) {
- return false;
- }
- switch (fType) {
- case kPath_Type:
- return fPath == element.fPath;
- case kRect_Type:
- return fRect == element.fRect;
- case kEmpty_Type:
- return true;
- default:
- SkDEBUGFAIL("Unexpected type.");
- return false;
- }
- }
+ bool operator== (const Element& element) const;
bool operator!= (const Element& element) const { return !(*this == element); }
//!< Call to get the type of the clip element.
Type getType() const { return fType; }
//!< Call if getType() is kPath to get the path.
- const SkPath& getPath() const { return fPath; }
+ const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return fPath; }
+
+ //!< Call if getType() is kRRect to get the round-rect.
+ const SkRRect& getRRect() const { SkASSERT(kRRect_Type == fType); return fRRect; }
//!< Call if getType() is kRect to get the rect.
- const SkRect& getRect() const { return fRect; }
+ const SkRect& getRect() const { SkASSERT(kRect_Type == fType); return fRect; }
//!< Call if getType() is not kEmpty to get the set operation used to combine this element.
SkRegion::Op getOp() const { return fOp; }
+ //!< Call to get the element as a path, regardless of its type.
+ void asPath(SkPath* path) const;
+
/** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased
when it is rasterized. */
bool isAA() const { return fDoAA; }
@@ -120,6 +112,8 @@
switch (fType) {
case kRect_Type:
return fRect;
+ case kRRect_Type:
+ return fRRect.getBounds();
case kPath_Type:
return fPath.getBounds();
case kEmpty_Type:
@@ -138,6 +132,8 @@
switch (fType) {
case kRect_Type:
return fRect.contains(rect);
+ case kRRect_Type:
+ return fRRect.contains(rect);
case kPath_Type:
return fPath.conservativelyContainsRect(rect);
case kEmpty_Type:
@@ -160,6 +156,7 @@
SkPath fPath;
SkRect fRect;
+ SkRRect fRRect;
int fSaveCount; // save count of stack when this element was added.
SkRegion::Op fOp;
Type fType;
@@ -189,6 +186,10 @@
this->setEmpty();
}
+ Element(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ this->initRRect(saveCount, rrect, op, doAA);
+ }
+
Element(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) {
this->initRect(saveCount, rect, op, doAA);
}
@@ -215,20 +216,29 @@
this->initCommon(saveCount, op, doAA);
}
- void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) {
- fPath = path;
- fType = kPath_Type;
+ void initRRect(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+ if (rrect.isRect()) {
+ fRect = rrect.getBounds();
+ fType = kRect_Type;
+ } else {
+ fRRect = rrect;
+ fType = kRRect_Type;
+ }
this->initCommon(saveCount, op, doAA);
}
+ void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA);
+
void setEmpty() {
fType = kEmpty_Type;
fFiniteBound.setEmpty();
fFiniteBoundType = kNormal_BoundsType;
fIsIntersectionOfRects = false;
fRect.setEmpty();
+ fRRect.setEmpty();
fPath.reset();
fGenID = kEmptyGenID;
+ SkDEBUGCODE(this->checkEmpty();)
}
// All Element methods below are only used within SkClipStack.cpp
@@ -305,6 +315,7 @@
this->clipDevRect(r, op, false);
}
void clipDevRect(const SkRect&, SkRegion::Op, bool doAA);
+ void clipDevRRect(const SkRRect&, SkRegion::Op, bool doAA);
void clipDevPath(const SkPath&, SkRegion::Op, bool doAA);
// An optimized version of clipDevRect(emptyRect, kIntersect, ...)
void clipEmpty();
@@ -428,6 +439,11 @@
static int32_t gGenID;
/**
+ * Helper for clipDevPath, etc.
+ */
+ void pushElement(const Element& element);
+
+ /**
* Restore the stack back to the specified save count.
*/
void restoreTo(int saveCount);