used for interpreting the clipstack when a device is a layer



git-svn-id: http://skia.googlecode.com/svn/trunk@894 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-03-04 22:27:10 +00:00
Родитель f966fd35cf
Коммит 6f8f292aa7
10 изменённых файлов: 128 добавлений и 67 удалений

Просмотреть файл

@ -28,7 +28,11 @@ class GrClip {
public: public:
GrClip(); GrClip();
GrClip(const GrClip& src); GrClip(const GrClip& src);
GrClip(GrClipIterator* iter, const GrRect* bounds = NULL); /**
* If specified, the bounds parameter already takes (tx,ty) into account.
*/
GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds = NULL);
GrClip(const GrIRect& rect); GrClip(const GrIRect& rect);
GrClip(const GrRect& rect); GrClip(const GrRect& rect);
@ -77,7 +81,12 @@ public:
* Resets this clip to be empty * Resets this clip to be empty
*/ */
void setEmpty(); void setEmpty();
void setFromIterator(GrClipIterator* iter, const GrRect* bounds = NULL);
/**
* If specified, the bounds parameter already takes (tx,ty) into account.
*/
void setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds = NULL);
void setFromRect(const GrRect& rect); void setFromRect(const GrRect& rect);
void setFromIRect(const GrIRect& rect); void setFromIRect(const GrIRect& rect);

Просмотреть файл

@ -46,6 +46,12 @@ public:
GrScalar x2, GrScalar y2); GrScalar x2, GrScalar y2);
virtual void close(); virtual void close();
/**
* Offset the path by (tx, ty), adding tx to the horizontal position
* and adds ty to the vertical position of every point.
*/
void offset(GrScalar tx, GrScalar ty);
class Iter : public GrPathIter { class Iter : public GrPathIter {
public: public:
/** /**

Просмотреть файл

@ -223,6 +223,14 @@ struct GrRect {
fBottom >= r.fBottom; 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;
}
/** /**
* Initialize a rectangle to a point. * Initialize a rectangle to a point.

Просмотреть файл

@ -38,9 +38,10 @@ GrClip::GrClip(const GrRect& rect)
this->setFromRect(rect); this->setFromRect(rect);
} }
GrClip::GrClip(GrClipIterator* iter, const GrRect* bounds) GrClip::GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds)
: fList(fListMemory, kPreAllocElements) { : fList(fListMemory, kPreAllocElements) {
this->setFromIterator(iter, bounds); this->setFromIterator(iter, tx, ty, bounds);
} }
GrClip::~GrClip() {} GrClip::~GrClip() {}
@ -86,7 +87,8 @@ void GrClip::setFromIRect(const GrIRect& r) {
} }
} }
void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) { void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
const GrRect* bounds) {
fList.reset(); fList.reset();
int rectCount = 0; int rectCount = 0;
@ -104,6 +106,9 @@ void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) {
switch (e.fType) { switch (e.fType) {
case kRect_ClipType: case kRect_ClipType:
iter->getRect(&e.fRect); iter->getRect(&e.fRect);
if (tx || ty) {
e.fRect.offset(tx, ty);
}
++rectCount; ++rectCount;
if (isectRectValid) { if (isectRectValid) {
if (1 == rectCount || kIntersect_SetOp == e.fOp) { if (1 == rectCount || kIntersect_SetOp == e.fOp) {
@ -122,6 +127,9 @@ void GrClip::setFromIterator(GrClipIterator* iter, const GrRect* bounds) {
break; break;
case kPath_ClipType: case kPath_ClipType:
e.fPath.resetFromIter(iter->getPathIter()); e.fPath.resetFromIter(iter->getPathIter());
if (tx || ty) {
e.fPath.offset(tx, ty);
}
e.fPathFill = iter->getPathFill(); e.fPathFill = iter->getPathFill();
isectRectValid = false; isectRectValid = false;
break; break;

Просмотреть файл

@ -84,12 +84,27 @@ void GrPath::close() {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void GrPath::offset(GrScalar tx, GrScalar ty) {
if (!tx && !ty) {
return; // nothing to do
}
GrPoint* iter = fPts.begin();
GrPoint* stop = fPts.end();
while (iter < stop) {
iter->offset(tx, ty);
++iter;
}
}
///////////////////////////////////////////////////////////////////////////////
static bool check_two_vecs(const GrVec& prevVec, static bool check_two_vecs(const GrVec& prevVec,
const GrVec& currVec, const GrVec& currVec,
GrScalar turnDir, GrScalar turnDir,
int* xDir, int* xDir,
int* yDir, int* yDir,
int* flipX, int* flipX,
int* flipY) { int* flipY) {
if (currVec.fX * *xDir < 0) { if (currVec.fX * *xDir < 0) {
++*flipX; ++*flipX;
@ -214,9 +229,9 @@ void GrPath::resetFromIter(GrPathIter* iter) {
vec.setBetween(previousPt, pts[consumed]); vec.setBetween(previousPt, pts[consumed]);
if (vec.fX || vec.fY) { if (vec.fX || vec.fY) {
if (subPathPts >= 2) { if (subPathPts >= 2) {
if (0 == turnDir) { if (0 == turnDir) {
firstVec = previousVec; firstVec = previousVec;
init_from_two_vecs(firstVec, vec, init_from_two_vecs(firstVec, vec,
&turnDir, &xDir, &yDir); &turnDir, &xDir, &yDir);
// here we aren't checking whether the x/y dirs // here we aren't checking whether the x/y dirs
// change between the first and second edge. It // change between the first and second edge. It
@ -236,14 +251,14 @@ void GrPath::resetFromIter(GrPathIter* iter) {
} }
++consumed; ++consumed;
} }
if (subPathPts > 2 && (kClose_PathCmd == cmd || if (subPathPts > 2 && (kClose_PathCmd == cmd ||
(!subPathClosed && kEnd_PathCmd == cmd ))) { (!subPathClosed && kEnd_PathCmd == cmd ))) {
// if an additional vector is needed to close the loop check // if an additional vector is needed to close the loop check
// that it validates against the previous vector. // that it validates against the previous vector.
GrVec vec; GrVec vec;
vec.setBetween(previousPt, firstPt); vec.setBetween(previousPt, firstPt);
if (vec.fX || vec.fY) { if (vec.fX || vec.fY) {
if (!check_two_vecs(previousVec, vec, turnDir, if (!check_two_vecs(previousVec, vec, turnDir,
&xDir, &yDir, &flipX, &flipY)) { &xDir, &yDir, &flipX, &flipY)) {
fConvexHint = kConcave_ConvexHint; fConvexHint = kConcave_ConvexHint;
break; break;
@ -251,7 +266,7 @@ void GrPath::resetFromIter(GrPathIter* iter) {
previousVec = vec; previousVec = vec;
} }
// check that closing vector validates against the first vector. // check that closing vector validates against the first vector.
if (!check_two_vecs(previousVec, firstVec, turnDir, if (!check_two_vecs(previousVec, firstVec, turnDir,
&xDir, &yDir, &flipX, &flipY)) { &xDir, &yDir, &flipX, &flipY)) {
fConvexHint = kConcave_ConvexHint; fConvexHint = kConcave_ConvexHint;
break; break;
@ -309,7 +324,7 @@ void GrPath::ConvexUnitTest() {
testIter.reset(triRight); testIter.reset(triRight);
testPath.resetFromIter(&testIter); testPath.resetFromIter(&testIter);
GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
GrPath square; GrPath square;
square.moveTo(0, 0); square.moveTo(0, 0);
square.lineTo(1, 0); square.lineTo(1, 0);
@ -335,7 +350,7 @@ void GrPath::ConvexUnitTest() {
square.lineTo(0, 1); square.lineTo(0, 1);
square.lineTo(0, 1); square.lineTo(0, 1);
square.close(); square.close();
testIter.reset(redundantSquare); testIter.reset(redundantSquare);
testPath.resetFromIter(&testIter); testPath.resetFromIter(&testIter);
GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); GrAssert(kConvex_ConvexHint == testPath.getConvexHint());
@ -354,7 +369,7 @@ void GrPath::ConvexUnitTest() {
bowTie.lineTo(0, 1); bowTie.lineTo(0, 1);
bowTie.lineTo(0, 1); bowTie.lineTo(0, 1);
bowTie.close(); bowTie.close();
testIter.reset(bowTie); testIter.reset(bowTie);
testPath.resetFromIter(&testIter); testPath.resetFromIter(&testIter);
GrAssert(kConcave_ConvexHint == testPath.getConvexHint()); GrAssert(kConcave_ConvexHint == testPath.getConvexHint());

Просмотреть файл

@ -81,6 +81,13 @@ public:
/** Return the height of the device (in pixels). /** Return the height of the device (in pixels).
*/ */
virtual int height() const { return fBitmap.height(); } virtual int height() const { return fBitmap.height(); }
/**
* Return the device's origin: its offset in device coordinates from
* the default origin in its canvas' matrix/clip
*/
const SkIPoint& getOrigin() const { return fOrigin; }
/** Return the bitmap config of the device's pixels /** Return the bitmap config of the device's pixels
*/ */
SkBitmap::Config config() const { return fBitmap.getConfig(); } SkBitmap::Config config() const { return fBitmap.getConfig(); }
@ -217,9 +224,14 @@ protected:
} }
private: private:
friend class SkCanvas;
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }
SkCanvas* fCanvas; SkCanvas* fCanvas;
SkBitmap fBitmap; SkBitmap fBitmap;
SkRefDict fRefDict; SkRefDict fRefDict;
SkIPoint fOrigin;
}; };
#endif #endif

Просмотреть файл

@ -26,13 +26,28 @@
*/ */
struct SkIPoint { struct SkIPoint {
int32_t fX, fY; int32_t fX, fY;
static SkIPoint Make(int32_t x, int32_t y) { static SkIPoint Make(int32_t x, int32_t y) {
SkIPoint pt; SkIPoint pt;
pt.set(x, y); pt.set(x, y);
return pt; return pt;
} }
int32_t x() const { return fX; }
int32_t y() const { return fY; }
void setX(int32_t x) { fX = x; }
void setY(int32_t y) { fY = y; }
/**
* Returns true iff fX and fY are both zero.
*/
bool isZero() const { return (fX | fY) == 0; }
/**
* Set both fX and fY to zero. Same as set(0, 0)
*/
void setZero() { fX = fY = 0; }
/** Set the x and y values of the point. */ /** Set the x and y values of the point. */
void set(int32_t x, int32_t y) { fX = x; fY = y; } void set(int32_t x, int32_t y) { fX = x; fY = y; }
@ -55,11 +70,11 @@ struct SkIPoint {
the point the point
*/ */
void rotateCCW() { this->rotateCCW(this); } void rotateCCW() { this->rotateCCW(this); }
/** Negate the X and Y coordinates of the point. /** Negate the X and Y coordinates of the point.
*/ */
void negate() { fX = -fX; fY = -fY; } void negate() { fX = -fX; fY = -fY; }
/** Return a new point whose X and Y coordinates are the negative of the /** Return a new point whose X and Y coordinates are the negative of the
original point's original point's
*/ */
@ -75,7 +90,7 @@ struct SkIPoint {
fX += v.fX; fX += v.fX;
fY += v.fY; fY += v.fY;
} }
/** Subtract v's coordinates from this point's */ /** Subtract v's coordinates from this point's */
void operator-=(const SkIPoint& v) { void operator-=(const SkIPoint& v) {
fX -= v.fX; fX -= v.fX;
@ -90,7 +105,7 @@ struct SkIPoint {
friend bool operator==(const SkIPoint& a, const SkIPoint& b) { friend bool operator==(const SkIPoint& a, const SkIPoint& b) {
return a.fX == b.fX && a.fY == b.fY; return a.fX == b.fX && a.fY == b.fY;
} }
friend bool operator!=(const SkIPoint& a, const SkIPoint& b) { friend bool operator!=(const SkIPoint& a, const SkIPoint& b) {
return a.fX != b.fX || a.fY != b.fY; return a.fX != b.fX || a.fY != b.fY;
} }
@ -111,7 +126,7 @@ struct SkIPoint {
v.set(a.fX + b.fX, a.fY + b.fY); v.set(a.fX + b.fX, a.fY + b.fY);
return v; return v;
} }
/** Returns the dot product of a and b, treating them as 2D vectors /** Returns the dot product of a and b, treating them as 2D vectors
*/ */
static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) { static int32_t DotProduct(const SkIPoint& a, const SkIPoint& b) {
@ -133,10 +148,10 @@ struct SkPoint {
pt.set(x, y); pt.set(x, y);
return pt; return pt;
} }
/** Set the point's X and Y coordinates */ /** Set the point's X and Y coordinates */
void set(SkScalar x, SkScalar y) { fX = x; fY = y; } void set(SkScalar x, SkScalar y) { fX = x; fY = y; }
/** Set the point's X and Y coordinates by automatically promoting (x,y) to /** Set the point's X and Y coordinates by automatically promoting (x,y) to
SkScalar values. SkScalar values.
*/ */
@ -144,7 +159,7 @@ struct SkPoint {
fX = SkIntToScalar(x); fX = SkIntToScalar(x);
fY = SkIntToScalar(y); fY = SkIntToScalar(y);
} }
/** Set the point's X and Y coordinates by automatically promoting p's /** Set the point's X and Y coordinates by automatically promoting p's
coordinates to SkScalar values. coordinates to SkScalar values.
*/ */
@ -163,19 +178,19 @@ struct SkPoint {
return true. return true.
*/ */
bool normalize(); bool normalize();
/** Set the point (vector) to be unit-length in the same direction as the /** Set the point (vector) to be unit-length in the same direction as the
x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0) x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0)
then return false and do nothing, otherwise return true. then return false and do nothing, otherwise return true.
*/ */
bool setNormalize(SkScalar x, SkScalar y); bool setNormalize(SkScalar x, SkScalar y);
/** Scale the point (vector) to have the specified length, and return that /** Scale the point (vector) to have the specified length, and return that
length. If the original length is degenerately small (nearly zero), length. If the original length is degenerately small (nearly zero),
do nothing and return false, otherwise return true. do nothing and return false, otherwise return true.
*/ */
bool setLength(SkScalar length); bool setLength(SkScalar length);
/** Set the point (vector) to have the specified length in the same /** Set the point (vector) to have the specified length in the same
direction as (x,y). If the vector (x,y) has a degenerate length direction as (x,y). If the vector (x,y) has a degenerate length
(i.e. nearly 0) then return false and do nothing, otherwise return true. (i.e. nearly 0) then return false and do nothing, otherwise return true.
@ -186,7 +201,7 @@ struct SkPoint {
It is legal for dst == this. It is legal for dst == this.
*/ */
void scale(SkScalar scale, SkPoint* dst) const; void scale(SkScalar scale, SkPoint* dst) const;
/** Scale the point's coordinates by scale, writing the answer back into /** Scale the point's coordinates by scale, writing the answer back into
the point. the point.
*/ */
@ -196,29 +211,29 @@ struct SkPoint {
It is legal for dst == this. It is legal for dst == this.
*/ */
void rotateCW(SkPoint* dst) const; void rotateCW(SkPoint* dst) const;
/** Rotate the point clockwise by 90 degrees, writing the answer back into /** Rotate the point clockwise by 90 degrees, writing the answer back into
the point. the point.
*/ */
void rotateCW() { this->rotateCW(this); } void rotateCW() { this->rotateCW(this); }
/** Rotate the point counter-clockwise by 90 degrees, writing the answer /** Rotate the point counter-clockwise by 90 degrees, writing the answer
into dst. It is legal for dst == this. into dst. It is legal for dst == this.
*/ */
void rotateCCW(SkPoint* dst) const; void rotateCCW(SkPoint* dst) const;
/** Rotate the point counter-clockwise by 90 degrees, writing the answer /** Rotate the point counter-clockwise by 90 degrees, writing the answer
back into the point. back into the point.
*/ */
void rotateCCW() { this->rotateCCW(this); } void rotateCCW() { this->rotateCCW(this); }
/** Negate the point's coordinates /** Negate the point's coordinates
*/ */
void negate() { void negate() {
fX = -fX; fX = -fX;
fY = -fY; fY = -fY;
} }
/** Returns a new point whose coordinates are the negative of the point's /** Returns a new point whose coordinates are the negative of the point's
*/ */
SkPoint operator-() const { SkPoint operator-() const {
@ -234,7 +249,7 @@ struct SkPoint {
fX += v.fX; fX += v.fX;
fY += v.fY; fY += v.fY;
} }
/** Subtract v's coordinates from the point's /** Subtract v's coordinates from the point's
*/ */
void operator-=(const SkPoint& v) { void operator-=(const SkPoint& v) {
@ -249,7 +264,7 @@ struct SkPoint {
friend bool operator==(const SkPoint& a, const SkPoint& b) { friend bool operator==(const SkPoint& a, const SkPoint& b) {
return a.fX == b.fX && a.fY == b.fY; return a.fX == b.fX && a.fY == b.fY;
} }
friend bool operator!=(const SkPoint& a, const SkPoint& b) { friend bool operator!=(const SkPoint& a, const SkPoint& b) {
return a.fX != b.fX || a.fY != b.fY; return a.fX != b.fX || a.fY != b.fY;
} }

Просмотреть файл

@ -72,8 +72,7 @@ struct DeviceCM {
SkDevice* fDevice; SkDevice* fDevice;
SkRegion fClip; SkRegion fClip;
const SkMatrix* fMatrix; const SkMatrix* fMatrix;
SkPaint* fPaint; // may be null (in the future) SkPaint* fPaint; // may be null (in the future)
int16_t fX, fY; // relative to base matrix/clip
// optional, related to canvas' external matrix // optional, related to canvas' external matrix
const SkMatrix* fMVMatrix; const SkMatrix* fMVMatrix;
const SkMatrix* fExtMatrix; const SkMatrix* fExtMatrix;
@ -85,8 +84,6 @@ struct DeviceCM {
device->lockPixels(); device->lockPixels();
} }
fDevice = device; fDevice = device;
fX = SkToS16(x);
fY = SkToS16(y);
fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
} }
@ -100,8 +97,8 @@ struct DeviceCM {
void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip, void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip,
const SkClipStack& clipStack, SkRegion* updateClip) { const SkClipStack& clipStack, SkRegion* updateClip) {
int x = fX; int x = fDevice->getOrigin().x();
int y = fY; int y = fDevice->getOrigin().y();
int width = fDevice->width(); int width = fDevice->width();
int height = fDevice->height(); int height = fDevice->height();
@ -147,12 +144,6 @@ struct DeviceCM {
fExtMatrix = &extM; // assumes extM has long life-time (owned by canvas) fExtMatrix = &extM; // assumes extM has long life-time (owned by canvas)
} }
void translateClip() {
if (fX | fY) {
fClip.translate(fX, fY);
}
}
private: private:
SkMatrix fMatrixStorage, fMVMatrixStorage; SkMatrix fMatrixStorage, fMVMatrixStorage;
}; };
@ -251,8 +242,6 @@ public:
fClip = &rec->fClip; fClip = &rec->fClip;
fDevice = rec->fDevice; fDevice = rec->fDevice;
fBitmap = &fDevice->accessBitmap(true); fBitmap = &fDevice->accessBitmap(true);
fLayerX = rec->fX;
fLayerY = rec->fY;
fPaint = rec->fPaint; fPaint = rec->fPaint;
fMVMatrix = rec->fMVMatrix; fMVMatrix = rec->fMVMatrix;
fExtMatrix = rec->fExtMatrix; fExtMatrix = rec->fExtMatrix;
@ -270,18 +259,17 @@ public:
return false; return false;
} }
int getX() const { return fLayerX; }
int getY() const { return fLayerY; }
SkDevice* getDevice() const { return fDevice; } SkDevice* getDevice() const { return fDevice; }
int getX() const { return fDevice->getOrigin().x(); }
int getY() const { return fDevice->getOrigin().y(); }
const SkMatrix& getMatrix() const { return *fMatrix; } const SkMatrix& getMatrix() const { return *fMatrix; }
const SkRegion& getClip() const { return *fClip; } const SkRegion& getClip() const { return *fClip; }
const SkPaint* getPaint() const { return fPaint; } const SkPaint* getPaint() const { return fPaint; }
private: private:
SkCanvas* fCanvas; SkCanvas* fCanvas;
const DeviceCM* fCurrLayer; const DeviceCM* fCurrLayer;
const SkPaint* fPaint; // May be null. const SkPaint* fPaint; // May be null.
int fLayerX;
int fLayerY;
SkBool8 fSkipEmptyClips; SkBool8 fSkipEmptyClips;
typedef SkDraw INHERITED; typedef SkDraw INHERITED;
@ -748,6 +736,7 @@ int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
SkDevice* device = this->createDevice(config, ir.width(), ir.height(), SkDevice* device = this->createDevice(config, ir.width(), ir.height(),
isOpaque, true); isOpaque, true);
device->setOrigin(ir.fLeft, ir.fTop);
DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint)); DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint));
device->unref(); device->unref();
@ -800,7 +789,8 @@ void SkCanvas::internalRestore() {
*/ */
if (NULL != layer) { if (NULL != layer) {
if (layer->fNext) { if (layer->fNext) {
this->drawDevice(layer->fDevice, layer->fX, layer->fY, const SkIPoint& origin = layer->fDevice->getOrigin();
this->drawDevice(layer->fDevice, origin.x(), origin.y(),
layer->fPaint); layer->fPaint);
// reset this, since drawDevice will have set it to true // reset this, since drawDevice will have set it to true
fDeviceCMDirty = true; fDeviceCMDirty = true;
@ -1035,9 +1025,9 @@ void SkCanvas::validateClip() const {
} }
} }
#if 0 // enable this locally for testing
// now compare against the current rgn // now compare against the current rgn
const SkRegion& rgn = this->getTotalClip(); const SkRegion& rgn = this->getTotalClip();
#if 0 // disable for now (reed)
SkASSERT(rgn == clipRgn); SkASSERT(rgn == clipRgn);
#endif #endif
} }

Просмотреть файл

@ -4,10 +4,13 @@
SkDeviceFactory::~SkDeviceFactory() {} SkDeviceFactory::~SkDeviceFactory() {}
SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {} SkDevice::SkDevice(SkCanvas* canvas) : fCanvas(canvas) {
fOrigin.setZero();
}
SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer) SkDevice::SkDevice(SkCanvas* canvas, const SkBitmap& bitmap, bool isForLayer)
: fCanvas(canvas), fBitmap(bitmap) { : fCanvas(canvas), fBitmap(bitmap) {
fOrigin.setZero();
// auto-allocate if we're for offscreen drawing // auto-allocate if we're for offscreen drawing
if (isForLayer) { if (isForLayer) {
if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) { if (NULL == fBitmap.getPixels() && NULL == fBitmap.pixelRef()) {

Просмотреть файл

@ -267,29 +267,24 @@ void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define USE_CLIP_STACK 0
static void convert_matrixclip(GrContext* context, const SkMatrix& matrix, static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
const SkClipStack& clipStack, const SkClipStack& clipStack,
const SkRegion& clipRegion) { const SkRegion& clipRegion,
const SkIPoint& origin) {
GrMatrix grmat; GrMatrix grmat;
SkGr::SkMatrix2GrMatrix(matrix, &grmat); SkGr::SkMatrix2GrMatrix(matrix, &grmat);
context->setMatrix(grmat); context->setMatrix(grmat);
#if USE_CLIP_STACK
SkGrClipIterator iter; SkGrClipIterator iter;
iter.reset(clipStack); iter.reset(clipStack);
#else
SkGrRegionIterator iter;
iter.reset(clipRegion);
#endif
const SkIRect& skBounds = clipRegion.getBounds(); const SkIRect& skBounds = clipRegion.getBounds();
GrRect bounds; GrRect bounds;
bounds.setLTRB(GrIntToScalar(skBounds.fLeft), bounds.setLTRB(GrIntToScalar(skBounds.fLeft),
GrIntToScalar(skBounds.fTop), GrIntToScalar(skBounds.fTop),
GrIntToScalar(skBounds.fRight), GrIntToScalar(skBounds.fRight),
GrIntToScalar(skBounds.fBottom)); GrIntToScalar(skBounds.fBottom));
GrClip grc(&iter, &bounds); GrClip grc(&iter, GrIntToScalar(-origin.x()), GrIntToScalar(-origin.y()),
&bounds);
context->setClip(grc); context->setClip(grc);
} }
@ -302,7 +297,7 @@ void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
fContext->setRenderTarget(fRenderTarget); fContext->setRenderTarget(fRenderTarget);
SkASSERT(draw.fClipStack); SkASSERT(draw.fClipStack);
convert_matrixclip(fContext, *draw.fMatrix, convert_matrixclip(fContext, *draw.fMatrix,
*draw.fClipStack, *draw.fClip); *draw.fClipStack, *draw.fClip, this->getOrigin());
fNeedPrepareRenderTarget = false; fNeedPrepareRenderTarget = false;
} }
} }
@ -311,7 +306,7 @@ void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
const SkClipStack& clipStack) { const SkClipStack& clipStack) {
this->INHERITED::setMatrixClip(matrix, clip, clipStack); this->INHERITED::setMatrixClip(matrix, clip, clipStack);
convert_matrixclip(fContext, matrix, clipStack, clip); convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
} }
void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix, void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
@ -321,7 +316,7 @@ void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
this->INHERITED::gainFocus(canvas, matrix, clip, clipStack); this->INHERITED::gainFocus(canvas, matrix, clip, clipStack);
convert_matrixclip(fContext, matrix, clipStack, clip); convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
if (fNeedClear) { if (fNeedClear) {
fContext->eraseColor(0x0); fContext->eraseColor(0x0);