--- /dev/null
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gm.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkString.h"
+
+namespace skiagm {
+
+static void create_bitmap(SkBitmap* bitmap) {
+ const int W = 100;
+ const int H = 100;
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, W, H);
+ bitmap->allocPixels();
+
+ SkCanvas canvas(*bitmap);
+ canvas.drawColor(SK_ColorRED);
+ SkPaint paint;
+ paint.setColor(SK_ColorBLUE);
+ canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint);
+}
+
+class ExtractBitmapGM : public GM {
+public:
+ ExtractBitmapGM() {}
+
+protected:
+ // overrides from SkEventSink
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("extractbitmap");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return make_isize(600, 600);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkBitmap bitmap;
+ create_bitmap(&bitmap);
+ int x = bitmap.width() / 2;
+ int y = bitmap.height() / 2;
+ SkBitmap subset;
+ bitmap.extractSubset(&subset, SkIRect::MakeXYWH(x, y, x, y));
+
+ canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
+
+ canvas->drawBitmap(bitmap, 0, 0);
+ canvas->drawBitmap(subset, 0, 0);
+
+ // Now do the same but with a device bitmap as source image
+ SkRefPtr<SkDevice> primaryDevice(canvas->getDevice());
+ SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice(
+ SkBitmap::kARGB_8888_Config, bitmap.width(),
+ bitmap.height(), true));
+ secondDevice->unref();
+ SkCanvas secondCanvas(secondDevice.get());
+ secondCanvas.writePixels(bitmap, 0, 0);
+
+ SkBitmap deviceBitmap = secondDevice->accessBitmap(false);
+ SkBitmap deviceSubset;
+ deviceBitmap.extractSubset(&deviceSubset,
+ SkIRect::MakeXYWH(x, y, x, y));
+
+ canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
+
+ canvas->drawBitmap(deviceBitmap, 0, 0);
+ canvas->drawBitmap(deviceSubset, 0, 0);
+
+ }
+
+private:
+ typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new ExtractBitmapGM; }
+static GMRegistry reg(MyFactory);
+
+}
'../samplecode/SampleDegenerateTwoPtRadials.cpp',
'../samplecode/SampleDither.cpp',
'../samplecode/SampleDitherBitmap.cpp',
- '../samplecode/SampleDrawBitmap.cpp',
'../samplecode/SampleDrawLooper.cpp',
'../samplecode/SampleEffects.cpp',
'../samplecode/SampleEmboss.cpp',
'../gm/degeneratesegments.cpp',
'../gm/dashing.cpp',
'../gm/drawbitmaprect.cpp',
+ '../gm/extractbitmap.cpp',
'../gm/emptypath.cpp',
'../gm/filltypes.cpp',
'../gm/filltypespersp.cpp',
+++ /dev/null
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SampleCode.h"
-#include "SkView.h"
-#include "SkCanvas.h"
-#include "SkShader.h"
-#include "SkUtils.h"
-#include "SkDevice.h"
-
-static void create_bitmap(SkBitmap* bitmap) {
- const int W = 100;
- const int H = 100;
- bitmap->setConfig(SkBitmap::kARGB_8888_Config, W, H);
- bitmap->allocPixels();
-
- SkCanvas canvas(*bitmap);
- canvas.drawColor(SK_ColorRED);
- SkPaint paint;
- paint.setColor(SK_ColorBLUE);
- canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint);
-}
-
-class DrawBitmapView : public SampleView {
- SkPath fPath;
-public:
- DrawBitmapView() {}
-
-protected:
- // overrides from SkEventSink
- virtual bool onQuery(SkEvent* evt) {
- if (SampleCode::TitleQ(*evt)) {
- SampleCode::TitleR(evt, "DrawBitmap");
- return true;
- }
- return this->INHERITED::onQuery(evt);
- }
-
- virtual void onDrawContent(SkCanvas* canvas) {
- SkBitmap bitmap;
- create_bitmap(&bitmap);
- int x = bitmap.width() / 2;
- int y = bitmap.height() / 2;
- SkBitmap subset;
- bitmap.extractSubset(&subset, SkIRect::MakeXYWH(x, y, x, y));
-
- canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
-
- canvas->drawBitmap(bitmap, 0, 0);
- canvas->drawBitmap(subset, 0, 0);
-
- // Now do the same but with a device bitmap as source image
- SkRefPtr<SkDevice> primaryDevice(canvas->getDevice());
- SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice(
- SkBitmap::kARGB_8888_Config, bitmap.width(),
- bitmap.height(), true));
- secondDevice->unref();
- SkCanvas secondCanvas(secondDevice.get());
- secondCanvas.writePixels(bitmap, 0, 0);
-
- SkBitmap deviceBitmap = secondDevice->accessBitmap(false);
- SkBitmap deviceSubset;
- deviceBitmap.extractSubset(&deviceSubset,
- SkIRect::MakeXYWH(x, y, x, y));
-
- canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
-
- canvas->drawBitmap(deviceBitmap, 0, 0);
- canvas->drawBitmap(deviceSubset, 0, 0);
-
- }
-
-private:
- typedef SampleView INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-static SkView* MyFactory() { return new DrawBitmapView; }
-static SkViewRegister reg(MyFactory);
* @return void* Pointer to the heap's copy of the bitmap. If NULL,
* the bitmap could not be copied.
*/
- const SkBitmap* addBitmap(const SkBitmap& bm) {
- const uint32_t genID = bm.getGenerationID();
+ const SkBitmap* addBitmap(const SkBitmap& orig) {
+ const uint32_t genID = orig.getGenerationID();
+ SkPixelRef* sharedPixelRef = NULL;
for (int i = fBitmaps.count() - 1; i >= 0; i--) {
if (genID == fBitmaps[i].fGenID) {
+ if (orig.pixelRefOffset() != fBitmaps[i].fBitmap->pixelRefOffset()) {
+ // In this case, the bitmaps share a pixelRef, but have
+ // different offsets. Keep track of the other bitmap so that
+ // instead of making another copy of the pixelRef we can use
+ // the copy we already made.
+ sharedPixelRef = fBitmaps[i].fBitmap->pixelRef();
+ break;
+ }
return fBitmaps[i].fBitmap;
}
}
// If the bitmap is mutable, we still need to do a deep copy, since the
// caller may modify it afterwards. That said, if the bitmap is mutable,
// but has no pixelRef, the copy constructor actually does a deep copy.
- if (fCanDoShallowCopies && (bm.isImmutable() || !bm.pixelRef())) {
- copy = new SkBitmap(bm);
+ if (fCanDoShallowCopies && (orig.isImmutable() || !orig.pixelRef())) {
+ copy = new SkBitmap(orig);
} else {
- copy = new SkBitmap();
- if (!bm.copyTo(copy, bm.getConfig())) {
- delete copy;
- return NULL;
+ if (sharedPixelRef != NULL) {
+ // Do a shallow copy of the bitmap to get the width, height, etc
+ copy = new SkBitmap(orig);
+ // Replace the pixelRef with the copy that was already made, and
+ // use the appropriate offset.
+ copy->setPixelRef(sharedPixelRef, orig.pixelRefOffset());
+ } else {
+ copy = new SkBitmap();
+ if (!orig.copyTo(copy, orig.getConfig())) {
+ delete copy;
+ return NULL;
+ }
}
}
BitmapInfo* info = fBitmaps.append();