Home | History | Annotate | Download | only in effects
      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