1#include "SkGroupShape.h"
2
3SkGroupShape::SkGroupShape() {}
4
5SkGroupShape::~SkGroupShape() {
6    this->removeAllShapes();
7}
8
9int SkGroupShape::countShapes() const {
10    return fList.count();
11}
12
13SkShape* SkGroupShape::getShape(int index, SkMatrixRef** mr) const {
14    if ((unsigned)index < (unsigned)fList.count()) {
15        const Rec& rec = fList[index];
16        if (mr) {
17            *mr = rec.fMatrixRef;
18        }
19        return rec.fShape;
20    }
21    return NULL;
22}
23
24void SkGroupShape::addShape(int index, SkShape* shape, SkMatrixRef* mr) {
25    int count = fList.count();
26    if (NULL == shape || index < 0 || index > count) {
27        return;
28    }
29
30    shape->ref();
31    SkMatrixRef::SafeRef(mr);
32
33    Rec* rec;
34    if (index == count) {
35        rec = fList.append();
36    } else {
37        rec = fList.insert(index);
38    }
39    rec->fShape = shape;
40    rec->fMatrixRef = mr;
41}
42
43void SkGroupShape::removeShape(int index) {
44    if ((unsigned)index < (unsigned)fList.count()) {
45        Rec& rec = fList[index];
46        rec.fShape->unref();
47        SkMatrixRef::SafeUnref(rec.fMatrixRef);
48        fList.remove(index);
49    }
50}
51
52void SkGroupShape::removeAllShapes() {
53    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    }
60    fList.reset();
61}
62
63///////////////////////////////////////////////////////////////////////////////
64
65void SkGroupShape::onDraw(SkCanvas* canvas) {
66    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++;
76    }
77}
78
79SkFlattenable::Factory SkGroupShape::getFactory() {
80    return CreateProc;
81}
82
83void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
84    this->INHERITED::flatten(buffer);
85
86    int count = fList.count();
87    buffer.write32(count);
88    const Rec* rec = fList.begin();
89    const Rec* stop = fList.end();
90    while (rec < stop) {
91        buffer.writeFlattenable(rec->fShape);
92        if (rec->fMatrixRef) {
93            char storage[SkMatrix::kMaxFlattenSize];
94            uint32_t size = rec->fMatrixRef->flatten(storage);
95            buffer.write32(size);
96            buffer.writePad(storage, size);
97        } else {
98            buffer.write32(0);
99        }
100        rec += 1;
101    }
102}
103
104SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
105    int count = buffer.readS32();
106    for (int i = 0; i < count; i++) {
107        SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
108        SkMatrixRef* mr = NULL;
109        uint32_t size = buffer.readS32();
110        if (size) {
111            char storage[SkMatrix::kMaxFlattenSize];
112            buffer.read(storage, SkAlign4(size));
113            mr = SkNEW(SkMatrixRef);
114            mr->unflatten(storage);
115        }
116        if (shape) {
117            this->appendShape(shape, mr)->unref();
118        }
119        SkSafeUnref(mr);
120    }
121}
122
123SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
124    return SkNEW_ARGS(SkGroupShape, (buffer));
125}
126
127static SkFlattenable::Registrar gReg("SkGroupShape", SkGroupShape::CreateProc);
128
129