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