Add bounding rect for paths
Review URL: http://codereview.appspot.com/4442094/
git-svn-id: http://skia.googlecode.com/svn/trunk@1205 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrPath.h b/gpu/include/GrPath.h
index 80bbeb3..f958329 100644
--- a/gpu/include/GrPath.h
+++ b/gpu/include/GrPath.h
@@ -22,6 +22,7 @@
#include "GrPathIter.h"
#include "GrTDArray.h"
#include "GrPoint.h"
+#include "GrRect.h"
class GrPath : public GrPathSink {
public:
@@ -33,6 +34,8 @@
GrConvexHint getConvexHint() const { return fConvexHint; }
void setConvexHint(GrConvexHint hint) { fConvexHint = hint; }
+ const GrRect& getConservativeBounds() const { return fConservativeBounds; }
+
void resetFromIter(GrPathIter*);
bool operator ==(const GrPath& path) const;
@@ -66,6 +69,7 @@
virtual GrConvexHint convexHint() const;
virtual GrPathCmd next();
virtual void rewind();
+ virtual bool getConservativeBounds(GrRect* rect) const;
/**
* Sets iterator to begining of path
@@ -84,7 +88,8 @@
GrTDArray<GrPathCmd> fCmds;
GrTDArray<GrPoint> fPts;
- GrConvexHint fConvexHint;
+ GrConvexHint fConvexHint;
+ GrRect fConservativeBounds;
// this ensures we have a moveTo at the start of each contour
inline void ensureMoveTo();
diff --git a/gpu/include/GrPathIter.h b/gpu/include/GrPathIter.h
index 55427c0..5261f0f 100644
--- a/gpu/include/GrPathIter.h
+++ b/gpu/include/GrPathIter.h
@@ -21,6 +21,7 @@
#include "GrTypes.h"
struct GrPoint;
+struct GrRect;
/**
2D Path iterator. Porting layer creates a subclass of this. It allows Ganesh to
@@ -60,6 +61,12 @@
*/
virtual GrPathCmd next() = 0;
+ /**
+ * Returns conservative bounds on the path points. If returns false then
+ * no bounds are available.
+ */
+ virtual bool getConservativeBounds(GrRect* rect) const = 0;
+
/**
Restarts iteration from the beginning.
*/
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
index b85574a..8a63cdc 100644
--- a/gpu/include/GrRect.h
+++ b/gpu/include/GrRect.h
@@ -225,6 +225,15 @@
}
/**
+ * Returns true if the rect contains the point or the
+ * point lies on the edge of the rect.
+ */
+ bool containsInclusive(const GrPoint& point) const {
+ return point.fX >= fLeft && point.fX <= fRight &&
+ point.fY >= fTop && point.fY <= fBottom;
+ }
+
+ /**
* Does this rect fully contain another rect.
*/
bool contains(const GrRect& r) const {
@@ -333,6 +342,14 @@
fBottom = GrMax(pt.fY, fBottom);
}
+ void growToInclude(GrScalar x, GrScalar y) {
+ fLeft = GrMin(x, fLeft);
+ fRight = GrMax(y, fRight);
+
+ fTop = GrMin(x, fTop);
+ fBottom = GrMax(y, fBottom);
+ }
+
/**
* Grows a rect to include another rect.
* @param rect the rect to include
@@ -390,6 +407,14 @@
}
}
+ void translate(GrScalar tx, GrScalar ty) {
+ fLeft += tx;
+ fRight += tx;
+
+ fTop += ty;
+ fBottom += ty;
+ }
+
bool operator ==(const GrRect& r) const {
return fLeft == r.fLeft &&
fTop == r.fTop &&
diff --git a/gpu/src/GrPath.cpp b/gpu/src/GrPath.cpp
index a740dfc..17ecd5d 100644
--- a/gpu/src/GrPath.cpp
+++ b/gpu/src/GrPath.cpp
@@ -2,6 +2,7 @@
GrPath::GrPath() {
fConvexHint = kNone_ConvexHint;
+ fConservativeBounds.setLargestInverted();
}
GrPath::GrPath(const GrPath& src) : INHERITED() {
@@ -40,6 +41,7 @@
if (fCmds.isEmpty() || this->wasLastVerb(kClose_PathCmd)) {
*fCmds.append() = kMove_PathCmd;
fPts.append()->set(0, 0);
+ fConservativeBounds.growToInclude(0,0);
}
}
@@ -51,12 +53,14 @@
*fCmds.append() = kMove_PathCmd;
fPts.append()->set(x, y);
}
+ fConservativeBounds.growToInclude(x,y);
}
void GrPath::lineTo(GrScalar x, GrScalar y) {
this->ensureMoveTo();
*fCmds.append() = kLine_PathCmd;
fPts.append()->set(x, y);
+ fConservativeBounds.growToInclude(x,y);
}
void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
@@ -64,6 +68,8 @@
*fCmds.append() = kQuadratic_PathCmd;
fPts.append()->set(x0, y0);
fPts.append()->set(x1, y1);
+ fConservativeBounds.growToInclude(x0,y0);
+ fConservativeBounds.growToInclude(x1,y1);
}
void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
@@ -73,6 +79,9 @@
fPts.append()->set(x0, y0);
fPts.append()->set(x1, y1);
fPts.append()->set(x2, y2);
+ fConservativeBounds.growToInclude(x0,y0);
+ fConservativeBounds.growToInclude(x1,y1);
+ fConservativeBounds.growToInclude(x2,y2);
}
void GrPath::close() {
@@ -95,6 +104,7 @@
iter->offset(tx, ty);
++iter;
}
+ fConservativeBounds.translate(tx, ty);
}
///////////////////////////////////////////////////////////////////////////////
@@ -148,6 +158,7 @@
void GrPath::resetFromIter(GrPathIter* iter) {
fPts.reset();
fCmds.reset();
+ fConservativeBounds.setLargestInverted();
fConvexHint = iter->convexHint();
@@ -209,6 +220,9 @@
break;
}
int n = NumPathCmdPoints(cmd);
+ for (int i = 0; i < n; ++i) {
+ fConservativeBounds.growToInclude(pts[i]);
+ }
if (0 == subPathPts && n > 0) {
previousPt = pts[0];
firstPt = previousPt;
@@ -427,6 +441,7 @@
}
fLastPt = srcPts[0];
GrAssert(fPtIndex <= fPath->fPts.count() + 1);
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
fPtIndex += 1;
break;
case kLine_PathCmd:
@@ -436,6 +451,7 @@
}
fLastPt = srcPts[0];
GrAssert(fPtIndex <= fPath->fPts.count() + 1);
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
fPtIndex += 1;
break;
case kQuadratic_PathCmd:
@@ -446,6 +462,8 @@
}
fLastPt = srcPts[1];
GrAssert(fPtIndex <= fPath->fPts.count() + 2);
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[1]));
fPtIndex += 2;
break;
case kCubic_PathCmd:
@@ -457,6 +475,9 @@
}
fLastPt = srcPts[2];
GrAssert(fPtIndex <= fPath->fPts.count() + 3);
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[1]));
+ GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[2]));
fPtIndex += 3;
break;
case kClose_PathCmd:
@@ -485,4 +506,11 @@
fCmdIndex = fPtIndex = 0;
}
+bool GrPath::Iter::getConservativeBounds(GrRect* rect) const {
+ if (!fPath->getConservativeBounds().isEmpty()) {
+ *rect = fPath->getConservativeBounds();
+ return true;
+ }
+ return false;
+}
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 10f1bd0..bcb6766 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -169,6 +169,7 @@
virtual GrPathCmd next();
virtual void rewind();
virtual GrConvexHint convexHint() const;
+ virtual bool getConservativeBounds(GrRect* rect) const;
void reset(const SkPath& path) {
fPath = &path;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index f6e1425..23918f9 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -143,6 +143,11 @@
kNone_ConvexHint;
}
+bool SkGrPathIter::getConservativeBounds(GrRect* rect) const {
+ *rect = Sk2Gr(fPath->getBounds());
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////
void SkGrClipIterator::reset(const SkClipStack& clipStack) {