1
2 /*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8 #include "SkGroupShape.h"
9
SkGroupShape()10 SkGroupShape::SkGroupShape() {}
11
~SkGroupShape()12 SkGroupShape::~SkGroupShape() {
13 this->removeAllShapes();
14 }
15
countShapes() const16 int SkGroupShape::countShapes() const {
17 return fList.count();
18 }
19
getShape(int index,SkMatrixRef ** mr) const20 SkShape* SkGroupShape::getShape(int index, SkMatrixRef** mr) const {
21 if ((unsigned)index < (unsigned)fList.count()) {
22 const Rec& rec = fList[index];
23 if (mr) {
24 *mr = rec.fMatrixRef;
25 }
26 return rec.fShape;
27 }
28 return NULL;
29 }
30
addShape(int index,SkShape * shape,SkMatrixRef * mr)31 void SkGroupShape::addShape(int index, SkShape* shape, SkMatrixRef* mr) {
32 int count = fList.count();
33 if (NULL == shape || index < 0 || index > count) {
34 return;
35 }
36
37 shape->ref();
38 SkMatrixRef::SafeRef(mr);
39
40 Rec* rec;
41 if (index == count) {
42 rec = fList.append();
43 } else {
44 rec = fList.insert(index);
45 }
46 rec->fShape = shape;
47 rec->fMatrixRef = mr;
48 }
49
removeShape(int index)50 void SkGroupShape::removeShape(int index) {
51 if ((unsigned)index < (unsigned)fList.count()) {
52 Rec& rec = fList[index];
53 rec.fShape->unref();
54 SkMatrixRef::SafeUnref(rec.fMatrixRef);
55 fList.remove(index);
56 }
57 }
58
removeAllShapes()59 void SkGroupShape::removeAllShapes() {
60 Rec* rec = fList.begin();
61 Rec* stop = fList.end();
62 while (rec < stop) {
63 rec->fShape->unref();
64 SkMatrixRef::SafeUnref(rec->fMatrixRef);
65 rec++;
66 }
67 fList.reset();
68 }
69
70 ///////////////////////////////////////////////////////////////////////////////
71
onDraw(SkCanvas * canvas)72 void SkGroupShape::onDraw(SkCanvas* canvas) {
73 const Rec* rec = fList.begin();
74 const Rec* stop = fList.end();
75 while (rec < stop) {
76 SkShape* shape = rec->fShape;
77 if (rec->fMatrixRef) {
78 shape->drawMatrix(canvas, *rec->fMatrixRef);
79 } else {
80 shape->draw(canvas);
81 }
82 rec++;
83 }
84 }
85
getFactory()86 SkFlattenable::Factory SkGroupShape::getFactory() {
87 return CreateProc;
88 }
89
flatten(SkFlattenableWriteBuffer & buffer)90 void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
91 this->INHERITED::flatten(buffer);
92
93 int count = fList.count();
94 buffer.write32(count);
95 const Rec* rec = fList.begin();
96 const Rec* stop = fList.end();
97 while (rec < stop) {
98 buffer.writeFlattenable(rec->fShape);
99 if (rec->fMatrixRef) {
100 char storage[SkMatrix::kMaxFlattenSize];
101 uint32_t size = rec->fMatrixRef->flatten(storage);
102 buffer.write32(size);
103 buffer.writePad(storage, size);
104 } else {
105 buffer.write32(0);
106 }
107 rec += 1;
108 }
109 }
110
SkGroupShape(SkFlattenableReadBuffer & buffer)111 SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
112 int count = buffer.readS32();
113 for (int i = 0; i < count; i++) {
114 SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
115 SkMatrixRef* mr = NULL;
116 uint32_t size = buffer.readS32();
117 if (size) {
118 char storage[SkMatrix::kMaxFlattenSize];
119 buffer.read(storage, SkAlign4(size));
120 mr = SkNEW(SkMatrixRef);
121 mr->unflatten(storage);
122 }
123 if (shape) {
124 this->appendShape(shape, mr)->unref();
125 }
126 SkSafeUnref(mr);
127 }
128 }
129
CreateProc(SkFlattenableReadBuffer & buffer)130 SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
131 return SkNEW_ARGS(SkGroupShape, (buffer));
132 }
133
134 SK_DEFINE_FLATTENABLE_REGISTRAR(SkGroupShape)
135
136