diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkCanvas.cpp | 8 | ||||
-rw-r--r-- | src/core/SkShape.cpp | 85 | ||||
-rw-r--r-- | src/core/core_files.mk | 1 | ||||
-rw-r--r-- | src/effects/SkNWayCanvas.cpp | 7 | ||||
-rw-r--r-- | src/shapes/SkGroupShape.cpp | 87 | ||||
-rw-r--r-- | src/shapes/SkGroupShape.h | 65 | ||||
-rw-r--r-- | src/shapes/SkRectShape.cpp | 85 | ||||
-rw-r--r-- | src/shapes/SkRectShape.h | 55 | ||||
-rw-r--r-- | src/utils/SkDumpCanvas.cpp | 4 | ||||
-rw-r--r-- | src/utils/SkProxyCanvas.cpp | 4 |
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, |