1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef Layer_DEFINED
18#define Layer_DEFINED
19
20#include "DrawExtra.h"
21#include "TestExport.h"
22#include "SkRefCnt.h"
23#include "SkTDArray.h"
24#include "SkColor.h"
25#include "SkMatrix.h"
26#include "SkPoint.h"
27#include "SkRect.h"
28#include "SkRegion.h"
29#include "SkSize.h"
30
31namespace WebCore {
32class IntRect;
33class GLWebViewState;
34};
35
36class SkCanvas;
37
38class TEST_EXPORT Layer : public SkRefCnt {
39
40public:
41    Layer();
42    Layer(const Layer&);
43    virtual ~Layer();
44
45    // Whether the layer should apply its tranform directly onto the root
46    // layer, rather than using the transforms of all ancestor layers. This is
47    // used for fixed position layers.
48    bool shouldInheritFromRootTransform() const { return m_shouldInheritFromRootTransform; }
49    SkScalar getOpacity() const { return m_opacity; }
50    const SkSize& getSize() const { return m_size; }
51    const SkPoint& getPosition() const { return m_position; }
52    const IntPoint& getScrollOffset() const { return m_scrollOffset; }
53    const SkPoint& getAnchorPoint() const { return m_anchorPoint; }
54    const SkMatrix& getMatrix() const { return m_matrix; }
55    const SkMatrix& getChildrenMatrix() const { return m_childrenMatrix; }
56
57    SkScalar getWidth() const { return m_size.width(); }
58    SkScalar getHeight() const { return m_size.height(); }
59
60    void setShouldInheritFromRootTransform(bool inherit) { m_shouldInheritFromRootTransform = inherit; }
61    void setOpacity(SkScalar opacity) { m_opacity = opacity; }
62    void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
63    void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
64    void setScrollOffset(IntPoint scrollOffset) { m_scrollOffset = scrollOffset; }
65    void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
66    void setMatrix(const SkMatrix& matrix) { m_matrix = matrix; }
67    void setChildrenMatrix(const SkMatrix& matrix) { m_childrenMatrix = matrix; }
68
69// rendering asset management
70    void markAsDirty(const SkRegion& invalRegion) {
71        m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op);
72    }
73
74    bool isDirty() {
75        return !m_dirtyRegion.isEmpty();
76    }
77
78// drawing
79
80    WebCore::GLWebViewState* state() { return m_state; }
81    void setState(WebCore::GLWebViewState* state);
82
83// children
84
85    /** Return the number of layers in our child list.
86     */
87    int countChildren() const;
88
89    /** Return the child at the specified index (starting at 0). This does not
90        affect the reference count of the child.
91     */
92    Layer* getChild(int index) const;
93
94    /** Add this layer to our child list at the end (top-most), and ref() it.
95        If it was already in another hierarchy, remove it from that list.
96        Return the new child.
97     */
98    Layer* addChild(Layer* child);
99
100    /** Remove this layer from its parent's list (or do nothing if it has no
101        parent.) If it had a parent, then unref() is called.
102     */
103    void detachFromParent();
104
105    /** Remove, and unref(), all of the layers in our child list.
106     */
107    void removeChildren();
108
109    /** Return our parent layer, or NULL if we have none.
110     */
111    Layer* getParent() const { return fParent; }
112
113    /** Return the root layer in this hiearchy. If this layer is the root
114        (i.e. has no parent), then this returns itself.
115     */
116    Layer* getRootLayer() const;
117
118    // coordinate system transformations
119
120    /** Return, in matrix, the matix transfomations that are applied locally
121        when this layer draws (i.e. its position and matrix/anchorPoint).
122        This does not include the childrenMatrix, since that is only applied
123        after this layer draws (but before its children draw).
124     */
125    virtual void getLocalTransform(SkMatrix* matrix) const;
126
127    /** Return, in matrix, the concatenation of transforms that are applied
128        from this layer's root parent to the layer itself.
129        This is the matrix that is applied to the layer during drawing.
130     */
131    void localToGlobal(SkMatrix* matrix) const { localToAncestor(0, matrix); }
132
133    /** Return, as a matrix, the transform that converts from this layer's local
134        space to the space of the given ancestor layer. Use NULL for ancestor to
135        represent the root layer. Note that this method must not be called on a
136        fixed position layer with ancestor != NULL.
137
138        For non-fixed position layers, the following holds (in pseudo-code for
139        brevity) ...
140        SkMatrix localToAncestor = layer->localToAncestor(ancestor);
141        SkMatrix ancestorToGlobal = ancestor->localToAncestor(NULL);
142        SkMatrix localToGlobal = layer->localToGlobal();
143        ASSERT(localToAncestor * ancestorToGlobal == localToGlobal);
144     */
145    void localToAncestor(const Layer* ancestor, SkMatrix* matrix) const;
146
147    // paint method
148
149    virtual bool drawCanvas(SkCanvas*) { return false; }
150    void draw(SkCanvas*, android::DrawExtra* extra, SkScalar opacity = SK_Scalar1);
151
152    void setHasOverflowChildren(bool value) { m_hasOverflowChildren = value; }
153
154    virtual bool contentIsScrollable() const { return false; }
155
156    typedef enum { MergedLayers, UnmergedLayers, FlattenedLayers } PaintStyle;
157protected:
158    virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style) {}
159
160    bool m_hasOverflowChildren;
161
162    // invalidation region
163    SkRegion m_dirtyRegion;
164private:
165    bool isAncestor(const Layer*) const;
166
167    Layer* fParent;
168    SkScalar m_opacity;
169    SkSize m_size;
170    // The position of the origin of the layer, relative to the parent layer.
171    SkPoint m_position;
172    // The scroll offset of the layer
173    IntPoint m_scrollOffset;
174    // The point in the layer used as the origin for local transformations,
175    // expressed as a fraction of the layer size.
176    SkPoint m_anchorPoint;
177    SkMatrix m_matrix;
178    SkMatrix m_childrenMatrix;
179    bool m_shouldInheritFromRootTransform;
180
181    SkTDArray<Layer*> m_children;
182
183    WebCore::GLWebViewState* m_state;
184
185    typedef SkRefCnt INHERITED;
186};
187
188#endif
189