aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkCanvas.cpp8
-rw-r--r--src/core/SkShape.cpp85
-rw-r--r--src/core/core_files.mk1
-rw-r--r--src/effects/SkNWayCanvas.cpp7
-rw-r--r--src/shapes/SkGroupShape.cpp87
-rw-r--r--src/shapes/SkGroupShape.h65
-rw-r--r--src/shapes/SkRectShape.cpp85
-rw-r--r--src/shapes/SkRectShape.h55
-rw-r--r--src/utils/SkDumpCanvas.cpp4
-rw-r--r--src/utils/SkProxyCanvas.cpp4
10 files changed, 399 insertions, 2 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 199c1b0b97..57b4f7b340 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -22,6 +22,7 @@
#include "SkDrawLooper.h"
#include "SkPicture.h"
#include "SkScalarCompare.h"
+#include "SkShape.h"
#include "SkTemplates.h"
#include "SkUtils.h"
#include <new>
@@ -1357,12 +1358,19 @@ void SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength,
this->drawTextOnPath(text, byteLength, path, &matrix, paint);
}
+///////////////////////////////////////////////////////////////////////////////
+
void SkCanvas::drawPicture(SkPicture& picture) {
int saveCount = save();
picture.draw(this);
restoreToCount(saveCount);
}
+void SkCanvas::drawShape(SkShape* shape) {
+ // shape baseclass takes care of save/restore
+ shape->draw(this);
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkShape.cpp b/src/core/SkShape.cpp
new file mode 100644
index 0000000000..a6d19af96b
--- /dev/null
+++ b/src/core/SkShape.cpp
@@ -0,0 +1,85 @@
+#include "SkCanvas.h"
+#include "SkShape.h"
+#include "SkMatrix.h"
+
+SkShape::~SkShape() {
+ if (fMatrix) {
+ SkDELETE(fMatrix);
+ }
+}
+
+void SkShape::getMatrix(SkMatrix* matrix) const {
+ if (matrix) {
+ if (fMatrix) {
+ *matrix = *fMatrix;
+ } else {
+ matrix->reset();
+ }
+ }
+}
+
+void SkShape::setMatrix(const SkMatrix& matrix) {
+ if (matrix.isIdentity()) {
+ this->resetMatrix();
+ } else {
+ if (NULL == fMatrix) {
+ fMatrix = SkNEW(SkMatrix);
+ }
+ *fMatrix = matrix;
+ }
+}
+
+void SkShape::resetMatrix() {
+ if (fMatrix) {
+ SkDELETE(fMatrix);
+ fMatrix = NULL;
+ }
+}
+
+void SkShape::draw(SkCanvas* canvas) {
+ int saveCount = canvas->getSaveCount();
+ if (fMatrix) {
+ canvas->save(SkCanvas::kMatrix_SaveFlag);
+ canvas->concat(*fMatrix);
+ }
+ this->onDraw(canvas);
+ canvas->restoreToCount(saveCount);
+}
+
+void SkShape::drawXY(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
+ int saveCount = canvas->save(SkCanvas::kMatrix_SaveFlag);
+ canvas->translate(dx, dy);
+ if (fMatrix) {
+ canvas->concat(*fMatrix);
+ }
+ this->onDraw(canvas);
+ canvas->restoreToCount(saveCount);
+}
+
+void SkShape::drawMatrix(SkCanvas* canvas, const SkMatrix& matrix) {
+ int saveCount = canvas->save(SkCanvas::kMatrix_SaveFlag);
+ canvas->concat(matrix);
+ if (fMatrix) {
+ canvas->concat(*fMatrix);
+ }
+ this->onDraw(canvas);
+ canvas->restoreToCount(saveCount);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkShape::flatten(SkFlattenableWriteBuffer& buffer) {
+ buffer.writeBool(fMatrix != NULL);
+ if (fMatrix) {
+ *(SkMatrix*)buffer.reserve(sizeof(SkMatrix)) = *fMatrix;
+ }
+}
+
+SkShape::SkShape(SkFlattenableReadBuffer& buffer) {
+ fMatrix = NULL;
+ if (buffer.readBool()) {
+ fMatrix = SkNEW(SkMatrix);
+ buffer.read(fMatrix, sizeof(*fMatrix));
+ }
+}
+
diff --git a/src/core/core_files.mk b/src/core/core_files.mk
index 27849e7021..94e19d7255 100644
--- a/src/core/core_files.mk
+++ b/src/core/core_files.mk
@@ -72,6 +72,7 @@ SOURCE := \
SkScan_Hairline.cpp \
SkScan_Path.cpp \
SkShader.cpp \
+ SkShape.cpp \
SkSpriteBlitter_ARGB32.cpp \
SkSpriteBlitter_RGB16.cpp \
SkStream.cpp \
diff --git a/src/effects/SkNWayCanvas.cpp b/src/effects/SkNWayCanvas.cpp
index d60f259f67..d3c84a145e 100644
--- a/src/effects/SkNWayCanvas.cpp
+++ b/src/effects/SkNWayCanvas.cpp
@@ -248,6 +248,13 @@ void SkNWayCanvas::drawPicture(SkPicture& picture) {
}
}
+void SkNWayCanvas::drawShape(SkShape* shape) {
+ Iter iter(fList);
+ while (iter.next()) {
+ iter->drawShape(shape);
+ }
+}
+
void SkNWayCanvas::drawVertices(VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,
diff --git a/src/shapes/SkGroupShape.cpp b/src/shapes/SkGroupShape.cpp
new file mode 100644
index 0000000000..1322fe49b3
--- /dev/null
+++ b/src/shapes/SkGroupShape.cpp
@@ -0,0 +1,87 @@
+#include "SkGroupShape.h"
+
+SkGroupShape::SkGroupShape() {}
+
+SkGroupShape::~SkGroupShape() {
+ this->removeAllShapes();
+}
+
+int SkGroupShape::countShapes() const {
+ return fList.count();
+}
+
+SkShape* SkGroupShape::getShape(int index) const {
+ if ((unsigned)index < (unsigned)fList.count()) {
+ return fList[index];
+ }
+ return NULL;
+}
+
+SkShape* SkGroupShape::addShape(int index, SkShape* shape) {
+ int count = fList.count();
+ if (NULL == shape || index < 0 || index > count) {
+ return shape;
+ }
+
+ shape->ref();
+ SkShape** spot;
+ if (index == count) {
+ spot = fList.append();
+ } else {
+ spot = fList.insert(index);
+ }
+ *spot = shape;
+ return shape;
+}
+
+void SkGroupShape::removeShape(int index) {
+ if ((unsigned)index < (unsigned)fList.count()) {
+ fList[index]->unref();
+ fList.remove(index);
+ }
+}
+
+void SkGroupShape::removeAllShapes() {
+ fList.unrefAll();
+ fList.reset();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGroupShape::onDraw(SkCanvas* canvas) {
+ SkShape** iter = fList.begin();
+ SkShape** stop = fList.end();
+ while (iter < stop) {
+ (*iter)->draw(canvas);
+ iter++;
+ }
+}
+
+SkFlattenable::Factory SkGroupShape::getFactory() {
+ return CreateProc;
+}
+
+void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
+ this->INHERITED::flatten(buffer);
+
+ int count = fList.count();
+ buffer.write32(count);
+ for (int i = 0; i < count; i++) {
+ buffer.writeFunctionPtr((void*)fList[i]->getFactory());
+ fList[i]->flatten(buffer);
+ }
+}
+
+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();
+ }
+}
+
+SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkGroupShape, (buffer));
+}
+
diff --git a/src/shapes/SkGroupShape.h b/src/shapes/SkGroupShape.h
new file mode 100644
index 0000000000..de7574b9eb
--- /dev/null
+++ b/src/shapes/SkGroupShape.h
@@ -0,0 +1,65 @@
+#ifndef SkGroupShape_DEFINED
+#define SkGroupShape_DEFINED
+
+#include "SkShape.h"
+#include "SkTDArray.h"
+
+class SkGroupShape : public SkShape {
+public:
+ SkGroupShape();
+ virtual ~SkGroupShape();
+
+ /** Return the number of child shapes in this group
+ */
+ int countShapes() const;
+
+ /** Return the shape at the specified index. Note this does not affect the
+ owner count of the index'd shape. If index is out of range, returns NULL
+ */
+ SkShape* getShape(int index) const;
+
+ /** Ref the specified shape, and insert it into the child list at the
+ specified index. If index == countShapes(), then the shape will be
+ appended to the child list, otherwise if index is out of range, the
+ shape is not added. Either way, the shape parameter is returned.
+
+ Child shapes are drawn in order, after the parent, so the shape at index
+ 0 will be drawn first, and the shape at index countShapes() - 1 will be
+ drawn last.
+ */
+ SkShape* addShape(int index, SkShape*);
+
+ /** Helper method to append a shape, passing countShapes() for the index
+ */
+ SkShape* appendShape(SkShape* shape) {
+ return this->addShape(this->countShapes(), shape);
+ }
+
+ /** Unref the specified index, and remove it from the child list. If index
+ is out of range, does nothing.
+ */
+ void removeShape(int index);
+
+ /** Unrefs and removes all of the child shapes
+ */
+ void removeAllShapes();
+
+ // overrides
+ virtual Factory getFactory();
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ // overrides
+ virtual void onDraw(SkCanvas*);
+
+ SkGroupShape(SkFlattenableReadBuffer&);
+
+private:
+ SkTDArray<SkShape*> fList;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ typedef SkShape INHERITED;
+};
+
+#endif
diff --git a/src/shapes/SkRectShape.cpp b/src/shapes/SkRectShape.cpp
new file mode 100644
index 0000000000..16886d4806
--- /dev/null
+++ b/src/shapes/SkRectShape.cpp
@@ -0,0 +1,85 @@
+#include "SkRectShape.h"
+#include "SkCanvas.h"
+
+SkPaintShape::SkPaintShape() {
+ fPaint.setAntiAlias(true);
+}
+
+SkRectShape::SkRectShape() {
+ fBounds.setEmpty();
+ fRadii.set(0, 0);
+}
+
+void SkRectShape::setRect(const SkRect& bounds) {
+ fBounds = bounds;
+ fRadii.set(0, 0);
+}
+
+void SkRectShape::setOval(const SkRect& bounds) {
+ fBounds = bounds;
+ fRadii.set(-SK_Scalar1, -SK_Scalar1);
+}
+
+void SkRectShape::setCircle(SkScalar cx, SkScalar cy, SkScalar radius) {
+ fBounds.set(cx - radius, cy - radius, cx + radius, cy + radius);
+ fRadii.set(-SK_Scalar1, -SK_Scalar1);
+}
+
+void SkRectShape::setRRect(const SkRect& bounds, SkScalar rx, SkScalar ry) {
+ if (rx < 0) {
+ rx = 0;
+ }
+ if (ry < 0) {
+ ry = 0;
+ }
+
+ fBounds = bounds;
+ fRadii.set(rx, ry);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkRectShape::onDraw(SkCanvas* canvas) {
+ const SkPaint& paint = this->paint();
+
+ if (fRadii.fWidth < 0) {
+ canvas->drawOval(fBounds, paint);
+ } else if (fRadii.isZero()) {
+ canvas->drawRect(fBounds, paint);
+ } else {
+ canvas->drawRoundRect(fBounds, fRadii.fWidth, fRadii.fHeight, paint);
+ }
+}
+
+SkFlattenable::Factory SkRectShape::getFactory() {
+ return CreateProc;
+}
+
+void SkRectShape::flatten(SkFlattenableWriteBuffer& buffer) {
+ this->INHERITED::flatten(buffer);
+
+ buffer.writeRect(fBounds);
+ *(SkSize*)buffer.reserve(sizeof(SkSize)) = fRadii;
+}
+
+SkRectShape::SkRectShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
+ buffer.read(&fBounds, sizeof(fBounds));
+ buffer.read(&fRadii, sizeof(fRadii));
+}
+
+SkFlattenable* SkRectShape::CreateProc(SkFlattenableReadBuffer& buffer) {
+ return SkNEW_ARGS(SkRectShape, (buffer));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkPaintShape::flatten(SkFlattenableWriteBuffer& buffer) {
+ this->INHERITED::flatten(buffer);
+
+ fPaint.flatten(buffer);
+}
+
+SkPaintShape::SkPaintShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
+ fPaint.unflatten(buffer);
+}
+
diff --git a/src/shapes/SkRectShape.h b/src/shapes/SkRectShape.h
new file mode 100644
index 0000000000..dfc07e95c7
--- /dev/null
+++ b/src/shapes/SkRectShape.h
@@ -0,0 +1,55 @@
+#ifndef SkRectShape_DEFINED
+#define SkRectShape_DEFINED
+
+#include "SkShape.h"
+#include "SkPaint.h"
+#include "SkSize.h"
+
+class SkPaintShape : public SkShape {
+public:
+ SkPaintShape();
+
+ SkPaint& paint() { return fPaint; }
+ const SkPaint& paint() const { return fPaint; }
+
+ // overrides
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkPaintShape(SkFlattenableReadBuffer& buffer);
+
+private:
+ SkPaint fPaint;
+
+ typedef SkShape INHERITED;
+};
+
+class SkRectShape : public SkPaintShape {
+public:
+ SkRectShape();
+
+ void setRect(const SkRect&);
+ void setOval(const SkRect&);
+ void setCircle(SkScalar x, SkScalar y, SkScalar radius);
+ void setRRect(const SkRect&, SkScalar rx, SkScalar ry);
+
+ // overrides
+ virtual Factory getFactory();
+ virtual void flatten(SkFlattenableWriteBuffer&);
+
+protected:
+ SkRectShape(SkFlattenableReadBuffer&);
+
+ // overrides
+ virtual void onDraw(SkCanvas*);
+
+private:
+ SkRect fBounds;
+ SkSize fRadii;
+
+ static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
+
+ typedef SkPaintShape INHERITED;
+};
+
+#endif
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 1ef444cb70..7a05f0918d 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -350,6 +350,10 @@ void SkDumpCanvas::drawTextOnPath(const void* text, size_t byteLength,
str.c_str(), byteLength);
}
+void SkDumpCanvas::drawShape(SkShape* shape) {
+ this->dump(kDrawShape_Verb, NULL, "drawShape(%p)", shape);
+}
+
void SkDumpCanvas::drawPicture(SkPicture& picture) {
this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p)", &picture);
}
diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp
index 2a02b457c6..e38a0df59a 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -134,8 +134,8 @@ void SkProxyCanvas::drawTextOnPath(const void* text, size_t byteLength,
fProxy->drawTextOnPath(text, byteLength, path, matrix, paint);
}
-void SkProxyCanvas::drawPicture(SkPicture& picture) {
- fProxy->drawPicture(picture);
+void SkProxyCanvas::drawShape(SkShape* shape) {
+ fProxy->drawShape(shape);
}
void SkProxyCanvas::drawVertices(VertexMode vmode, int vertexCount,