blob: 0e7640f1057f123c32daef67c244a42d9497ad09 [file] [log] [blame]
reed@android.comf76bacf2009-05-13 14:00:33 +00001#include "SkGroupShape.h"
2
3SkGroupShape::SkGroupShape() {}
4
5SkGroupShape::~SkGroupShape() {
6 this->removeAllShapes();
7}
8
9int SkGroupShape::countShapes() const {
10 return fList.count();
11}
12
reed@android.comf48f2812009-05-18 04:20:55 +000013SkShape* SkGroupShape::getShape(int index, SkMatrixRef** mr) const {
reed@android.comf76bacf2009-05-13 14:00:33 +000014 if ((unsigned)index < (unsigned)fList.count()) {
reed@android.comf48f2812009-05-18 04:20:55 +000015 const Rec& rec = fList[index];
16 if (mr) {
17 *mr = rec.fMatrixRef;
18 }
19 return rec.fShape;
reed@android.comf76bacf2009-05-13 14:00:33 +000020 }
21 return NULL;
22}
23
reed@android.comf48f2812009-05-18 04:20:55 +000024void SkGroupShape::addShape(int index, SkShape* shape, SkMatrixRef* mr) {
reed@android.comf76bacf2009-05-13 14:00:33 +000025 int count = fList.count();
26 if (NULL == shape || index < 0 || index > count) {
reed@android.comf48f2812009-05-18 04:20:55 +000027 return;
reed@android.comf76bacf2009-05-13 14:00:33 +000028 }
29
30 shape->ref();
reed@android.comf48f2812009-05-18 04:20:55 +000031 SkMatrixRef::SafeRef(mr);
32
33 Rec* rec;
reed@android.comf76bacf2009-05-13 14:00:33 +000034 if (index == count) {
reed@android.comf48f2812009-05-18 04:20:55 +000035 rec = fList.append();
reed@android.comf76bacf2009-05-13 14:00:33 +000036 } else {
reed@android.comf48f2812009-05-18 04:20:55 +000037 rec = fList.insert(index);
reed@android.comf76bacf2009-05-13 14:00:33 +000038 }
reed@android.comf48f2812009-05-18 04:20:55 +000039 rec->fShape = shape;
40 rec->fMatrixRef = mr;
reed@android.comf76bacf2009-05-13 14:00:33 +000041}
42
43void SkGroupShape::removeShape(int index) {
44 if ((unsigned)index < (unsigned)fList.count()) {
reed@android.comf48f2812009-05-18 04:20:55 +000045 Rec& rec = fList[index];
46 rec.fShape->unref();
47 SkMatrixRef::SafeUnref(rec.fMatrixRef);
reed@android.comf76bacf2009-05-13 14:00:33 +000048 fList.remove(index);
49 }
50}
51
52void SkGroupShape::removeAllShapes() {
reed@android.comf48f2812009-05-18 04:20:55 +000053 Rec* rec = fList.begin();
54 Rec* stop = fList.end();
55 while (rec < stop) {
56 rec->fShape->unref();
57 SkMatrixRef::SafeUnref(rec->fMatrixRef);
58 rec++;
59 }
reed@android.comf76bacf2009-05-13 14:00:33 +000060 fList.reset();
61}
62
63///////////////////////////////////////////////////////////////////////////////
64
65void SkGroupShape::onDraw(SkCanvas* canvas) {
reed@android.comf48f2812009-05-18 04:20:55 +000066 const Rec* rec = fList.begin();
67 const Rec* stop = fList.end();
68 while (rec < stop) {
69 SkShape* shape = rec->fShape;
70 if (rec->fMatrixRef) {
71 shape->drawMatrix(canvas, *rec->fMatrixRef);
72 } else {
73 shape->draw(canvas);
74 }
75 rec++;
reed@android.comf76bacf2009-05-13 14:00:33 +000076 }
77}
78
79SkFlattenable::Factory SkGroupShape::getFactory() {
80 return CreateProc;
81}
82
reed@android.com0ad336f2009-06-29 16:02:20 +000083#define SAFE_MATRIX_STORAGE_SIZE (sizeof(SkMatrix)*2)
84
reed@android.comf76bacf2009-05-13 14:00:33 +000085void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
86 this->INHERITED::flatten(buffer);
87
88 int count = fList.count();
89 buffer.write32(count);
reed@android.comf48f2812009-05-18 04:20:55 +000090 const Rec* rec = fList.begin();
91 const Rec* stop = fList.end();
92 while (rec < stop) {
reed@android.com0ad336f2009-06-29 16:02:20 +000093 buffer.writeFlattenable(rec->fShape);
94 if (rec->fMatrixRef) {
95 char storage[SAFE_MATRIX_STORAGE_SIZE];
96 uint32_t size = rec->fMatrixRef->flatten(storage);
97 buffer.write32(size);
98 buffer.writePad(storage, size);
99 } else {
100 buffer.write32(0);
101 }
102 rec += 1;
reed@android.comf76bacf2009-05-13 14:00:33 +0000103 }
104}
105
106SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
107 int count = buffer.readS32();
108 for (int i = 0; i < count; i++) {
reed@android.com0ad336f2009-06-29 16:02:20 +0000109 SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
110 SkMatrixRef* mr = NULL;
111 uint32_t size = buffer.readS32();
112 if (size) {
113 char storage[SAFE_MATRIX_STORAGE_SIZE];
114 SkASSERT(size <= SAFE_MATRIX_STORAGE_SIZE);
115 buffer.read(storage, SkAlign4(size));
116 mr = SkNEW(SkMatrixRef);
117 mr->unflatten(storage);
118 }
119 if (shape) {
120 this->appendShape(shape, mr)->unref();
121 }
122 SkSafeUnref(mr);
reed@android.comf76bacf2009-05-13 14:00:33 +0000123 }
124}
125
126SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
127 return SkNEW_ARGS(SkGroupShape, (buffer));
128}
129
reed@android.com0ad336f2009-06-29 16:02:20 +0000130static SkFlattenable::Registrar gReg("SkGroupShape", SkGroupShape::CreateProc);
131