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
This commit is contained in:
bsalomon@google.com 2011-04-27 21:13:04 +00:00
parent 31a5840ac8
commit 06e1795cd9
6 changed files with 72 additions and 1 deletions

View File

@ -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 @@ public:
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 @@ public:
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 @@ private:
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();

View File

@ -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 @@ public:
*/
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.
*/

View File

@ -224,6 +224,15 @@ struct GrRect {
point.fY >= fTop && point.fY < fBottom;
}
/**
* 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.
*/
@ -333,6 +342,14 @@ struct GrRect {
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 @@ struct GrRect {
}
}
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 &&

View File

@ -2,6 +2,7 @@
GrPath::GrPath() {
fConvexHint = kNone_ConvexHint;
fConservativeBounds.setLargestInverted();
}
GrPath::GrPath(const GrPath& src) : INHERITED() {
@ -40,6 +41,7 @@ void GrPath::ensureMoveTo() {
if (fCmds.isEmpty() || this->wasLastVerb(kClose_PathCmd)) {
*fCmds.append() = kMove_PathCmd;
fPts.append()->set(0, 0);
fConservativeBounds.growToInclude(0,0);
}
}
@ -51,12 +53,14 @@ void GrPath::moveTo(GrScalar x, GrScalar y) {
*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 @@ void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
*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 @@ void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
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 @@ void GrPath::offset(GrScalar tx, GrScalar ty) {
iter->offset(tx, ty);
++iter;
}
fConservativeBounds.translate(tx, ty);
}
///////////////////////////////////////////////////////////////////////////////
@ -148,6 +158,7 @@ static void init_from_two_vecs(const GrVec& firstVec,
void GrPath::resetFromIter(GrPathIter* iter) {
fPts.reset();
fCmds.reset();
fConservativeBounds.setLargestInverted();
fConvexHint = iter->convexHint();
@ -209,6 +220,9 @@ void GrPath::resetFromIter(GrPathIter* iter) {
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 @@ GrPathCmd GrPath::Iter::next(GrPoint points[]) {
}
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 @@ GrPathCmd GrPath::Iter::next(GrPoint points[]) {
}
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 @@ GrPathCmd GrPath::Iter::next(GrPoint points[]) {
}
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 @@ GrPathCmd GrPath::Iter::next(GrPoint points[]) {
}
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 @@ void GrPath::Iter::reset(const GrPath& path) {
fCmdIndex = fPtIndex = 0;
}
bool GrPath::Iter::getConservativeBounds(GrRect* rect) const {
if (!fPath->getConservativeBounds().isEmpty()) {
*rect = fPath->getConservativeBounds();
return true;
}
return false;
}

View File

@ -169,6 +169,7 @@ public:
virtual GrPathCmd next();
virtual void rewind();
virtual GrConvexHint convexHint() const;
virtual bool getConservativeBounds(GrRect* rect) const;
void reset(const SkPath& path) {
fPath = &path;

View File

@ -143,6 +143,11 @@ GrConvexHint SkGrPathIter::convexHint() const {
kNone_ConvexHint;
}
bool SkGrPathIter::getConservativeBounds(GrRect* rect) const {
*rect = Sk2Gr(fPath->getBounds());
return true;
}
///////////////////////////////////////////////////////////////////////////////
void SkGrClipIterator::reset(const SkClipStack& clipStack) {