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 fFlags = 0; 23 24#ifdef DEBUG_TRACK_NEW_DELETE 25 gLayerAllocCount += 1; 26 SkDebugf("SkLayer new: %d\n", gLayerAllocCount); 27#endif 28} 29 30SkLayer::SkLayer(const SkLayer& src) { 31 fParent = NULL; 32 m_opacity = src.m_opacity; 33 m_size = src.m_size; 34 m_position = src.m_position; 35 m_anchorPoint = src.m_anchorPoint; 36 37 fMatrix = src.fMatrix; 38 fChildrenMatrix = src.fChildrenMatrix; 39 fFlags = src.fFlags; 40 41#ifdef DEBUG_TRACK_NEW_DELETE 42 gLayerAllocCount += 1; 43 SkDebugf("SkLayer copy: %d\n", gLayerAllocCount); 44#endif 45} 46 47SkLayer::~SkLayer() { 48 this->removeChildren(); 49 50#ifdef DEBUG_TRACK_NEW_DELETE 51 gLayerAllocCount -= 1; 52 SkDebugf("SkLayer delete: %d\n", gLayerAllocCount); 53#endif 54} 55 56/////////////////////////////////////////////////////////////////////////////// 57 58bool SkLayer::isInheritFromRootTransform() const { 59 return (fFlags & kInheritFromRootTransform_Flag) != 0; 60} 61 62void SkLayer::setInheritFromRootTransform(bool doInherit) { 63 if (doInherit) { 64 fFlags |= kInheritFromRootTransform_Flag; 65 } else { 66 fFlags &= ~kInheritFromRootTransform_Flag; 67 } 68} 69 70void SkLayer::setMatrix(const SkMatrix& matrix) { 71 fMatrix = matrix; 72} 73 74void SkLayer::setChildrenMatrix(const SkMatrix& matrix) { 75 fChildrenMatrix = matrix; 76} 77 78/////////////////////////////////////////////////////////////////////////////// 79 80int SkLayer::countChildren() const { 81 return m_children.count(); 82} 83 84SkLayer* SkLayer::getChild(int index) const { 85 if ((unsigned)index < (unsigned)m_children.count()) { 86 SkASSERT(m_children[index]->fParent == this); 87 return m_children[index]; 88 } 89 return NULL; 90} 91 92SkLayer* SkLayer::addChild(SkLayer* child) { 93 SkASSERT(this != child); 94 child->ref(); 95 child->detachFromParent(); 96 SkASSERT(child->fParent == NULL); 97 child->fParent = this; 98 99 *m_children.append() = child; 100 return child; 101} 102 103void SkLayer::detachFromParent() { 104 if (fParent) { 105 int index = fParent->m_children.find(this); 106 SkASSERT(index >= 0); 107 fParent->m_children.remove(index); 108 fParent = NULL; 109 this->unref(); // this call might delete us 110 } 111} 112 113void SkLayer::removeChildren() { 114 int count = m_children.count(); 115 for (int i = 0; i < count; i++) { 116 SkLayer* child = m_children[i]; 117 SkASSERT(child->fParent == this); 118 child->fParent = NULL; // in case it has more than one owner 119 child->unref(); 120 } 121 m_children.reset(); 122} 123 124SkLayer* SkLayer::getRootLayer() const { 125 const SkLayer* root = this; 126 while (root->fParent != NULL) { 127 root = root->fParent; 128 } 129 return const_cast<SkLayer*>(root); 130} 131 132/////////////////////////////////////////////////////////////////////////////// 133 134void SkLayer::getLocalTransform(SkMatrix* matrix) const { 135 matrix->setTranslate(m_position.fX, m_position.fY); 136 137 SkScalar tx = SkScalarMul(m_anchorPoint.fX, m_size.width()); 138 SkScalar ty = SkScalarMul(m_anchorPoint.fY, m_size.height()); 139 matrix->preTranslate(tx, ty); 140 matrix->preConcat(this->getMatrix()); 141 matrix->preTranslate(-tx, -ty); 142} 143 144void SkLayer::localToGlobal(SkMatrix* matrix) const { 145 this->getLocalTransform(matrix); 146 147 if (this->isInheritFromRootTransform()) { 148 matrix->postConcat(this->getRootLayer()->getMatrix()); 149 return; 150 } 151 152 const SkLayer* layer = this; 153 while (layer->fParent != NULL) { 154 layer = layer->fParent; 155 156 SkMatrix tmp; 157 layer->getLocalTransform(&tmp); 158 tmp.preConcat(layer->getChildrenMatrix()); 159 matrix->postConcat(tmp); 160 } 161} 162 163/////////////////////////////////////////////////////////////////////////////// 164 165void SkLayer::onDraw(SkCanvas*, SkScalar opacity) { 166// SkDebugf("----- no onDraw for %p\n", this); 167} 168 169#include "SkString.h" 170 171void SkLayer::draw(SkCanvas* canvas, SkScalar opacity) { 172#if 0 173 SkString str1, str2; 174 // this->getMatrix().toDumpString(&str1); 175 // this->getChildrenMatrix().toDumpString(&str2); 176 SkDebugf("--- drawlayer %p opacity %g size [%g %g] pos [%g %g] matrix %s children %s\n", 177 this, opacity * this->getOpacity(), m_size.width(), m_size.height(), 178 m_position.fX, m_position.fY, str1.c_str(), str2.c_str()); 179#endif 180 181 opacity = SkScalarMul(opacity, this->getOpacity()); 182 if (opacity <= 0) { 183// SkDebugf("---- abort drawing %p opacity %g\n", this, opacity); 184 return; 185 } 186 187 SkAutoCanvasRestore acr(canvas, true); 188 189 // apply our local transform 190 { 191 SkMatrix tmp; 192 this->getLocalTransform(&tmp); 193 if (this->isInheritFromRootTransform()) { 194 // should we also apply the root's childrenMatrix? 195 canvas->setMatrix(getRootLayer()->getMatrix()); 196 } 197 canvas->concat(tmp); 198 } 199 200 this->onDraw(canvas, opacity); 201 202#ifdef DEBUG_DRAW_LAYER_BOUNDS 203 { 204 SkRect r = SkRect::MakeSize(this->getSize()); 205 SkPaint p; 206 p.setAntiAlias(true); 207 p.setStyle(SkPaint::kStroke_Style); 208 p.setStrokeWidth(SkIntToScalar(2)); 209 p.setColor(0xFFFF44DD); 210 canvas->drawRect(r, p); 211 canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, p); 212 canvas->drawLine(r.fLeft, r.fBottom, r.fRight, r.fTop, p); 213 } 214#endif 215 216 int count = this->countChildren(); 217 if (count > 0) { 218 canvas->concat(this->getChildrenMatrix()); 219 for (int i = 0; i < count; i++) { 220 this->getChild(i)->draw(canvas, opacity); 221 } 222 } 223} 224 225