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