| Index: src/core/SkCanvas.cpp
|
| diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
|
| index 71b81a1fa2b4ae1b2d355a22e00379a3b3e76102..a5fa30ff2d7a6946e8c5e32d1ca9f786f7d6275c 100644
|
| --- a/src/core/SkCanvas.cpp
|
| +++ b/src/core/SkCanvas.cpp
|
| @@ -335,7 +335,8 @@ private:
|
| class AutoDrawLooper {
|
| public:
|
| AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint,
|
| - bool skipLayerForImageFilter = false) : fOrigPaint(paint) {
|
| + bool skipLayerForImageFilter = false,
|
| + const SkRect* bounds = NULL) : fOrigPaint(paint) {
|
| fCanvas = canvas;
|
| fLooper = paint.getLooper();
|
| fFilter = canvas->getDrawFilter();
|
| @@ -347,8 +348,7 @@ public:
|
| if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) {
|
| SkPaint tmp;
|
| tmp.setImageFilter(fOrigPaint.getImageFilter());
|
| - // it would be nice if we had a guess at the bounds, instead of null
|
| - (void)canvas->internalSaveLayer(NULL, &tmp,
|
| + (void)canvas->internalSaveLayer(bounds, &tmp,
|
| SkCanvas::kARGB_ClipLayer_SaveFlag, true);
|
| // we'll clear the imageFilter for the actual draws in next(), so
|
| // it will only be applied during the restore().
|
| @@ -471,9 +471,9 @@ private:
|
| SkAutoBounderCommit ac(fBounder); \
|
| SkDrawIter iter(this);
|
|
|
| -#define LOOPER_BEGIN(paint, type) \
|
| +#define LOOPER_BEGIN(paint, type, bounds) \
|
| this->predrawNotify(); \
|
| - AutoDrawLooper looper(this, paint); \
|
| + AutoDrawLooper looper(this, paint, false, bounds); \
|
| while (looper.next(type)) { \
|
| SkAutoBounderCommit ac(fBounder); \
|
| SkDrawIter iter(this);
|
| @@ -972,7 +972,15 @@ void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap,
|
| SkDEBUGCODE(bitmap.validate();)
|
| CHECK_LOCKCOUNT_BALANCE(bitmap);
|
|
|
| - LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
|
| + SkRect storage;
|
| + const SkRect* bounds = NULL;
|
| + if (paint && paint->canComputeFastBounds()) {
|
| + bitmap.getBounds(&storage);
|
| + matrix.mapRect(&storage);
|
| + bounds = &paint->computeFastBounds(storage, &storage);
|
| + }
|
| +
|
| + LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
|
| @@ -1572,7 +1580,7 @@ void SkCanvas::drawPaint(const SkPaint& paint) {
|
| void SkCanvas::internalDrawPaint(const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawPaint(iter, looper.paint());
|
| @@ -1589,23 +1597,24 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
|
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| + SkRect r, storage;
|
| + const SkRect* bounds = NULL;
|
| if (paint.canComputeFastBounds()) {
|
| - SkRect r;
|
| // special-case 2 points (common for drawing a single line)
|
| if (2 == count) {
|
| r.set(pts[0], pts[1]);
|
| } else {
|
| r.set(pts, SkToInt(count));
|
| }
|
| - SkRect storage;
|
| - if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) {
|
| + bounds = &paint.computeFastStrokeBounds(r, &storage);
|
| + if (this->quickReject(*bounds)) {
|
| return;
|
| }
|
| }
|
|
|
| SkASSERT(pts != NULL);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
|
| @@ -1617,14 +1626,16 @@ void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
| void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| + SkRect storage;
|
| + const SkRect* bounds = NULL;
|
| if (paint.canComputeFastBounds()) {
|
| - SkRect storage;
|
| - if (this->quickReject(paint.computeFastBounds(r, &storage))) {
|
| + bounds = &paint.computeFastBounds(r, &storage);
|
| + if (this->quickReject(*bounds)) {
|
| return;
|
| }
|
| }
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawRect(iter, r, looper.paint());
|
| @@ -1636,14 +1647,16 @@ void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
|
| void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| + SkRect storage;
|
| + const SkRect* bounds = NULL;
|
| if (paint.canComputeFastBounds()) {
|
| - SkRect storage;
|
| - if (this->quickReject(paint.computeFastBounds(oval, &storage))) {
|
| + bounds = &paint.computeFastBounds(oval, &storage);
|
| + if (this->quickReject(*bounds)) {
|
| return;
|
| }
|
| }
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawOval(iter, oval, looper.paint());
|
| @@ -1655,9 +1668,11 @@ void SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
|
| void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| + SkRect storage;
|
| + const SkRect* bounds = NULL;
|
| if (paint.canComputeFastBounds()) {
|
| - SkRect storage;
|
| - if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) {
|
| + bounds = &paint.computeFastBounds(rrect.getBounds(), &storage);
|
| + if (this->quickReject(*bounds)) {
|
| return;
|
| }
|
| }
|
| @@ -1672,7 +1687,7 @@ void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
| return;
|
| }
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawRRect(iter, rrect, looper.paint());
|
| @@ -1689,10 +1704,12 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
|
| return;
|
| }
|
|
|
| + SkRect storage;
|
| + const SkRect* bounds = NULL;
|
| if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
|
| - SkRect storage;
|
| - const SkRect& bounds = path.getBounds();
|
| - if (this->quickReject(paint.computeFastBounds(bounds, &storage))) {
|
| + const SkRect& pathBounds = path.getBounds();
|
| + bounds = &paint.computeFastBounds(pathBounds, &storage);
|
| + if (this->quickReject(*bounds)) {
|
| return;
|
| }
|
| }
|
| @@ -1703,7 +1720,7 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
|
| return;
|
| }
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawPath(iter, path, looper.paint());
|
| @@ -1745,9 +1762,9 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
|
|
| CHECK_LOCKCOUNT_BALANCE(bitmap);
|
|
|
| + SkRect storage;
|
| + const SkRect* bounds = &dst;
|
| if (NULL == paint || paint->canComputeFastBounds()) {
|
| - SkRect storage;
|
| - const SkRect* bounds = &dst;
|
| if (paint) {
|
| bounds = &paint->computeFastBounds(dst, &storage);
|
| }
|
| @@ -1761,7 +1778,7 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
| paint = lazy.init();
|
| }
|
|
|
| - LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type)
|
| + LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags);
|
| @@ -1955,7 +1972,7 @@ void SkCanvas::drawText(const void* text, size_t byteLength,
|
| SkScalar x, SkScalar y, const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
|
|
|
| while (iter.next()) {
|
| SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
| @@ -1971,7 +1988,7 @@ void SkCanvas::drawPosText(const void* text, size_t byteLength,
|
| const SkPoint pos[], const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
|
|
|
| while (iter.next()) {
|
| SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
| @@ -1987,7 +2004,7 @@ void SkCanvas::drawPosTextH(const void* text, size_t byteLength,
|
| const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
|
|
|
| while (iter.next()) {
|
| SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
| @@ -2003,7 +2020,7 @@ void SkCanvas::drawTextOnPath(const void* text, size_t byteLength,
|
| const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
|
| @@ -2020,7 +2037,7 @@ void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
|
| const SkPaint& paint) {
|
| CHECK_SHADER_NOSETCONTEXT(paint);
|
|
|
| - LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type)
|
| + LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL)
|
|
|
| while (iter.next()) {
|
| iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
|
|
|