Home | History | Annotate | Download | only in utils
      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 = nullptr;
     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 = nullptr;
     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 nullptr;
     97 }
     98 
     99 SkLayer* SkLayer::addChild(SkLayer* child) {
    100     SkASSERT(this != child);
    101     child->ref();
    102     child->detachFromParent();
    103     SkASSERT(child->fParent == nullptr);
    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 = nullptr;
    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 = nullptr;  // 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 != nullptr) {
    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 != nullptr) {
    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 }
    231