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