aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-06-29 16:02:20 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-06-29 16:02:20 +0000
commit0ad336f8c6f6f0325eee309c9cd501ea432cc33e (patch)
tree5ce71598d388b28a6ea3d6f03528dc8bb2df88cf
parent0bfffc59a0d4967a18cc3c4f429af3f706c18511 (diff)
add shape flatten so they work properly in pictures
add flatten/unflatten to matrix git-svn-id: http://skia.googlecode.com/svn/trunk@242 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gm/shapes.cpp7
-rw-r--r--include/core/SkMatrix.h5
-rw-r--r--include/core/SkShape.h12
-rw-r--r--include/effects/SkGroupShape.h5
-rw-r--r--include/effects/SkRectShape.h5
-rw-r--r--samplecode/SampleShapes.cpp20
-rw-r--r--src/core/SkMatrix.cpp14
-rw-r--r--src/core/SkPicturePlayback.cpp31
-rw-r--r--src/core/SkPictureRecord.cpp1
-rw-r--r--src/core/SkShape.cpp44
-rw-r--r--src/effects/SkGroupShape.cpp36
-rw-r--r--src/effects/SkRectShape.cpp2
12 files changed, 145 insertions, 37 deletions
diff --git a/gm/shapes.cpp b/gm/shapes.cpp
index 2cf3f5e01d..b3d48638a4 100644
--- a/gm/shapes.cpp
+++ b/gm/shapes.cpp
@@ -57,8 +57,6 @@ public:
for (size_t i = 0; i < SK_ARRAY_COUNT(fMatrixRefs); i++) {
SkSafeRef(fMatrixRefs[i] = fGroup.getShapeMatrixRef(i));
}
-
- fAngle = 0;
}
virtual ~ShapesGM() {
@@ -80,15 +78,12 @@ protected:
canvas->drawColor(0xFFDDDDDD);
}
- int fAngle;
-
virtual void onDraw(SkCanvas* canvas) {
this->drawBG(canvas);
SkMatrix saveM = *fMatrixRefs[3];
- fAngle = (fAngle + 5) % 360;
SkScalar c = SkIntToScalar(50);
- fMatrixRefs[3]->preRotate(SkIntToScalar(fAngle), c, c);
+ fMatrixRefs[3]->preRotate(SkIntToScalar(30), c, c);
SkMatrix matrix;
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index aa008cb2d9..9dd4fc9c5c 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -399,6 +399,11 @@ public:
friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
}
+
+ // return the number of bytes written, whether or not buffer is null
+ uint32_t flatten(void* buffer) const;
+ // return the number of bytes read
+ uint32_t unflatten(const void* buffer);
void dump() const;
void toDumpString(SkString*) const;
diff --git a/include/core/SkShape.h b/include/core/SkShape.h
index abe4e268af..6cee70e751 100644
--- a/include/core/SkShape.h
+++ b/include/core/SkShape.h
@@ -9,7 +9,8 @@ class SkWStream;
class SkShape : public SkFlattenable {
public:
- SkShape() {}
+ SkShape();
+ virtual ~SkShape();
void draw(SkCanvas*);
@@ -24,15 +25,18 @@ public:
void drawMatrix(SkCanvas*, const SkMatrix&);
// overrides
+ virtual Factory getFactory();
virtual void flatten(SkFlattenableWriteBuffer&);
+ // public for Registrar
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
protected:
- virtual void onDraw(SkCanvas*) = 0;
+ virtual void onDraw(SkCanvas*);
- SkShape(SkFlattenableReadBuffer&) {}
+ SkShape(SkFlattenableReadBuffer&);
private:
- static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
typedef SkFlattenable INHERITED;
};
diff --git a/include/effects/SkGroupShape.h b/include/effects/SkGroupShape.h
index 58ebeccf9e..2c851fac66 100644
--- a/include/effects/SkGroupShape.h
+++ b/include/effects/SkGroupShape.h
@@ -128,6 +128,9 @@ public:
virtual Factory getFactory();
virtual void flatten(SkFlattenableWriteBuffer&);
+ // public for Registrar
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
protected:
// overrides
virtual void onDraw(SkCanvas*);
@@ -141,8 +144,6 @@ private:
};
SkTDArray<Rec> fList;
- static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
typedef SkShape INHERITED;
};
diff --git a/include/effects/SkRectShape.h b/include/effects/SkRectShape.h
index dfc07e95c7..9b8cfc175c 100644
--- a/include/effects/SkRectShape.h
+++ b/include/effects/SkRectShape.h
@@ -37,6 +37,9 @@ public:
virtual Factory getFactory();
virtual void flatten(SkFlattenableWriteBuffer&);
+ // public for Registrar
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
protected:
SkRectShape(SkFlattenableReadBuffer&);
@@ -47,8 +50,6 @@ private:
SkRect fBounds;
SkSize fRadii;
- static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
-
typedef SkPaintShape INHERITED;
};
diff --git a/samplecode/SampleShapes.cpp b/samplecode/SampleShapes.cpp
index 81f6e4f6b1..95efd0fb48 100644
--- a/samplecode/SampleShapes.cpp
+++ b/samplecode/SampleShapes.cpp
@@ -2,6 +2,7 @@
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPicture.h"
+#include "SkStream.h"
#include "SkView.h"
#include "SkRectShape.h"
@@ -83,6 +84,20 @@ protected:
canvas->drawColor(0xFFDDDDDD);
}
+ void drawpicture(SkCanvas* canvas, SkPicture& pict) {
+#if 1
+ SkDynamicMemoryWStream ostream;
+ pict.serialize(&ostream);
+
+ SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
+ SkPicture newPict(&istream);
+
+ canvas->drawPicture(newPict);
+#else
+ canvas->drawPicture(pict);
+#endif
+ }
+
int fAngle;
virtual void onDraw(SkCanvas* canvas) {
@@ -105,7 +120,7 @@ protected:
matrix.preScale(SK_Scalar1*2, SK_Scalar1*2);
gs->appendShape(&fGroup, matrix);
-#if 0
+#if 0
canvas->drawShape(gs);
#else
SkPicture pict;
@@ -116,7 +131,8 @@ protected:
cv->scale(-SK_Scalar1, SK_Scalar1);
cv->drawShape(gs);
pict.endRecording();
- canvas->drawPicture(pict);
+
+ drawpicture(canvas, pict);
#endif
*fMatrixRefs[3] = saveM;
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index ac5ae926e0..48fa804d9b 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -1582,6 +1582,20 @@ bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[],
///////////////////////////////////////////////////////////////////////////////
+uint32_t SkMatrix::flatten(void* buffer) const {
+ // TODO write less for simple matrices
+ if (buffer) {
+ memcpy(buffer, fMat, 9 * sizeof(SkScalar));
+ }
+ return 9 * sizeof(SkScalar);
+}
+
+uint32_t SkMatrix::unflatten(const void* buffer) {
+ memcpy(fMat, buffer, 9 * sizeof(SkScalar));
+ this->setTypeMask(kUnknown_Mask);
+ return 9 * sizeof(SkScalar);
+}
+
void SkMatrix::dump() const {
SkString str;
this->toDumpString(&str);
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 24fcd8e57d..77ac9122a7 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -246,7 +246,7 @@ SkPicturePlayback::~SkPicturePlayback() {
SkDELETE_ARRAY(fPictureRefs);
for (int i = 0; i < fShapeCount; i++) {
- fShapes[i]->unref();
+ SkSafeUnref(fShapes[i]);
}
SkDELETE_ARRAY(fShapes);
@@ -279,7 +279,7 @@ void SkPicturePlayback::dumpSize() const {
#define PICT_PAINT_TAG SkSetFourByteTag('p', 'n', 't', ' ')
#define PICT_PATH_TAG SkSetFourByteTag('p', 't', 'h', ' ')
#define PICT_REGION_TAG SkSetFourByteTag('r', 'g', 'n', ' ')
-
+#define PICT_SHAPE_TAG SkSetFourByteTag('s', 'h', 'p', ' ')
#include "SkStream.h"
@@ -376,6 +376,11 @@ void SkPicturePlayback::serialize(SkWStream* stream) const {
buffer.writePad(storage.get(), size);
}
+ writeTagSize(buffer, PICT_SHAPE_TAG, fShapeCount);
+ for (i = 0; i < fShapeCount; i++) {
+ buffer.writeFlattenable(fShapes[i]);
+ }
+
// now we can write to the stream again
writeFactories(stream, factRecorder);
@@ -386,13 +391,6 @@ void SkPicturePlayback::serialize(SkWStream* stream) const {
fPictureRefs[i]->serialize(stream);
}
-#if 0
- writeTagSize(stream, PICT_SHAPE_TAG, fShapeCount);
- for (i = 0; i < fShapeCount; i++) {
- fShapes[i]->serialize(stream);
- }
-#endif
-
writeTagSize(stream, PICT_ARRAYS_TAG, buffer.size());
buffer.writeToStream(stream);
}
@@ -491,6 +489,12 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
SkDEBUGCODE(uint32_t bytes =) fRegions[i].unflatten(buffer.skip(size));
SkASSERT(size == bytes);
}
+
+ fShapeCount = readTagSize(buffer, PICT_SHAPE_TAG);
+ fShapes = SkNEW_ARRAY(SkShape*, fShapeCount);
+ for (i = 0; i < fShapeCount; i++) {
+ fShapes[i] = reinterpret_cast<SkShape*>(buffer.readFlattenable());
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -633,9 +637,12 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
const SkPaint& paint = *getPaint();
canvas.drawRect(*fReader.skipRect(), paint);
} break;
- case DRAW_SHAPE:
- canvas.drawShape(getShape());
- break;
+ case DRAW_SHAPE: {
+ SkShape* shape = getShape();
+ if (shape) {
+ canvas.drawShape(shape);
+ }
+ } break;
case DRAW_SPRITE: {
const SkPaint* paint = getPaint();
const SkBitmap& bitmap = getBitmap();
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index f0f3402790..4778726943 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -413,6 +413,7 @@ void SkPictureRecord::reset() {
fPaints.reset();
fPictureRefs.unrefAll();
fRegions.reset();
+ fShapes.unrefAll();
fWriter.reset();
fHeap.reset();
diff --git a/src/core/SkShape.cpp b/src/core/SkShape.cpp
index e5fa8ff487..cd405dbf61 100644
--- a/src/core/SkShape.cpp
+++ b/src/core/SkShape.cpp
@@ -2,6 +2,23 @@
#include "SkShape.h"
#include "SkMatrix.h"
+#if 0
+static int gShapeCounter;
+static void inc_shape(const SkShape* s) {
+ SkDebugf("inc %d\n", gShapeCounter);
+ gShapeCounter += 1;
+}
+static void dec_shape(const SkShape* s) {
+ --gShapeCounter;
+ SkDebugf("dec %d\n", gShapeCounter);
+}
+#else
+#define inc_shape(s)
+#define dec_shape(s)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
void SkShape::draw(SkCanvas* canvas) {
int saveCount = canvas->getSaveCount();
this->onDraw(canvas);
@@ -24,5 +41,30 @@ void SkShape::drawMatrix(SkCanvas* canvas, const SkMatrix& matrix) {
///////////////////////////////////////////////////////////////////////////////
-void SkShape::flatten(SkFlattenableWriteBuffer& buffer) {}
+SkShape::SkShape() {
+ inc_shape(this);
+}
+
+SkShape::~SkShape() {
+ dec_shape(this);
+}
+
+SkShape::SkShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
+ inc_shape(this);
+}
+
+SkFlattenable* SkShape::CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkShape, (buffer));
+}
+
+SkFlattenable::Factory SkShape::getFactory() {
+ return CreateProc;
+}
+
+void SkShape::flatten(SkFlattenableWriteBuffer& buffer) {
+ this->INHERITED::flatten(buffer);
+}
+
+void SkShape::onDraw(SkCanvas*) {}
+static SkFlattenable::Registrar gReg("SkShape", SkShape::CreateProc);
diff --git a/src/effects/SkGroupShape.cpp b/src/effects/SkGroupShape.cpp
index 3baa3152ed..0e7640f105 100644
--- a/src/effects/SkGroupShape.cpp
+++ b/src/effects/SkGroupShape.cpp
@@ -80,6 +80,8 @@ SkFlattenable::Factory SkGroupShape::getFactory() {
return CreateProc;
}
+#define SAFE_MATRIX_STORAGE_SIZE (sizeof(SkMatrix)*2)
+
void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
this->INHERITED::flatten(buffer);
@@ -88,20 +90,36 @@ void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
const Rec* rec = fList.begin();
const Rec* stop = fList.end();
while (rec < stop) {
- SkShape* shape = rec->fShape;
- buffer.writeFunctionPtr((void*)shape->getFactory());
- shape->flatten(buffer);
- // todo: flatten the matrixref if present
+ buffer.writeFlattenable(rec->fShape);
+ if (rec->fMatrixRef) {
+ char storage[SAFE_MATRIX_STORAGE_SIZE];
+ uint32_t size = rec->fMatrixRef->flatten(storage);
+ buffer.write32(size);
+ buffer.writePad(storage, size);
+ } else {
+ buffer.write32(0);
+ }
+ rec += 1;
}
}
SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
int count = buffer.readS32();
for (int i = 0; i < count; i++) {
- SkFlattenable::Factory fact =
- (SkFlattenable::Factory)buffer.readFunctionPtr();
- this->appendShape((SkShape*)fact(buffer))->unref();
- // todo: unflatten the matrixref if present
+ SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
+ SkMatrixRef* mr = NULL;
+ uint32_t size = buffer.readS32();
+ if (size) {
+ char storage[SAFE_MATRIX_STORAGE_SIZE];
+ SkASSERT(size <= SAFE_MATRIX_STORAGE_SIZE);
+ buffer.read(storage, SkAlign4(size));
+ mr = SkNEW(SkMatrixRef);
+ mr->unflatten(storage);
+ }
+ if (shape) {
+ this->appendShape(shape, mr)->unref();
+ }
+ SkSafeUnref(mr);
}
}
@@ -109,3 +127,5 @@ SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkGroupShape, (buffer));
}
+static SkFlattenable::Registrar gReg("SkGroupShape", SkGroupShape::CreateProc);
+
diff --git a/src/effects/SkRectShape.cpp b/src/effects/SkRectShape.cpp
index 16886d4806..8a38a1ebe8 100644
--- a/src/effects/SkRectShape.cpp
+++ b/src/effects/SkRectShape.cpp
@@ -83,3 +83,5 @@ SkPaintShape::SkPaintShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer)
fPaint.unflatten(buffer);
}
+static SkFlattenable::Registrar gReg("SkRectShape", SkRectShape::CreateProc);
+