Share code with SkRect

http://codereview.appspot.com/4523046/



git-svn-id: http://skia.googlecode.com/svn/trunk@1277 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-05-09 17:00:02 +00:00
parent 59f9961d00
commit 20efde71b4
14 changed files with 149 additions and 549 deletions

View File

@ -18,9 +18,7 @@
#ifndef GrMatrix_DEFINED
#define GrMatrix_DEFINED
#include "GrPoint.h"
struct GrRect;
#include "GrRect.h"
/*
* 3x3 matrix

View File

@ -18,9 +18,7 @@
#ifndef GrPathIter_DEFINED
#define GrPathIter_DEFINED
#include "GrPoint.h"
struct GrRect;
#include "GrRect.h"
/**
2D Path iterator. Porting layer creates a subclass of this. It allows Ganesh to

View File

@ -19,465 +19,24 @@
#define GrRect_DEFINED
#include "GrPoint.h"
#include "SkRect.h"
struct GrIRect {
int32_t fLeft, fTop, fRight, fBottom;
GrIRect() {}
GrIRect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
fLeft = left;
fTop = top;
fRight = right;
fBottom = bottom;
}
int32_t x() const { return fLeft; }
int32_t y() const { return fTop; }
int32_t width() const { return fRight - fLeft; }
int32_t height() const { return fBottom - fTop; }
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
bool isInverted() const { return fLeft > fRight || fTop > fBottom; }
void setEmpty() { fLeft = fTop = fRight = fBottom = 0; }
void setXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
fLeft = x;
fTop = y;
fRight = x + w;
fBottom = y + h;
}
void setLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
fLeft = l;
fTop = t;
fRight = r;
fBottom = b;
}
/**
* Make the largest representable rectangle
*/
void setLargest() {
fLeft = fTop = GR_Int32Min;
fRight = fBottom = GR_Int32Max;
}
void setLargestInverted() {
fLeft = fTop = GR_Int32Max;
fRight = fBottom = GR_Int32Min;
}
bool quickReject(int l, int t, int r, int b) const {
return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
}
void unionWith(const GrIRect& r) {
if (fLeft > r.fLeft) fLeft = r.fLeft;
if (fTop > r.fTop) fTop = r.fTop;
if (fRight < r.fRight) fRight = r.fRight;
if (fBottom < r.fBottom) fBottom = r.fBottom;
}
/**
* Sets this rect to the intersection with a clip rect. If there is no
* intersection then this rect will be made empty and the function will
* return false.
*/
bool intersectWith(const GrIRect& clipRect) {
if (fRight < clipRect.fLeft ||
fLeft > clipRect.fRight ||
fBottom < clipRect.fTop ||
fTop > clipRect.fBottom) {
this->setEmpty();
return false;
} else {
fLeft = GrMax(fLeft, clipRect.fLeft);
fRight = GrMin(fRight, clipRect.fRight);
fTop = GrMax(fTop, clipRect.fTop);
fBottom = GrMin(fBottom, clipRect.fBottom);
return true;
}
}
bool intersectWith(int left, int top,
int right, int bottom) {
if (fRight < left ||
fLeft > right ||
fBottom < top ||
fTop > bottom) {
this->setEmpty();
return false;
} else {
fLeft = GrMax(fLeft, left);
fRight = GrMin(fRight, right);
fTop = GrMax(fTop, top);
fBottom = GrMin(fBottom, bottom);
return true;
}
}
/**
* Enlarge the rectangle to include rect.
*/
void growToInclude(const GrIRect& rect) {
GrAssert(!rect.isEmpty());
fLeft = GrMin(rect.fLeft, fLeft);
fRight = GrMax(rect.fRight, fRight);
fTop = GrMin(rect.fTop, fTop);
fBottom = GrMax(rect.fBottom, fBottom);
}
friend bool operator==(const GrIRect& a, const GrIRect& b) {
return 0 == memcmp(&a, &b, sizeof(a));
}
friend bool operator!=(const GrIRect& a, const GrIRect& b) {
return 0 != memcmp(&a, &b, sizeof(a));
}
bool equalsLTRB(int l, int t, int r, int b) const {
return fLeft == l && fTop == t &&
fRight == r && fBottom == b;
}
bool equalsXYWH(int x, int y, int w, int h) const {
return fLeft == x && fTop == y &&
this->width() == w && this->height() == h;
}
bool contains(const GrIRect& r) const {
return fLeft <= r.fLeft &&
fRight >= r.fRight &&
fTop <= r.fTop &&
fBottom >= r.fBottom;
}
static const GrIRect& EmptyIRect() {
static const GrIRect gEmpty(0,0,0,0);
return gEmpty;
}
};
typedef SkIRect GrIRect;
typedef SkRect GrRect;
struct GrIRect16 {
int16_t fLeft, fTop, fRight, fBottom;
int width() const { return fRight - fLeft; }
int height() const { return fBottom - fTop; }
int area() const { return this->width() * this->height(); }
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
void set(const GrIRect& r) {
fLeft = GrToS16(r.fLeft);
fTop = GrToS16(r.fTop);
fRight = GrToS16(r.fRight);
fBottom = GrToS16(r.fBottom);
}
};
/**
* 2D Rect struct
*/
struct GrRect {
GrScalar fLeft, fTop, fRight, fBottom;
/**
* Uninitialized rectangle.
*/
GrRect() {}
/**
* Initialize a rectangle to a point.
* @param pt the point used to initialize the rectanglee.
*/
explicit GrRect(const GrPoint& pt) {
setToPoint(pt);
}
GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
fLeft = left;
fTop = top;
fRight = right;
fBottom = bottom;
}
explicit GrRect(const GrIRect& src) {
fLeft = GrIntToScalar(src.fLeft);
fTop = GrIntToScalar(src.fTop);
fRight = GrIntToScalar(src.fRight);
fBottom = GrIntToScalar(src.fBottom);
}
GrScalar x() const { return fLeft; }
GrScalar y() const { return fTop; }
GrScalar width() const { return fRight - fLeft; }
GrScalar height() const { return fBottom - fTop; }
GrScalar left() const { return fLeft; }
GrScalar top() const { return fTop; }
GrScalar right() const { return fRight; }
GrScalar bottom() const { return fBottom; }
GrScalar diagonalLengthSqd() const {
GrScalar w = width();
GrScalar h = height();
return GrMul(w, w) + GrMul(h, h);
}
GrScalar diagonalLength() const {
// TODO: fixed point sqrt
return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
}
/**
* Returns true if the width or height is <= 0
*/
bool isEmpty() const {
return fLeft >= fRight || fTop >= fBottom;
}
void setEmpty() {
fLeft = fTop = fRight = fBottom = 0;
}
/**
* returns true if the rectangle is inverted either in x or y
*/
bool isInverted() const {
return (fLeft > fRight) || (fTop > fBottom);
}
/**
* Returns true if the rects edges are integer-aligned.
*/
bool isIRect() const {
return GrScalarIsInt(fLeft) && GrScalarIsInt(fTop) &&
GrScalarIsInt(fRight) && GrScalarIsInt(fBottom);
}
/**
* Does this rect contain a point.
*/
bool contains(const GrPoint& point) const {
return point.fX >= fLeft && point.fX < fRight &&
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.
*/
bool contains(const GrRect& r) const {
return fLeft <= r.fLeft &&
fRight >= r.fRight &&
fTop <= r.fTop &&
fBottom >= r.fBottom;
}
/**
* Offset the rectangle by (tx, ty), adding tx to the horizontal position
* and adds ty to the vertical position.
*/
void offset(GrScalar tx, GrScalar ty) {
fLeft += tx; fTop += ty;
fRight += tx; fBottom += ty;
}
/**
* Inset the rectangle by dx,dy. If dx > 0 the rect becomes narrower,
* if dx < 0 the rect becomes wider.
*/
void inset(GrScalar dx, GrScalar dy) {
fLeft += dx; fTop += dy;
fRight -= dx; fBottom -= dy;
}
/**
* Initialize a rectangle to a point.
* @param pt the point used to initialize the rectangle.
*/
void setToPoint(const GrPoint& pt) {
fLeft = pt.fX;
fTop = pt.fY;
fRight = pt.fX;
fBottom = pt.fY;
}
void set(const GrIRect& r) {
fLeft = GrIntToScalar(r.fLeft);
fTop = GrIntToScalar(r.fTop);
fRight = GrIntToScalar(r.fRight);
fBottom = GrIntToScalar(r.fBottom);
}
void roundOut(GrIRect* r) const {
r->setLTRB(GrScalarFloorToInt(fLeft),
GrScalarFloorToInt(fTop),
GrScalarCeilToInt(fRight),
GrScalarCeilToInt(fBottom));
}
/**
* Set the rect to the union of the array of points. If the array is empty
* the rect will be empty [0,0,0,0]
*/
void setBounds(const GrPoint pts[], int count);
/**
* Make the largest representable rectangle
* Set the rect to fLeft = fTop = GR_ScalarMin and
* fRight = fBottom = GR_ScalarMax.
*/
void setLargest() {
fLeft = fTop = GR_ScalarMin;
fRight = fBottom = GR_ScalarMax;
}
/**
Set the rect to fLeft = fTop = GR_ScalarMax and
fRight = fBottom = GR_ScalarMin.
Useful for initializing a bounding rectangle.
*/
void setLargestInverted() {
fLeft = fTop = GR_ScalarMax;
fRight = fBottom = GR_ScalarMin;
}
void setLTRB(GrScalar left,
GrScalar top,
GrScalar right,
GrScalar bottom) {
fLeft = left;
fTop = top;
fRight = right;
fBottom = bottom;
}
void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
fLeft = x;
fTop = y;
fRight = x + width;
fBottom = y + height;
}
/**
Expand the edges of the rectangle to include a point.
Useful for constructing a bounding rectangle.
@param pt the point used to grow the rectangle.
*/
void growToInclude(const GrPoint& pt) {
fLeft = GrMin(pt.fX, fLeft);
fRight = GrMax(pt.fX, fRight);
fTop = GrMin(pt.fY, fTop);
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
*/
void growToInclude(const GrRect& rect) {
GrAssert(!rect.isEmpty());
fLeft = GrMin(rect.fLeft, fLeft);
fRight = GrMax(rect.fRight, fRight);
fTop = GrMin(rect.fTop, fTop);
fBottom = GrMax(rect.fBottom, fBottom);
}
/**
* Sets this rect to the intersection with a clip rect. If there is no
* intersection then this rect will be made empty.
*/
bool intersectWith(const GrRect& clipRect) {
if (fRight < clipRect.fLeft ||
fLeft > clipRect.fRight ||
fBottom < clipRect.fTop ||
fTop > clipRect.fBottom) {
this->setEmpty();
return false;
} else {
fLeft = GrMax(fLeft, clipRect.fLeft);
fRight = GrMin(fRight, clipRect.fRight);
fTop = GrMax(fTop, clipRect.fTop);
fBottom = GrMin(fBottom, clipRect.fBottom);
return true;
}
}
bool intersectWith(GrScalar left, GrScalar top,
GrScalar right, GrScalar bottom) {
if (fRight < left ||
fLeft > right ||
fBottom < top ||
fTop > bottom) {
this->setEmpty();
return false;
} else {
fLeft = GrMax(fLeft, left);
fRight = GrMin(fRight, right);
fTop = GrMax(fTop, top);
fBottom = GrMin(fBottom, bottom);
return true;
}
}
/**
* Assigns 4 sequential points in order to construct a counter-clockwise
* triangle fan, given the corners of this rect. Returns the address of
* the next point, treating pts as an array.
*/
GrPoint* setRectFan(GrPoint pts[4]) const {
pts->setRectFan(fLeft, fTop, fRight, fBottom);
return pts + 4;
}
/**
* Swaps (left and right) and/or (top and bottom) if they are inverted
*/
void sort() {
if (fLeft > fRight) {
GrScalar temp = fLeft;
fLeft = fRight;
fRight = temp;
}
if (fTop > fBottom) {
GrScalar temp = fTop;
fTop = fBottom;
fBottom = temp;
}
}
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 &&
fRight == r.fRight &&
fBottom == r.fBottom;
fLeft = SkToS16(r.fLeft);
fTop = SkToS16(r.fTop);
fRight = SkToS16(r.fRight);
fBottom = SkToS16(r.fBottom);
}
};

View File

@ -87,6 +87,12 @@ void GrClip::setFromIRect(const GrIRect& r) {
}
}
static void intersectWith(SkRect* dst, const SkRect& src) {
if (!dst->intersect(src)) {
dst->setEmpty();
}
}
void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* conservativeBounds) {
fList.reset();
@ -118,7 +124,7 @@ void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
rectCount = 1;
fList.pop_back();
GrAssert(kRect_ClipType == fList.back().fType);
fList.back().fRect.intersectWith(e.fRect);
intersectWith(&fList.back().fRect, e.fRect);
}
} else {
isectRectValid = false;

View File

@ -550,7 +550,7 @@ bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
// clip gets applied in second pass
target->disableState(GrDrawTarget::kClip_StateBit);
GrIRect clear(0, 0, scale * boundW, scale * boundH);
GrIRect clear = SkIRect::MakeWH(scale * boundW, scale * boundH);
target->clear(&clear, 0x0);
return true;
@ -590,15 +590,14 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
scale * GR_Scalar1 / src->height());
sampler.setMatrix(sampleM);
target->setSamplerState(kOffscreenStage, sampler);
GrRect rect(0, 0,
scale * boundRect.width(),
scale * boundRect.height());
GrRect rect = SkRect::MakeWH(scale * boundRect.width(),
scale * boundRect.height());
target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage);
src = record->fEntry1->texture();
} else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) {
scale = 1;
GrIRect rect(0, 0, boundRect.width(), boundRect.height());
GrIRect rect = SkIRect::MakeWH(boundRect.width(), boundRect.height());
src->asRenderTarget()->overrideResolveRect(rect);
} else {
GrAssert(OffscreenRecord::k4x4SinglePass_Downsample ==
@ -624,8 +623,9 @@ void GrContext::offscreenAAPass2(GrDrawTarget* target,
sampler.preConcatMatrix(sampleM);
target->setSamplerState(kOffscreenStage, sampler);
GrRect dstRect(boundRect);
GrRect dstRect;
int stages = (1 << kOffscreenStage) | (NULL == paint.getTexture() ? 0 : 1);
dstRect.set(boundRect);
target->drawSimpleRect(dstRect, NULL, stages);
this->unlockTexture(record->fEntry0);
@ -840,6 +840,14 @@ void GrContext::strokeAARect(GrDrawTarget* target, const GrPaint& paint,
0, 0, 16, aaStrokeRectIndexCount());
}
/**
* Returns true if the rects edges are integer-aligned.
*/
static bool isIRect(const GrRect& r) {
return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) &&
GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom);
}
static bool apply_aa_to_rect(GrDrawTarget* target,
GrGpu* gpu,
const GrPaint& paint,
@ -884,7 +892,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
devRect->sort();
if (width < 0) {
return !devRect->isIRect();
return !isIRect(*devRect);
} else {
return true;
}
@ -1163,13 +1171,12 @@ void GrContext::drawPath(const GrPaint& paint,
bool needsStencil = pr->requiresStencilPass(target, path, fill);
// compute bounds as intersection of rt size, clip, and path
GrIRect bound(0, 0,
target->getRenderTarget()->width(),
target->getRenderTarget()->height());
GrIRect bound = SkIRect::MakeWH(target->getRenderTarget()->width(),
target->getRenderTarget()->height());
if (target->getClip().hasConservativeBounds()) {
GrIRect clipIBounds;
target->getClip().getConservativeBounds().roundOut(&clipIBounds);
if (!bound.intersectWith(clipIBounds)) {
if (!bound.intersect(clipIBounds)) {
return;
}
}
@ -1178,7 +1185,7 @@ void GrContext::drawPath(const GrPaint& paint,
GrIRect pathIBounds;
target->getViewMatrix().mapRect(&pathBounds, pathBounds);
pathBounds.roundOut(&pathIBounds);
if (!bound.intersectWith(pathIBounds)) {
if (!bound.intersect(pathIBounds)) {
return;
}
}

View File

@ -399,7 +399,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
GrIntToScalar(rt.width()), GrIntToScalar(rt.height()));
if (fClip.hasConservativeBounds()) {
bounds = fClip.getConservativeBounds();
bounds.intersectWith(rtRect);
if (!bounds.intersect(rtRect)) {
bounds.setEmpty();
}
} else {
bounds = rtRect;
}

View File

@ -1175,10 +1175,9 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
if (NULL != rect) {
// flushScissor expects rect to be clipped to the target.
r = *rect;
GrIRect rtRect(0, 0,
fCurrDrawState.fRenderTarget->width(),
fCurrDrawState.fRenderTarget->height());
if (r.intersectWith(rtRect)) {
GrIRect rtRect = SkIRect::MakeWH(fCurrDrawState.fRenderTarget->width(),
fCurrDrawState.fRenderTarget->height());
if (r.intersect(rtRect)) {
rect = &r;
} else {
return;

View File

@ -717,33 +717,3 @@ int Gr_clz(uint32_t n) {
return count;
}
///////////////////////////////////////////////////////////////////////////////
#include "GrRect.h"
void GrRect::setBounds(const GrPoint pts[], int count) {
if (count <= 0) {
this->setEmpty();
} else {
GrScalar L, R, T, B;
L = R = pts[0].fX;
T = B = pts[0].fY;
for (int i = 1; i < count; i++) {
GrScalar x = pts[i].fX;
GrScalar y = pts[i].fY;
if (x < L) {
L = x;
} else if (x > R) {
R = x;
}
if (y < T) {
T = y;
} else if (y > B) {
B = y;
}
}
this->setLTRB(L, T, R, B);
}
}

View File

@ -104,7 +104,7 @@ void GrPath::offset(GrScalar tx, GrScalar ty) {
iter->offset(tx, ty);
++iter;
}
fConservativeBounds.translate(tx, ty);
fConservativeBounds.offset(tx, ty);
}
///////////////////////////////////////////////////////////////////////////////
@ -221,7 +221,7 @@ void GrPath::resetFromIter(GrPathIter* iter) {
}
int n = NumPathCmdPoints(cmd);
for (int i = 0; i < n; ++i) {
fConservativeBounds.growToInclude(pts[i]);
fConservativeBounds.growToInclude(pts[i].fX, pts[i].fY);
}
if (0 == subPathPts && n > 0) {
previousPt = pts[0];
@ -423,6 +423,13 @@ GrPath::Iter::Iter(const GrPath& path) : fPath(&path) {
this->rewind();
}
#ifdef SK_DEBUG
static bool containsInclusive(const GrRect& rect, const GrPoint& point) {
return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
point.fY >= rect.fTop && point.fY <= rect.fBottom;
}
#endif
GrPathCmd GrPath::Iter::next(GrPoint points[]) {
if (fCmdIndex == fPath->fCmds.count()) {
GrAssert(fPtIndex == fPath->fPts.count());
@ -441,7 +448,7 @@ GrPathCmd GrPath::Iter::next(GrPoint points[]) {
}
fLastPt = srcPts[0];
GrAssert(fPtIndex <= fPath->fPts.count() + 1);
GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
fPtIndex += 1;
break;
case kLine_PathCmd:
@ -451,7 +458,7 @@ GrPathCmd GrPath::Iter::next(GrPoint points[]) {
}
fLastPt = srcPts[0];
GrAssert(fPtIndex <= fPath->fPts.count() + 1);
GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
fPtIndex += 1;
break;
case kQuadratic_PathCmd:
@ -462,8 +469,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]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[1]));
fPtIndex += 2;
break;
case kCubic_PathCmd:
@ -475,9 +482,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]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[1]));
GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[2]));
fPtIndex += 3;
break;
case kClose_PathCmd:

View File

@ -32,8 +32,10 @@ bool GrRenderTarget::readPixels(int left, int top, int width, int height,
void GrRenderTarget::flagAsNeedingResolve(const GrIRect* rect) {
if (kCanResolve_ResolveType == getResolveType()) {
if (NULL != rect) {
fResolveRect.growToInclude(*rect);
fResolveRect.intersectWith(0, 0, this->width(), this->height());
fResolveRect.join(*rect);
if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
fResolveRect.setEmpty();
}
} else {
fResolveRect.setLTRB(0, 0, this->width(), this->height());
}
@ -45,7 +47,7 @@ void GrRenderTarget::overrideResolveRect(const GrIRect rect) {
if (fResolveRect.isEmpty()) {
fResolveRect.setLargestInverted();
} else {
if (!fResolveRect.intersectWith(0, 0, this->width(), this->height())) {
if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
fResolveRect.setLargestInverted();
}
}

View File

@ -94,6 +94,10 @@ struct SK_API SkIRect {
fRight = right;
fBottom = bottom;
}
// alias for set(l, t, r, b)
void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) {
this->set(left, top, right, bottom);
}
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) {
fLeft = x;
@ -101,6 +105,23 @@ struct SK_API SkIRect {
fRight = x + width;
fBottom = y + height;
}
/**
* Make the largest representable rectangle
*/
void setLargest() {
fLeft = fTop = SK_MinS32;
fRight = fBottom = SK_MaxS32;
}
/**
* Make the largest representable rectangle, but inverted (e.g. fLeft will
* be max 32bit and right will be min 32bit).
*/
void setLargestInverted() {
fLeft = fTop = SK_MaxS32;
fRight = fBottom = SK_MinS32;
}
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
@ -127,6 +148,10 @@ struct SK_API SkIRect {
fBottom -= dy;
}
bool quickReject(int l, int t, int r, int b) const {
return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
}
/** Returns true if (x,y) is inside the rectangle and the rectangle is not
empty. The left and top are considered to be inside, while the right
and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
@ -263,6 +288,11 @@ struct SK_API SkIRect {
When this returns, left <= right && top <= bottom
*/
void sort();
static const SkIRect& EmptyIRect() {
static const SkIRect gEmpty = {0};
return gEmpty;
}
};
/** \struct SkRect
@ -304,6 +334,10 @@ struct SK_API SkRect {
*/
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
bool hasValidCoordinates() const;
SkScalar left() const { return fLeft; }
SkScalar top() const { return fTop; }
SkScalar right() const { return fRight; }
SkScalar bottom() const { return fBottom; }
SkScalar width() const { return fRight - fLeft; }
SkScalar height() const { return fBottom - fTop; }
SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); }
@ -338,7 +372,11 @@ struct SK_API SkRect {
fRight = right;
fBottom = bottom;
}
// alias for set(l, t, r, b)
void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
this->set(left, top, right, bottom);
}
/** Initialize the rect with the 4 specified integers. The routine handles
converting them to scalars (by calling SkIntToScalar)
*/
@ -355,6 +393,11 @@ struct SK_API SkRect {
*/
void set(const SkPoint pts[], int count);
// alias for set(pts, count)
void setBounds(const SkPoint pts[], int count) {
this->set(pts, count);
}
void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
fLeft = x;
fTop = y;
@ -362,6 +405,23 @@ struct SK_API SkRect {
fBottom = y + height;
}
/**
* Make the largest representable rectangle
*/
void setLargest() {
fLeft = fTop = SK_ScalarMin;
fRight = fBottom = SK_ScalarMax;
}
/**
* Make the largest representable rectangle, but inverted (e.g. fLeft will
* be max and right will be min).
*/
void setLargestInverted() {
fLeft = fTop = SK_ScalarMax;
fRight = fBottom = SK_ScalarMin;
}
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/
@ -433,6 +493,15 @@ struct SK_API SkRect {
void join(const SkRect& r) {
this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
// alias for join()
void growToInclude(const SkRect& r) { this->join(r); }
void growToInclude(SkScalar x, SkScalar y) {
fLeft = SkMinScalar(x, fLeft);
fRight = SkMaxScalar(y, fRight);
fTop = SkMinScalar(x, fTop);
fBottom = SkMaxScalar(y, fBottom);
}
/** Returns true if (p.fX,p.fY) is inside the rectangle. The left and top coordinates of
the rectangle are considered to be inside, while the right and bottom coordinates

View File

@ -104,27 +104,8 @@ GR_STATIC_ASSERT((int)SkPath::kDone_Verb == (int)kEnd_PathCmd);
#include "SkColorPriv.h"
static inline GrRect Sk2Gr(const SkRect& src) {
return GrRect(SkScalarToGrScalar(src.fLeft),
SkScalarToGrScalar(src.fTop),
SkScalarToGrScalar(src.fRight),
SkScalarToGrScalar(src.fBottom));
}
class SkGr {
public:
static inline SkIRect& SetIRect(SkIRect* dst, const GrIRect& src) {
GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
memcpy(dst, &src, sizeof(*dst));
return *dst;
}
static inline GrIRect& SetIRect(GrIRect* dst, const SkIRect& src) {
GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
memcpy(dst, &src, sizeof(*dst));
return *dst;
}
/**
* Convert the SkBitmap::Config to the corresponding PixelConfig, or
* kUnknown_PixelConfig if the conversion cannot be done.
@ -203,7 +184,7 @@ public:
if (!fCurr->fRect) {
rect->setEmpty();
} else {
*rect = Sk2Gr(*fCurr->fRect);
*rect = *fCurr->fRect;
}
}

View File

@ -691,7 +691,7 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix, &grPaint)) {
return;
}
fContext->drawRect(grPaint, Sk2Gr(rect), doStroke ? width : -1);
fContext->drawRect(grPaint, rect, doStroke ? width : -1);
}
#include "SkMaskFilter.h"
@ -967,7 +967,8 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
grPaint->setTexture(texture);
GrRect dstRect(0, 0, GrIntToScalar(srcRect.width()), GrIntToScalar(srcRect.height()));
GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()),
GrIntToScalar(srcRect.height()));
GrRect paintRect;
paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16) / bitmap.width()),
GrFixedToScalar((srcRect.fTop << 16) / bitmap.height()),
@ -1003,10 +1004,11 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
grPaint.setTexture(texture);
fContext->drawRectToRect(grPaint,
GrRect(GrIntToScalar(left), GrIntToScalar(top),
GrIntToScalar(left + bitmap.width()),
GrIntToScalar(top + bitmap.height())),
GrRect(0, 0, GR_Scalar1, GR_Scalar1));
GrRect::MakeXYWH(GrIntToScalar(left),
GrIntToScalar(top),
GrIntToScalar(bitmap.width()),
GrIntToScalar(bitmap.height())),
GrRect::MakeWH(GR_Scalar1, GR_Scalar1));
}
void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
@ -1030,11 +1032,11 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
grPaint.fSampler.setClampNoFilter();
fContext->drawRectToRect(grPaint,
GrRect(GrIntToScalar(x),
GrIntToScalar(y),
GrIntToScalar(x + w),
GrIntToScalar(y + h)),
GrRect(0, 0, GR_Scalar1, GR_Scalar1));
GrRect::MakeXYWH(GrIntToScalar(x),
GrIntToScalar(y),
GrIntToScalar(w),
GrIntToScalar(h)),
GrRect::MakeWH(GR_Scalar1, GR_Scalar1));
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -144,7 +144,7 @@ GrConvexHint SkGrPathIter::convexHint() const {
}
bool SkGrPathIter::getConservativeBounds(GrRect* rect) const {
*rect = Sk2Gr(fPath->getBounds());
*rect = fPath->getBounds();
return true;
}