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