blob: fd741ee43b6808dd9ed26030411a5f7c9739db44 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.comf76bacf2009-05-13 14:00:33 +00008#include "SkGroupShape.h"
9
10SkGroupShape::SkGroupShape() {}
11
12SkGroupShape::~SkGroupShape() {
13 this->removeAllShapes();
14}
15
16int SkGroupShape::countShapes() const {
17 return fList.count();
18}
19
reed@android.comf48f2812009-05-18 04:20:55 +000020SkShape* SkGroupShape::getShape(int index, SkMatrixRef** mr) const {
reed@android.comf76bacf2009-05-13 14:00:33 +000021 if ((unsigned)index < (unsigned)fList.count()) {
reed@android.comf48f2812009-05-18 04:20:55 +000022 const Rec& rec = fList[index];
23 if (mr) {
24 *mr = rec.fMatrixRef;
25 }
26 return rec.fShape;
reed@android.comf76bacf2009-05-13 14:00:33 +000027 }
28 return NULL;
29}
30
reed@android.comf48f2812009-05-18 04:20:55 +000031void SkGroupShape::addShape(int index, SkShape* shape, SkMatrixRef* mr) {
reed@android.comf76bacf2009-05-13 14:00:33 +000032 int count = fList.count();
33 if (NULL == shape || index < 0 || index > count) {
reed@android.comf48f2812009-05-18 04:20:55 +000034 return;
reed@android.comf76bacf2009-05-13 14:00:33 +000035 }
36
37 shape->ref();
reed@android.comf48f2812009-05-18 04:20:55 +000038 SkMatrixRef::SafeRef(mr);
39
40 Rec* rec;
reed@android.comf76bacf2009-05-13 14:00:33 +000041 if (index == count) {
reed@android.comf48f2812009-05-18 04:20:55 +000042 rec = fList.append();
reed@android.comf76bacf2009-05-13 14:00:33 +000043 } else {
reed@android.comf48f2812009-05-18 04:20:55 +000044 rec = fList.insert(index);
reed@android.comf76bacf2009-05-13 14:00:33 +000045 }
reed@android.comf48f2812009-05-18 04:20:55 +000046 rec->fShape = shape;
47 rec->fMatrixRef = mr;
reed@android.comf76bacf2009-05-13 14:00:33 +000048}
49
50void SkGroupShape::removeShape(int index) {
51 if ((unsigned)index < (unsigned)fList.count()) {
reed@android.comf48f2812009-05-18 04:20:55 +000052 Rec& rec = fList[index];
53 rec.fShape->unref();
54 SkMatrixRef::SafeUnref(rec.fMatrixRef);
reed@android.comf76bacf2009-05-13 14:00:33 +000055 fList.remove(index);
56 }
57}
58
59void SkGroupShape::removeAllShapes() {
reed@android.comf48f2812009-05-18 04:20:55 +000060 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 }
reed@android.comf76bacf2009-05-13 14:00:33 +000067 fList.reset();
68}
69
70///////////////////////////////////////////////////////////////////////////////
71
72void SkGroupShape::onDraw(SkCanvas* canvas) {
reed@android.comf48f2812009-05-18 04:20:55 +000073 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++;
reed@android.comf76bacf2009-05-13 14:00:33 +000083 }
84}
85
86SkFlattenable::Factory SkGroupShape::getFactory() {
87 return CreateProc;
88}
89
90void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
91 this->INHERITED::flatten(buffer);
92
93 int count = fList.count();
94 buffer.write32(count);
reed@android.comf48f2812009-05-18 04:20:55 +000095 const Rec* rec = fList.begin();
96 const Rec* stop = fList.end();
97 while (rec < stop) {
reed@android.com0ad336f2009-06-29 16:02:20 +000098 buffer.writeFlattenable(rec->fShape);
99 if (rec->fMatrixRef) {
reed@android.com4b7577b2009-06-29 16:14:41 +0000100 char storage[SkMatrix::kMaxFlattenSize];
reed@android.com0ad336f2009-06-29 16:02:20 +0000101 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;
reed@android.comf76bacf2009-05-13 14:00:33 +0000108 }
109}
110
111SkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
112 int count = buffer.readS32();
113 for (int i = 0; i < count; i++) {
reed@android.com0ad336f2009-06-29 16:02:20 +0000114 SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
115 SkMatrixRef* mr = NULL;
116 uint32_t size = buffer.readS32();
117 if (size) {
reed@android.com4b7577b2009-06-29 16:14:41 +0000118 char storage[SkMatrix::kMaxFlattenSize];
reed@android.com0ad336f2009-06-29 16:02:20 +0000119 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);
reed@android.comf76bacf2009-05-13 14:00:33 +0000127 }
128}
129
130SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
131 return SkNEW_ARGS(SkGroupShape, (buffer));
132}
133
caryclark@google.comd26147a2011-12-15 14:16:43 +0000134SK_DEFINE_FLATTENABLE_REGISTRAR(SkGroupShape)
reed@android.com0ad336f2009-06-29 16:02:20 +0000135