140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkGroupShape.h"
240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGroupShape::SkGroupShape() {}
440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGroupShape::~SkGroupShape() {
640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    this->removeAllShapes();
740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerint SkGroupShape::countShapes() const {
1040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return fList.count();
1140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkShape* SkGroupShape::getShape(int index, SkMatrixRef** mr) const {
1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if ((unsigned)index < (unsigned)fList.count()) {
1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        const Rec& rec = fList[index];
1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (mr) {
1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            *mr = rec.fMatrixRef;
1840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
1940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        return rec.fShape;
2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return NULL;
2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkGroupShape::addShape(int index, SkShape* shape, SkMatrixRef* mr) {
2540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    int count = fList.count();
2640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (NULL == shape || index < 0 || index > count) {
2740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        return;
2840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    shape->ref();
3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkMatrixRef::SafeRef(mr);
3240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
3340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    Rec* rec;
3440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (index == count) {
3540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec = fList.append();
3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
3740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec = fList.insert(index);
3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    rec->fShape = shape;
4040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    rec->fMatrixRef = mr;
4140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
4240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkGroupShape::removeShape(int index) {
4440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if ((unsigned)index < (unsigned)fList.count()) {
4540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        Rec& rec = fList[index];
4640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec.fShape->unref();
4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkMatrixRef::SafeUnref(rec.fMatrixRef);
4840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        fList.remove(index);
4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
5240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkGroupShape::removeAllShapes() {
5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    Rec* rec = fList.begin();
5440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    Rec* stop = fList.end();
5540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (rec < stop) {
5640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec->fShape->unref();
5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkMatrixRef::SafeUnref(rec->fMatrixRef);
5840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec++;
5940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
6040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    fList.reset();
6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
6240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
6440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkGroupShape::onDraw(SkCanvas* canvas) {
6640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    const Rec* rec = fList.begin();
6740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    const Rec* stop = fList.end();
6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (rec < stop) {
6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkShape* shape = rec->fShape;
7040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (rec->fMatrixRef) {
7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            shape->drawMatrix(canvas, *rec->fMatrixRef);
7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            shape->draw(canvas);
7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
7540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec++;
7640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
7740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkFlattenable::Factory SkGroupShape::getFactory() {
8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return CreateProc;
8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    this->INHERITED::flatten(buffer);
8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    int count = fList.count();
8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    buffer.write32(count);
8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    const Rec* rec = fList.begin();
8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    const Rec* stop = fList.end();
9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (rec < stop) {
9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        buffer.writeFlattenable(rec->fShape);
9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (rec->fMatrixRef) {
9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            char storage[SkMatrix::kMaxFlattenSize];
9440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            uint32_t size = rec->fMatrixRef->flatten(storage);
9540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            buffer.write32(size);
9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            buffer.writePad(storage, size);
9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            buffer.write32(0);
9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec += 1;
10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGroupShape::SkGroupShape(SkFlattenableReadBuffer& buffer) : INHERITED(buffer){
10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    int count = buffer.readS32();
10640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    for (int i = 0; i < count; i++) {
10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkShape* shape = reinterpret_cast<SkShape*>(buffer.readFlattenable());
10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkMatrixRef* mr = NULL;
10940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        uint32_t size = buffer.readS32();
11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (size) {
11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            char storage[SkMatrix::kMaxFlattenSize];
11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            buffer.read(storage, SkAlign4(size));
11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            mr = SkNEW(SkMatrixRef);
11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            mr->unflatten(storage);
11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (shape) {
11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            this->appendShape(shape, mr)->unref();
11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(mr);
12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkFlattenable* SkGroupShape::CreateProc(SkFlattenableReadBuffer& buffer) {
12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return SkNEW_ARGS(SkGroupShape, (buffer));
12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkFlattenable::Registrar gReg("SkGroupShape", SkGroupShape::CreateProc);
12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
129