• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkLayer()13 SkLayer::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 
SkLayer(const SkLayer & src)30 SkLayer::SkLayer(const SkLayer& src) : INHERITED() {
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 
~SkLayer()47 SkLayer::~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 
isInheritFromRootTransform() const58 bool SkLayer::isInheritFromRootTransform() const {
59     return (fFlags & kInheritFromRootTransform_Flag) != 0;
60 }
61 
setInheritFromRootTransform(bool doInherit)62 void SkLayer::setInheritFromRootTransform(bool doInherit) {
63     if (doInherit) {
64         fFlags |= kInheritFromRootTransform_Flag;
65     } else {
66         fFlags &= ~kInheritFromRootTransform_Flag;
67     }
68 }
69 
setMatrix(const SkMatrix & matrix)70 void SkLayer::setMatrix(const SkMatrix& matrix) {
71     fMatrix = matrix;
72 }
73 
setChildrenMatrix(const SkMatrix & matrix)74 void SkLayer::setChildrenMatrix(const SkMatrix& matrix) {
75     fChildrenMatrix = matrix;
76 }
77 
78 ///////////////////////////////////////////////////////////////////////////////
79 
countChildren() const80 int SkLayer::countChildren() const {
81     return m_children.count();
82 }
83 
getChild(int index) const84 SkLayer* 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 
addChild(SkLayer * child)92 SkLayer* 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 
detachFromParent()103 void 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 
removeChildren()113 void 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 
getRootLayer() const124 SkLayer* 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 
getLocalTransform(SkMatrix * matrix) const134 void 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 
localToGlobal(SkMatrix * matrix) const144 void 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 
onDraw(SkCanvas *,SkScalar opacity)165 void SkLayer::onDraw(SkCanvas*, SkScalar opacity) {
166 //    SkDebugf("----- no onDraw for %p\n", this);
167 }
168 
169 #include "SkString.h"
170 
draw(SkCanvas * canvas,SkScalar opacity)171 void 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