SkLayer.cpp revision 5770f2c5ca580514442e30a9f4965e8bb15342f3
1#include "SkLayer.h" 2#include "SkCanvas.h" 3 4//#define DEBUG_DRAW_LAYER_BOUNDS 5//#define DEBUG_TRACK_NEW_DELETE 6 7#ifdef DEBUG_TRACK_NEW_DELETE 8 static int gLayerAllocCount; 9#endif 10 11/////////////////////////////////////////////////////////////////////////////// 12 13SkLayer::SkLayer() { 14 fParent = NULL; 15 m_opacity = SK_Scalar1; 16 m_size.set(0, 0); 17 m_position.set(0, 0); 18 m_anchorPoint.set(SK_ScalarHalf, SK_ScalarHalf); 19 20 fMatrix.reset(); 21 fChildrenMatrix.reset(); 22 23#ifdef DEBUG_TRACK_NEW_DELETE 24 gLayerAllocCount += 1; 25 SkDebugf("SkLayer new: %d\n", gLayerAllocCount); 26#endif 27} 28 29SkLayer::SkLayer(const SkLayer& src) { 30 fParent = NULL; 31 m_opacity = src.m_opacity; 32 m_size = src.m_size; 33 m_position = src.m_position; 34 m_anchorPoint = src.m_anchorPoint; 35 36 fMatrix = src.fMatrix; 37 fChildrenMatrix = src.fChildrenMatrix; 38 39#ifdef DEBUG_TRACK_NEW_DELETE 40 gLayerAllocCount += 1; 41 SkDebugf("SkLayer copy: %d\n", gLayerAllocCount); 42#endif 43} 44 45SkLayer::~SkLayer() { 46 this->removeChildren(); 47 48#ifdef DEBUG_TRACK_NEW_DELETE 49 gLayerAllocCount -= 1; 50 SkDebugf("SkLayer delete: %d\n", gLayerAllocCount); 51#endif 52} 53 54/////////////////////////////////////////////////////////////////////////////// 55 56void SkLayer::setMatrix(const SkMatrix& matrix) { 57 fMatrix = matrix; 58} 59 60void SkLayer::setChildrenMatrix(const SkMatrix& matrix) { 61 fChildrenMatrix = matrix; 62} 63 64/////////////////////////////////////////////////////////////////////////////// 65 66int SkLayer::countChildren() const { 67 return m_children.count(); 68} 69 70SkLayer* SkLayer::getChild(int index) const { 71 if ((unsigned)index < (unsigned)m_children.count()) { 72 return m_children[index]; 73 } 74 return NULL; 75} 76 77SkLayer* SkLayer::addChild(SkLayer* child) { 78 child->ref(); 79 if (child->fParent) { 80 child->fParent->removeChild(child); 81 } 82 SkASSERT(child->fParent == NULL); 83 child->fParent = this; 84 85 *m_children.append() = child; 86 return child; 87} 88 89bool SkLayer::removeChild(SkLayer* child) { 90 int index = m_children.find(child); 91 if (index >= 0) { 92 SkASSERT(child->fParent == this); 93 child->fParent = NULL; 94 child->unref(); 95 m_children.remove(index); 96 return true; 97 } 98 return false; 99} 100 101void SkLayer::removeChildren() { 102 m_children.unrefAll(); 103 m_children.reset(); 104} 105 106SkLayer* SkLayer::getRootLayer() const { 107 const SkLayer* root = this; 108 while (root->fParent != NULL) { 109 root = root->fParent; 110 } 111 return const_cast<SkLayer*>(root); 112} 113 114/////////////////////////////////////////////////////////////////////////////// 115 116void SkLayer::getLocalTransform(SkMatrix* matrix) const { 117 matrix->setTranslate(m_position.fX, m_position.fY); 118 119 SkScalar tx = SkScalarMul(m_anchorPoint.fX, m_size.width()); 120 SkScalar ty = SkScalarMul(m_anchorPoint.fY, m_size.height()); 121 matrix->preTranslate(tx, ty); 122 matrix->preConcat(this->getMatrix()); 123 matrix->preTranslate(-tx, -ty); 124} 125 126void SkLayer::localToGlobal(SkMatrix* matrix) const { 127 this->getLocalTransform(matrix); 128 129 const SkLayer* layer = this; 130 while (layer->fParent != NULL) { 131 layer = layer->fParent; 132 133 SkMatrix tmp; 134 layer->getLocalTransform(&tmp); 135 tmp.preConcat(layer->getChildrenMatrix()); 136 matrix->postConcat(tmp); 137 } 138} 139 140/////////////////////////////////////////////////////////////////////////////// 141 142void SkLayer::onDraw(SkCanvas*, SkScalar opacity) { 143// SkDebugf("----- no onDraw for %p\n", this); 144} 145 146#include "SkString.h" 147 148void SkLayer::draw(SkCanvas* canvas, SkScalar opacity) { 149#if 0 150 SkString str1, str2; 151 // this->getMatrix().toDumpString(&str1); 152 // this->getChildrenMatrix().toDumpString(&str2); 153 SkDebugf("--- drawlayer %p opacity %g size [%g %g] pos [%g %g] matrix %s children %s\n", 154 this, opacity * this->getOpacity(), m_size.width(), m_size.height(), 155 m_position.fX, m_position.fY, str1.c_str(), str2.c_str()); 156#endif 157 158 opacity = SkScalarMul(opacity, this->getOpacity()); 159 if (opacity <= 0) { 160// SkDebugf("---- abort drawing %p opacity %g\n", this, opacity); 161 return; 162 } 163 164 SkAutoCanvasRestore acr(canvas, true); 165 166 // apply our local transform 167 { 168 canvas->translate(m_position.fX, m_position.fY); 169 170 SkScalar tx = SkScalarMul(m_anchorPoint.fX, m_size.width()); 171 SkScalar ty = SkScalarMul(m_anchorPoint.fY, m_size.height()); 172 canvas->translate(tx, ty); 173 canvas->concat(this->getMatrix()); 174 canvas->translate(-tx, -ty); 175 } 176 177 this->onDraw(canvas, opacity); 178 179#ifdef DEBUG_DRAW_LAYER_BOUNDS 180 { 181 SkRect r = SkRect::MakeSize(this->getSize()); 182 SkPaint p; 183 p.setAntiAlias(true); 184 p.setStyle(SkPaint::kStroke_Style); 185 p.setStrokeWidth(SkIntToScalar(2)); 186 p.setColor(0xFFFF44DD); 187 canvas->drawRect(r, p); 188 canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, p); 189 canvas->drawLine(r.fLeft, r.fBottom, r.fRight, r.fTop, p); 190 } 191#endif 192 193 int count = this->countChildren(); 194 if (count > 0) { 195 canvas->concat(this->getChildrenMatrix()); 196 for (int i = 0; i < count; i++) { 197 this->getChild(i)->draw(canvas, opacity); 198 } 199 } 200} 201 202