1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/SkLayer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,230 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 +#include "SkLayer.h" 1.12 +#include "SkCanvas.h" 1.13 + 1.14 +//#define DEBUG_DRAW_LAYER_BOUNDS 1.15 +//#define DEBUG_TRACK_NEW_DELETE 1.16 + 1.17 +#ifdef DEBUG_TRACK_NEW_DELETE 1.18 + static int gLayerAllocCount; 1.19 +#endif 1.20 + 1.21 +/////////////////////////////////////////////////////////////////////////////// 1.22 + 1.23 +SkLayer::SkLayer() { 1.24 + fParent = NULL; 1.25 + m_opacity = SK_Scalar1; 1.26 + m_size.set(0, 0); 1.27 + m_position.set(0, 0); 1.28 + m_anchorPoint.set(SK_ScalarHalf, SK_ScalarHalf); 1.29 + 1.30 + fMatrix.reset(); 1.31 + fChildrenMatrix.reset(); 1.32 + fFlags = 0; 1.33 + 1.34 +#ifdef DEBUG_TRACK_NEW_DELETE 1.35 + gLayerAllocCount += 1; 1.36 + SkDebugf("SkLayer new: %d\n", gLayerAllocCount); 1.37 +#endif 1.38 +} 1.39 + 1.40 +SkLayer::SkLayer(const SkLayer& src) : INHERITED() { 1.41 + fParent = NULL; 1.42 + m_opacity = src.m_opacity; 1.43 + m_size = src.m_size; 1.44 + m_position = src.m_position; 1.45 + m_anchorPoint = src.m_anchorPoint; 1.46 + 1.47 + fMatrix = src.fMatrix; 1.48 + fChildrenMatrix = src.fChildrenMatrix; 1.49 + fFlags = src.fFlags; 1.50 + 1.51 +#ifdef DEBUG_TRACK_NEW_DELETE 1.52 + gLayerAllocCount += 1; 1.53 + SkDebugf("SkLayer copy: %d\n", gLayerAllocCount); 1.54 +#endif 1.55 +} 1.56 + 1.57 +SkLayer::~SkLayer() { 1.58 + this->removeChildren(); 1.59 + 1.60 +#ifdef DEBUG_TRACK_NEW_DELETE 1.61 + gLayerAllocCount -= 1; 1.62 + SkDebugf("SkLayer delete: %d\n", gLayerAllocCount); 1.63 +#endif 1.64 +} 1.65 + 1.66 +/////////////////////////////////////////////////////////////////////////////// 1.67 + 1.68 +bool SkLayer::isInheritFromRootTransform() const { 1.69 + return (fFlags & kInheritFromRootTransform_Flag) != 0; 1.70 +} 1.71 + 1.72 +void SkLayer::setInheritFromRootTransform(bool doInherit) { 1.73 + if (doInherit) { 1.74 + fFlags |= kInheritFromRootTransform_Flag; 1.75 + } else { 1.76 + fFlags &= ~kInheritFromRootTransform_Flag; 1.77 + } 1.78 +} 1.79 + 1.80 +void SkLayer::setMatrix(const SkMatrix& matrix) { 1.81 + fMatrix = matrix; 1.82 +} 1.83 + 1.84 +void SkLayer::setChildrenMatrix(const SkMatrix& matrix) { 1.85 + fChildrenMatrix = matrix; 1.86 +} 1.87 + 1.88 +/////////////////////////////////////////////////////////////////////////////// 1.89 + 1.90 +int SkLayer::countChildren() const { 1.91 + return m_children.count(); 1.92 +} 1.93 + 1.94 +SkLayer* SkLayer::getChild(int index) const { 1.95 + if ((unsigned)index < (unsigned)m_children.count()) { 1.96 + SkASSERT(m_children[index]->fParent == this); 1.97 + return m_children[index]; 1.98 + } 1.99 + return NULL; 1.100 +} 1.101 + 1.102 +SkLayer* SkLayer::addChild(SkLayer* child) { 1.103 + SkASSERT(this != child); 1.104 + child->ref(); 1.105 + child->detachFromParent(); 1.106 + SkASSERT(child->fParent == NULL); 1.107 + child->fParent = this; 1.108 + 1.109 + *m_children.append() = child; 1.110 + return child; 1.111 +} 1.112 + 1.113 +void SkLayer::detachFromParent() { 1.114 + if (fParent) { 1.115 + int index = fParent->m_children.find(this); 1.116 + SkASSERT(index >= 0); 1.117 + fParent->m_children.remove(index); 1.118 + fParent = NULL; 1.119 + this->unref(); // this call might delete us 1.120 + } 1.121 +} 1.122 + 1.123 +void SkLayer::removeChildren() { 1.124 + int count = m_children.count(); 1.125 + for (int i = 0; i < count; i++) { 1.126 + SkLayer* child = m_children[i]; 1.127 + SkASSERT(child->fParent == this); 1.128 + child->fParent = NULL; // in case it has more than one owner 1.129 + child->unref(); 1.130 + } 1.131 + m_children.reset(); 1.132 +} 1.133 + 1.134 +SkLayer* SkLayer::getRootLayer() const { 1.135 + const SkLayer* root = this; 1.136 + while (root->fParent != NULL) { 1.137 + root = root->fParent; 1.138 + } 1.139 + return const_cast<SkLayer*>(root); 1.140 +} 1.141 + 1.142 +/////////////////////////////////////////////////////////////////////////////// 1.143 + 1.144 +void SkLayer::getLocalTransform(SkMatrix* matrix) const { 1.145 + matrix->setTranslate(m_position.fX, m_position.fY); 1.146 + 1.147 + SkScalar tx = SkScalarMul(m_anchorPoint.fX, m_size.width()); 1.148 + SkScalar ty = SkScalarMul(m_anchorPoint.fY, m_size.height()); 1.149 + matrix->preTranslate(tx, ty); 1.150 + matrix->preConcat(this->getMatrix()); 1.151 + matrix->preTranslate(-tx, -ty); 1.152 +} 1.153 + 1.154 +void SkLayer::localToGlobal(SkMatrix* matrix) const { 1.155 + this->getLocalTransform(matrix); 1.156 + 1.157 + if (this->isInheritFromRootTransform()) { 1.158 + matrix->postConcat(this->getRootLayer()->getMatrix()); 1.159 + return; 1.160 + } 1.161 + 1.162 + const SkLayer* layer = this; 1.163 + while (layer->fParent != NULL) { 1.164 + layer = layer->fParent; 1.165 + 1.166 + SkMatrix tmp; 1.167 + layer->getLocalTransform(&tmp); 1.168 + tmp.preConcat(layer->getChildrenMatrix()); 1.169 + matrix->postConcat(tmp); 1.170 + } 1.171 +} 1.172 + 1.173 +/////////////////////////////////////////////////////////////////////////////// 1.174 + 1.175 +void SkLayer::onDraw(SkCanvas*, SkScalar opacity) { 1.176 +// SkDebugf("----- no onDraw for %p\n", this); 1.177 +} 1.178 + 1.179 +#include "SkString.h" 1.180 + 1.181 +void SkLayer::draw(SkCanvas* canvas, SkScalar opacity) { 1.182 +#if 0 1.183 + SkString str1, str2; 1.184 + // this->getMatrix().toDumpString(&str1); 1.185 + // this->getChildrenMatrix().toDumpString(&str2); 1.186 + SkDebugf("--- drawlayer %p opacity %g size [%g %g] pos [%g %g] matrix %s children %s\n", 1.187 + this, opacity * this->getOpacity(), m_size.width(), m_size.height(), 1.188 + m_position.fX, m_position.fY, str1.c_str(), str2.c_str()); 1.189 +#endif 1.190 + 1.191 + opacity = SkScalarMul(opacity, this->getOpacity()); 1.192 + if (opacity <= 0) { 1.193 +// SkDebugf("---- abort drawing %p opacity %g\n", this, opacity); 1.194 + return; 1.195 + } 1.196 + 1.197 + SkAutoCanvasRestore acr(canvas, true); 1.198 + 1.199 + // apply our local transform 1.200 + { 1.201 + SkMatrix tmp; 1.202 + this->getLocalTransform(&tmp); 1.203 + if (this->isInheritFromRootTransform()) { 1.204 + // should we also apply the root's childrenMatrix? 1.205 + canvas->setMatrix(getRootLayer()->getMatrix()); 1.206 + } 1.207 + canvas->concat(tmp); 1.208 + } 1.209 + 1.210 + this->onDraw(canvas, opacity); 1.211 + 1.212 +#ifdef DEBUG_DRAW_LAYER_BOUNDS 1.213 + { 1.214 + SkRect r = SkRect::MakeSize(this->getSize()); 1.215 + SkPaint p; 1.216 + p.setAntiAlias(true); 1.217 + p.setStyle(SkPaint::kStroke_Style); 1.218 + p.setStrokeWidth(SkIntToScalar(2)); 1.219 + p.setColor(0xFFFF44DD); 1.220 + canvas->drawRect(r, p); 1.221 + canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, p); 1.222 + canvas->drawLine(r.fLeft, r.fBottom, r.fRight, r.fTop, p); 1.223 + } 1.224 +#endif 1.225 + 1.226 + int count = this->countChildren(); 1.227 + if (count > 0) { 1.228 + canvas->concat(this->getChildrenMatrix()); 1.229 + for (int i = 0; i < count; i++) { 1.230 + this->getChild(i)->draw(canvas, opacity); 1.231 + } 1.232 + } 1.233 +}