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 10 SkGroupShape::SkGroupShape() {} 11 12 SkGroupShape::~SkGroupShape() { 13 this->removeAllShapes(); 14 } 15 16 int SkGroupShape::countShapes() const { 17 return fList.count(); 18 } 19 20 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 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 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 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 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 86 SkFlattenable::Factory SkGroupShape::getFactory() { 87 return CreateProc; 88 } 89 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 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 130 SkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) { 131 return SkNEW_ARGS(SkGroupShape, (buffer)); 132 } 133 134 SK_DEFINE_FLATTENABLE_REGISTRAR(SkGroupShape) 135 136