diff options
author | reed <reed@google.com> | 2014-11-19 06:59:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-19 06:59:41 -0800 |
commit | 7e76bff26e7c74902841ca4f607eb0b24a833a4a (patch) | |
tree | cb2f55b88a3ec2b3838dc9003808af03b6700e1d | |
parent | ec03a4608025106ea3f21353865c7d302c0a13c6 (diff) |
allow pictures to have a full bounds
BUG=skia:
Review URL: https://codereview.chromium.org/736583004
-rw-r--r-- | include/core/SkBBHFactory.h | 8 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 2 | ||||
-rw-r--r-- | include/core/SkDevice.h | 7 | ||||
-rw-r--r-- | include/core/SkPicture.h | 7 | ||||
-rw-r--r-- | include/core/SkPictureRecorder.h | 11 | ||||
-rw-r--r-- | samplecode/SampleArc.cpp | 23 | ||||
-rw-r--r-- | src/core/SkBBHFactory.cpp | 13 | ||||
-rw-r--r-- | src/core/SkCanvas.cpp | 15 | ||||
-rw-r--r-- | src/core/SkCanvasDrawable.cpp | 22 | ||||
-rw-r--r-- | src/core/SkPicture.cpp | 5 | ||||
-rw-r--r-- | src/core/SkPictureRecorder.cpp | 17 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 8 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 3 | ||||
-rw-r--r-- | tests/PictureTest.cpp | 2 |
14 files changed, 103 insertions, 40 deletions
diff --git a/include/core/SkBBHFactory.h b/include/core/SkBBHFactory.h index 67c9cd767d..2cc37e5491 100644 --- a/include/core/SkBBHFactory.h +++ b/include/core/SkBBHFactory.h @@ -9,7 +9,7 @@ #define SkBBHFactory_DEFINED #include "SkSize.h" -#include "SkPoint.h" +#include "SkRect.h" class SkBBoxHierarchy; @@ -18,13 +18,13 @@ public: /** * Allocate a new SkBBoxHierarchy. Return NULL on failure. */ - virtual SkBBoxHierarchy* operator()(int width, int height) const = 0; + virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0; virtual ~SkBBHFactory() {}; }; class SK_API SkRTreeFactory : public SkBBHFactory { public: - virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE; + virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const SK_OVERRIDE; private: typedef SkBBHFactory INHERITED; }; @@ -50,7 +50,7 @@ public: SkTileGridFactory(const TileGridInfo& info) : fInfo(info) { } - virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE; + virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const SK_OVERRIDE; private: TileGridInfo fInfo; diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 276b39236f..d172674c41 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -1335,7 +1335,7 @@ private: kDefault_InitFlags = 0, kConservativeRasterClip_InitFlag = 1 << 0, }; - SkCanvas(int width, int height, InitFlags); + SkCanvas(const SkIRect& bounds, InitFlags); SkCanvas(SkBaseDevice*, const SkSurfaceProps*, InitFlags); SkCanvas(const SkBitmap&, const SkSurfaceProps&); diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index 471a76be8e..3c26baca5b 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -53,6 +53,12 @@ public: bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height()); } + SkIRect getGlobalBounds() const { + SkIRect bounds; + this->getGlobalBounds(&bounds); + return bounds; + } + int width() const { return this->imageInfo().width(); } @@ -366,6 +372,7 @@ private: friend class SkDeviceFilteredPaint; friend class SkDeviceImageFilterProxy; friend class SkDeferredDevice; // for newSurface + friend class SkNoPixelsBitmapDevice; friend class SkSurface_Raster; diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index 99bca367d9..c69db37ffa 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -130,7 +130,7 @@ public: It does not necessarily reflect the bounds of what has been recorded into the picture. @return the cull rect used to create this picture */ - const SkRect cullRect() const { return SkRect::MakeWH(fCullWidth, fCullHeight); } + SkRect cullRect() const { return fCullRect; } /** Return a non-zero, unique value representing the picture. This call is only valid when not recording. Between a beginRecording/endRecording @@ -260,15 +260,14 @@ private: static bool IsValidPictInfo(const SkPictInfo& info); // Takes ownership of the SkRecord, refs the (optional) drawablePicts and BBH. - SkPicture(SkScalar width, SkScalar height, SkRecord*, SkData* drawablePicts, + SkPicture(const SkRect& cullRect, SkRecord*, SkData* drawablePicts, SkBBoxHierarchy*); static SkPicture* Forwardport(const SkPictInfo&, const SkPictureData*); static SkPictureData* Backport(const SkRecord&, const SkPictInfo&, SkPicture const* const drawablePics[], int drawableCount); - const SkScalar fCullWidth; - const SkScalar fCullHeight; + const SkRect fCullRect; mutable SkAutoTUnref<const AccelData> fAccelData; mutable SkTDArray<DeletionListener*> fDeletionListeners; // pointers are refed SkAutoTDelete<SkRecord> fRecord; diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h index de216b4e5b..a8ca600b81 100644 --- a/include/core/SkPictureRecorder.h +++ b/include/core/SkPictureRecorder.h @@ -50,10 +50,16 @@ public: @param recordFlags optional flags that control recording. @return the canvas. */ - SkCanvas* beginRecording(SkScalar width, SkScalar height, + SkCanvas* beginRecording(const SkRect& bounds, SkBBHFactory* bbhFactory = NULL, uint32_t recordFlags = 0); + SkCanvas* beginRecording(SkScalar width, SkScalar height, + SkBBHFactory* bbhFactory = NULL, + uint32_t recordFlags = 0) { + return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags); + } + /** Returns the recording canvas if one is active, or NULL if recording is not active. This does not alter the refcnt on the canvas (if present). */ @@ -79,8 +85,7 @@ private: void partialReplay(SkCanvas* canvas) const; uint32_t fFlags; - SkScalar fCullWidth; - SkScalar fCullHeight; + SkRect fCullRect; SkAutoTUnref<SkBBoxHierarchy> fBBH; SkAutoTUnref<SkRecorder> fRecorder; SkAutoTDelete<SkRecord> fRecord; diff --git a/samplecode/SampleArc.cpp b/samplecode/SampleArc.cpp index a44eeb59ba..ecea90bf3f 100644 --- a/samplecode/SampleArc.cpp +++ b/samplecode/SampleArc.cpp @@ -37,6 +37,27 @@ static void testparse() { SkParsePath::ToSVGString(p2, &str2); } +#include "SkPictureRecorder.h" +static void test_pictbounds(SkCanvas* canvas) { + SkRect r = SkRect::MakeXYWH(100, 50, 100, 100); + SkPictureRecorder recorder; + { + SkCanvas* c = recorder.beginRecording(r, NULL, 0); + c->drawOval(r, SkPaint()); + + SkIRect ir; + c->getClipDeviceBounds(&ir); + SkDebugf("devbounds [%d %d %d %d]\n", ir.left(), ir.top(), ir.right(), ir.bottom()); + + SkASSERT(!c->quickReject(r)); + } + SkPicture* pic = recorder.endRecording(); + + canvas->drawPicture(pic); + SkASSERT(pic->cullRect() == r); + pic->unref(); +} + class ArcsView : public SampleView { class MyDrawable : public SkCanvasDrawable { SkRect fR; @@ -176,6 +197,8 @@ protected: } virtual void onDrawContent(SkCanvas* canvas) { + if (true) { test_pictbounds(canvas); return; } + fDrawable->setSweep(SampleCode::GetAnimScalar(SkIntToScalar(360)/24, SkIntToScalar(360))); diff --git a/src/core/SkBBHFactory.cpp b/src/core/SkBBHFactory.cpp index 22f816c4d9..4b9ae558e2 100644 --- a/src/core/SkBBHFactory.cpp +++ b/src/core/SkBBHFactory.cpp @@ -9,15 +9,20 @@ #include "SkRTree.h" #include "SkTileGrid.h" - -SkBBoxHierarchy* SkRTreeFactory::operator()(int width, int height) const { - SkScalar aspectRatio = SkScalarDiv(SkIntToScalar(width), SkIntToScalar(height)); +SkBBoxHierarchy* SkRTreeFactory::operator()(const SkRect& bounds) const { + SkScalar aspectRatio = bounds.width() / bounds.height(); return SkNEW_ARGS(SkRTree, (aspectRatio)); } -SkBBoxHierarchy* SkTileGridFactory::operator()(int width, int height) const { +SkBBoxHierarchy* SkTileGridFactory::operator()(const SkRect& bounds) const { SkASSERT(fInfo.fMargin.width() >= 0); SkASSERT(fInfo.fMargin.height() >= 0); + + // We want a conservative answer for the size... + const SkIRect ibounds = bounds.roundOut(); + const int width = ibounds.width(); + const int height = ibounds.height(); + // Note: SkIRects are non-inclusive of the right() column and bottom() row. // For example, an SkIRect at 0,0 with a size of (1,1) will only have // content at pixel (0,0) and will report left=0 and right=1, hence the diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 4fda7a37b3..31a9a7970b 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -431,7 +431,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { } device->onAttachToCanvas(this); fMCRec->fLayer->fDevice = SkRef(device); - fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height())); + fMCRec->fRasterClip.setRect(device->getGlobalBounds()); } return device; } @@ -453,7 +453,11 @@ static SkBitmap make_nopixels(int width, int height) { class SkNoPixelsBitmapDevice : public SkBitmapDevice { public: - SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {} + SkNoPixelsBitmapDevice(const SkIRect& bounds) + : INHERITED(make_nopixels(bounds.width(), bounds.height())) + { + this->setOrigin(bounds.x(), bounds.y()); + } private: @@ -466,16 +470,17 @@ SkCanvas::SkCanvas(int width, int height) { inc_canvas(); - this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref(); + this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, + (SkIRect::MakeWH(width, height))), kDefault_InitFlags)->unref(); } -SkCanvas::SkCanvas(int width, int height, InitFlags flags) +SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) , fProps(SkSurfaceProps::kLegacyFontHost_InitType) { inc_canvas(); - this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref(); + this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (bounds)), flags)->unref(); } SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags) diff --git a/src/core/SkCanvasDrawable.cpp b/src/core/SkCanvasDrawable.cpp index 0065d430f9..e0120f0bb1 100644 --- a/src/core/SkCanvasDrawable.cpp +++ b/src/core/SkCanvasDrawable.cpp @@ -23,9 +23,22 @@ static int32_t next_generation_id() { SkCanvasDrawable::SkCanvasDrawable() : fGenerationID(0) {} +static void draw_bbox(SkCanvas* canvas, const SkRect& r) { + SkPaint paint; + paint.setStyle(SkPaint::kStroke_Style); + paint.setColor(0xFFFF7088); + canvas->drawRect(r, paint); + canvas->drawLine(r.left(), r.top(), r.right(), r.bottom(), paint); + canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), paint); +} + void SkCanvasDrawable::draw(SkCanvas* canvas) { SkAutoCanvasRestore acr(canvas, true); this->onDraw(canvas); + + if (false) { + draw_bbox(canvas, this->getBounds()); + } } SkPicture* SkCanvasDrawable::newPictureSnapshot(SkBBHFactory* bbhFactory, uint32_t recordFlags) { @@ -52,8 +65,13 @@ void SkCanvasDrawable::notifyDrawingChanged() { #include "SkPictureRecorder.h" SkPicture* SkCanvasDrawable::onNewPictureSnapshot(SkBBHFactory* bbhFactory, uint32_t recordFlags) { - const SkRect bounds = this->getBounds(); SkPictureRecorder recorder; - this->draw(recorder.beginRecording(bounds.width(), bounds.height(), bbhFactory, recordFlags)); + + const SkRect bounds = this->getBounds(); + SkCanvas* canvas = recorder.beginRecording(bounds, bbhFactory, recordFlags); + this->draw(canvas); + if (false) { + draw_bbox(canvas, bounds); + } return recorder.endRecording(); } diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 4c97cb71b9..7f4b33afac 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -530,10 +530,9 @@ uint32_t SkPicture::uniqueID() const { return fUniqueID; } -SkPicture::SkPicture(SkScalar width, SkScalar height, SkRecord* record, SkData* drawablePicts, +SkPicture::SkPicture(const SkRect& cullRect, SkRecord* record, SkData* drawablePicts, SkBBoxHierarchy* bbh) - : fCullWidth(width) - , fCullHeight(height) + : fCullRect(cullRect) , fRecord(record) , fBBH(SkSafeRef(bbh)) , fDrawablePicts(SkSafeRef(drawablePicts)) diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index bc8bffb9b3..aea9e389da 100644 --- a/src/core/SkPictureRecorder.cpp +++ b/src/core/SkPictureRecorder.cpp @@ -18,20 +18,19 @@ SkPictureRecorder::SkPictureRecorder() {} SkPictureRecorder::~SkPictureRecorder() {} -SkCanvas* SkPictureRecorder::beginRecording(SkScalar width, SkScalar height, +SkCanvas* SkPictureRecorder::beginRecording(const SkRect& cullRect, SkBBHFactory* bbhFactory /* = NULL */, uint32_t recordFlags /* = 0 */) { + fCullRect = cullRect; fFlags = recordFlags; - fCullWidth = width; - fCullHeight = height; if (bbhFactory) { - fBBH.reset((*bbhFactory)(width, height)); + fBBH.reset((*bbhFactory)(cullRect)); SkASSERT(fBBH.get()); } fRecord.reset(SkNEW(SkRecord)); - fRecorder.reset(SkNEW_ARGS(SkRecorder, (fRecord.get(), width, height))); + fRecorder.reset(SkNEW_ARGS(SkRecorder, (fRecord.get(), cullRect))); return this->getRecordingCanvas(); } @@ -52,12 +51,10 @@ SkPicture* SkPictureRecorder::endRecording() { } if (fBBH.get()) { - SkRect cullRect = SkRect::MakeWH(fCullWidth, fCullHeight); - if (saveLayerData) { - SkRecordComputeLayers(cullRect, *fRecord, fBBH.get(), saveLayerData); + SkRecordComputeLayers(fCullRect, *fRecord, fBBH.get(), saveLayerData); } else { - SkRecordFillBounds(cullRect, *fRecord, fBBH.get()); + SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); } } @@ -65,7 +62,7 @@ SkPicture* SkPictureRecorder::endRecording() { SkBBHFactory* factory = NULL; uint32_t recordFlags = 0; SkAutoDataUnref drawablePicts(fRecorder->newDrawableSnapshot(factory, recordFlags)); - SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight, fRecord.detach(), + SkPicture* pict = SkNEW_ARGS(SkPicture, (fCullRect, fRecord.detach(), drawablePicts, fBBH.get())); if (saveLayerData) { diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 1af328afd2..998fb6645b 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -10,9 +10,13 @@ #include "SkPatchUtils.h" #include "SkPicture.h" -// SkCanvas will fail in mysterious ways if it doesn't know the real width and height. SkRecorder::SkRecorder(SkRecord* record, int width, int height) - : SkCanvas(width, height, SkCanvas::kConservativeRasterClip_InitFlag) + : SkCanvas(SkIRect::MakeWH(width, height), SkCanvas::kConservativeRasterClip_InitFlag) + , fRecord(record) + , fSaveLayerCount(0) {} + +SkRecorder::SkRecorder(SkRecord* record, const SkRect& bounds) + : SkCanvas(bounds.roundOut(), SkCanvas::kConservativeRasterClip_InitFlag) , fRecord(record) , fSaveLayerCount(0) {} diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 563f16d124..7b2cbfe3a0 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -18,7 +18,8 @@ class SkRecorder : public SkCanvas { public: // Does not take ownership of the SkRecord. - SkRecorder(SkRecord*, int width, int height); + SkRecorder(SkRecord*, int width, int height); // legacy version + SkRecorder(SkRecord*, const SkRect& bounds); virtual ~SkRecorder() SK_OVERRIDE; // return a (new or ref'd) data containing the array of pictures that were diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp index 5bc60371c9..c9298335f1 100644 --- a/tests/PictureTest.cpp +++ b/tests/PictureTest.cpp @@ -1842,7 +1842,7 @@ struct CountingBBH : public SkBBoxHierarchy { class SpoonFedBBHFactory : public SkBBHFactory { public: explicit SpoonFedBBHFactory(SkBBoxHierarchy* bbh) : fBBH(bbh) {} - virtual SkBBoxHierarchy* operator()(int width, int height) const { + SkBBoxHierarchy* operator()(const SkRect&) const SK_OVERRIDE { return SkRef(fBBH); } private: |