diff --git a/gm/drawable.cpp b/gm/drawable.cpp index 375ce73cbe..3847ba5a32 100644 --- a/gm/drawable.cpp +++ b/gm/drawable.cpp @@ -10,9 +10,7 @@ #include "SkDrawable.h" struct MyDrawable : public SkDrawable { - SkRect onGetBounds() override { - return SkRect::MakeWH(640, 480); - } + SkRect onGetBounds() override { return SkRect::MakeWH(50, 100); } void onDraw(SkCanvas* canvas) override { SkPath path; @@ -29,7 +27,20 @@ struct MyDrawable : public SkDrawable { } }; -DEF_SIMPLE_GM(Drawables, canvas, 640, 480) { - SkAutoTUnref d(new MyDrawable); - canvas->drawDrawable(d); +/* + * Test calling drawables w/ translate and matrices + */ +DEF_SIMPLE_GM(drawable, canvas, 180, 275) { + SkAutoTUnref drawable(new MyDrawable); + + canvas->translate(10, 10); + canvas->drawDrawable(drawable); + canvas->drawDrawable(drawable, 0, 150); + + SkMatrix m = SkMatrix::MakeScale(1.5f, 0.8f); + m.postTranslate(70, 0); + canvas->drawDrawable(drawable, &m); + + m.postTranslate(0, 150); + canvas->drawDrawable(drawable, &m); } diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index a8e2c7f19d..9a46801a98 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1073,7 +1073,8 @@ public: * If the intent is to force the contents of the drawable into this canvas immediately, * then drawable->draw(canvas) may be called. */ - void drawDrawable(SkDrawable* drawable); + void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL); + void drawDrawable(SkDrawable*, SkScalar x, SkScalar y); ////////////////////////////////////////////////////////////////////////// @@ -1229,7 +1230,7 @@ protected: virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint); - virtual void onDrawDrawable(SkDrawable*); + virtual void onDrawDrawable(SkDrawable*, const SkMatrix*); virtual void onDrawPaint(const SkPaint&); virtual void onDrawRect(const SkRect&, const SkPaint&); diff --git a/include/core/SkDrawable.h b/include/core/SkDrawable.h index 15bb0bbe0f..2f0a62d8b5 100644 --- a/include/core/SkDrawable.h +++ b/include/core/SkDrawable.h @@ -30,7 +30,8 @@ public: * (i.e. the saveLevel() on the canvas will match what it was when draw() was called, * and the current matrix and clip settings will not be changed. */ - void draw(SkCanvas*); + void draw(SkCanvas*, const SkMatrix* = NULL); + void draw(SkCanvas*, SkScalar x, SkScalar y); SkPicture* newPictureSnapshot(); diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 88339ff4f3..09bfa45935 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2446,14 +2446,35 @@ void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], LOOPER_END } -void SkCanvas::drawDrawable(SkDrawable* dr) { - if (dr && !this->quickReject(dr->getBounds())) { - this->onDrawDrawable(dr); +void SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { + if (dr) { + if (x || y) { + SkMatrix matrix = SkMatrix::MakeTrans(x, y); + this->onDrawDrawable(dr, &matrix); + } else { + this->onDrawDrawable(dr, NULL); + } } } -void SkCanvas::onDrawDrawable(SkDrawable* dr) { - dr->draw(this); +void SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { + if (dr) { + if (matrix && matrix->isIdentity()) { + matrix = NULL; + } + this->onDrawDrawable(dr, matrix); + } +} + +void SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { + SkRect bounds = dr->getBounds(); + if (matrix) { + matrix->mapRect(&bounds); + } + if (this->quickReject(bounds)) { + return; + } + dr->draw(this, matrix); } void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], diff --git a/src/core/SkDrawable.cpp b/src/core/SkDrawable.cpp index 64fefd2f1c..41547ee697 100644 --- a/src/core/SkDrawable.cpp +++ b/src/core/SkDrawable.cpp @@ -32,8 +32,11 @@ static void draw_bbox(SkCanvas* canvas, const SkRect& r) { canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), paint); } -void SkDrawable::draw(SkCanvas* canvas) { +void SkDrawable::draw(SkCanvas* canvas, const SkMatrix* matrix) { SkAutoCanvasRestore acr(canvas, true); + if (matrix) { + canvas->concat(*matrix); + } this->onDraw(canvas); if (false) { @@ -41,6 +44,11 @@ void SkDrawable::draw(SkCanvas* canvas) { } } +void SkDrawable::draw(SkCanvas* canvas, SkScalar x, SkScalar y) { + SkMatrix matrix = SkMatrix::MakeTrans(x, y); + this->draw(canvas, &matrix); +} + SkPicture* SkDrawable::newPictureSnapshot() { return this->onNewPictureSnapshot(); } diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 118027b7a7..7ef2eafda8 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -124,9 +124,9 @@ template <> void Draw::draw(const DrawDrawable& r) { SkASSERT(r.index < fDrawableCount); if (fDrawables) { SkASSERT(NULL == fDrawablePicts); - fCanvas->drawDrawable(fDrawables[r.index]); + fCanvas->drawDrawable(fDrawables[r.index], r.matrix); } else { - fCanvas->drawPicture(fDrawablePicts[r.index]); + fCanvas->drawPicture(fDrawablePicts[r.index], r.matrix, NULL); } } diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 7433a5b5bf..0413860e9d 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -155,12 +155,12 @@ void SkRecorder::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const APPEND(DrawDRRect, paint, outer, inner); } -void SkRecorder::onDrawDrawable(SkDrawable* drawable) { +void SkRecorder::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { if (!fDrawableList) { fDrawableList.reset(SkNEW(SkDrawableList)); } fDrawableList->append(drawable); - APPEND(DrawDrawable, drawable->getBounds(), fDrawableList->count() - 1); + APPEND(DrawDrawable, this->copy(matrix), drawable->getBounds(), fDrawableList->count() - 1); } void SkRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) { diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 338fab4968..b151578397 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -62,7 +62,7 @@ public: void didSetMatrix(const SkMatrix&) override; void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; - void onDrawDrawable(SkDrawable*) override; + void onDrawDrawable(SkDrawable*, const SkMatrix*) override; void onDrawText(const void* text, size_t byteLength, SkScalar x, diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index b98b93c827..074a560c04 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -10,6 +10,7 @@ #include "SkCanvas.h" #include "SkDrawable.h" +#include "SkMatrix.h" #include "SkPathPriv.h" #include "SkPicture.h" #include "SkRSXform.h" @@ -289,7 +290,7 @@ RECORD5(DrawBitmapRectToRectFixedSize, SkPaint, paint, SkRect, dst, SkCanvas::DrawBitmapRectFlags, flags); RECORD3(DrawDRRect, SkPaint, paint, SkRRect, outer, SkRRect, inner); -RECORD2(DrawDrawable, SkRect, worstCaseBounds, int32_t, index); +RECORD3(DrawDrawable, Optional, matrix, SkRect, worstCaseBounds, int32_t, index); RECORD4(DrawImage, Optional, paint, RefBox, image, SkScalar, left, diff --git a/src/utils/android/SkAndroidSDKCanvas.cpp b/src/utils/android/SkAndroidSDKCanvas.cpp index 883abb8aa2..26baaf2954 100644 --- a/src/utils/android/SkAndroidSDKCanvas.cpp +++ b/src/utils/android/SkAndroidSDKCanvas.cpp @@ -251,8 +251,8 @@ void SkAndroidSDKCanvas::onDrawPicture(const SkPicture* picture, fProxyTarget->drawPicture(picture, matrix, filteredPaint); } -void SkAndroidSDKCanvas::onDrawDrawable(SkDrawable* drawable) { - fProxyTarget->drawDrawable(drawable); +void SkAndroidSDKCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { + fProxyTarget->drawDrawable(drawable, matrix); } SkISize SkAndroidSDKCanvas::getBaseLayerSize() const { diff --git a/src/utils/android/SkAndroidSDKCanvas.h b/src/utils/android/SkAndroidSDKCanvas.h index 47e771bb6a..a54315d478 100644 --- a/src/utils/android/SkAndroidSDKCanvas.h +++ b/src/utils/android/SkAndroidSDKCanvas.h @@ -78,7 +78,7 @@ protected: // PASS THROUGH - void onDrawDrawable(SkDrawable*) override; + void onDrawDrawable(SkDrawable*, const SkMatrix*) override; SkISize getBaseLayerSize() const override; bool getClipBounds(SkRect*) const override; bool getClipDeviceBounds(SkIRect*) const override;