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#ifndef SkGroupShape_DEFINED 940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#define SkGroupShape_DEFINED 1040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkMatrix.h" 1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkShape.h" 1340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkTDArray.h" 1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkThread.h" 1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergertemplate <typename T> class SkTRefCnt : public T { 1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 1840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTRefCnt() : fRefCnt(1) {} 1940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger ~SkTRefCnt() { SkASSERT(1 == fRefCnt); } 2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int32_t getRefCnt() const { return fRefCnt; } 2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Increment the reference count. Must be balanced by a call to unref(). 2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 2540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void ref() const { 2640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(fRefCnt > 0); 2740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger sk_atomic_inc(&fRefCnt); 2840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 2940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Decrement the reference count. If the reference count is 1 before the 3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger decrement, then call delete on the object. Note that if this is the 3240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case, then the object needs to have been allocated via new, and not on 3340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger the stack. 3440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 3540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void unref() const { 3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(fRefCnt > 0); 3740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (sk_atomic_dec(&fRefCnt) == 1) { 3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fRefCnt = 1; // so our destructor won't complain 3940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDELETE(this); 4040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 4140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 4240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger static void SafeRef(const SkTRefCnt* obj) { 4440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (obj) { 4540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger obj->ref(); 4640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 4840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger static void SafeUnref(const SkTRefCnt* obj) { 5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (obj) { 5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger obj->unref(); 5240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 5440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 5640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger mutable int32_t fRefCnt; 5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 5840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass SkMatrixRef : public SkTRefCnt<SkMatrix> { 6040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrixRef() { this->reset(); } 6240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger explicit SkMatrixRef(const SkMatrix& matrix) { 6340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix& m = *this; 6440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger m = matrix; 6540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix& operator=(const SkMatrix& matrix) { 6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix& m = *this; 6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger m = matrix; 7040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return m; 7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass SkGroupShape : public SkShape { 7540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 7640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkGroupShape(); 7740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual ~SkGroupShape(); 7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Return the number of child shapes in this group 8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int countShapes() const; 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Return the shape at the specified index. Note this does not affect the 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger owner count of the index'd shape. If index is out of range, returns NULL 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkShape* getShape(int index, SkMatrixRef** = NULL) const; 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Helper function to return the matrixref of the specified shape. 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrixRef* getShapeMatrixRef(int index) const { 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrixRef* mr = NULL; 9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger (void)this->getShape(index, &mr); 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return mr; 9440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 9540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Ref the specified shape, and insert it into the child list at the 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger specified index. If index == countShapes(), then the shape will be 9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger appended to the child list, otherwise if index is out of range, the 9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger shape is not added. Either way, the shape parameter is returned. 10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Child shapes are drawn in order, after the parent, so the shape at index 10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 0 will be drawn first, and the shape at index countShapes() - 1 will be 10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger drawn last. 10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void addShape(int index, SkShape*, SkMatrixRef* = NULL); 10640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void addShape(int index, SkShape* shape, const SkMatrix& matrix) { 10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrixRef* mr = SkNEW_ARGS(SkMatrixRef, (matrix)); 10940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->addShape(index, shape, mr); 11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger mr->unref(); 11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Helper method to append a shape, passing countShapes() for the index 11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkShape* appendShape(SkShape* shape, SkMatrixRef* mr = NULL) { 11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->addShape(this->countShapes(), shape, mr); 11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return shape; 11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkShape* appendShape(SkShape* shape, const SkMatrix& matrix) { 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->addShape(this->countShapes(), shape, matrix); 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return shape; 12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Unref the specified index, and remove it from the child list. If index 12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger is out of range, does nothing. 12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void removeShape(int index); 12940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger /** Unrefs and removes all of the child shapes 13140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 13240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void removeAllShapes(); 13340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // overrides 13540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual Factory getFactory(); 13640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void flatten(SkFlattenableWriteBuffer&); 13740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // public for Registrar 13940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer&); 14040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DECLARE_FLATTENABLE_REGISTRAR() 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprotected: 14440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // overrides 14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void onDraw(SkCanvas*); 14640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkGroupShape(SkFlattenableReadBuffer&); 14840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 15040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger struct Rec { 15140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkShape* fShape; 15240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrixRef* fMatrixRef; 15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger }; 15440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTDArray<Rec> fList; 15540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger typedef SkShape INHERITED; 15740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 15840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 15940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 160