1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *  * Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef FixedPositioning_h
27#define FixedPositioning_h
28
29#if USE(ACCELERATED_COMPOSITING)
30
31#include "LayerAndroid.h"
32#include "Length.h"
33
34namespace WebCore {
35
36class IFrameLayerAndroid;
37
38struct SkLength {
39    enum SkLengthType { Undefined, Auto, Relative,
40        Percent, Fixed, Static, Intrinsic, MinIntrinsic };
41    SkLengthType type;
42    SkScalar value;
43    SkLength()
44    {
45        type = Undefined;
46        value = 0;
47    }
48    bool defined() const
49    {
50        if (type == Undefined)
51            return false;
52        return true;
53    }
54    void setFixedValue(float v)
55    {
56        type = Fixed;
57        value = v;
58    }
59    void setAuto()
60    {
61        type = Auto;
62    }
63    float calcFloatValue(float max) const
64    {
65        switch (type) {
66        case Percent:
67            return (max * value) / 100.0f;
68        case Fixed:
69            return value;
70        default:
71            return value;
72        }
73    }
74
75    static SkLength convertLength(Length len)
76    {
77        SkLength length;
78        length.type = SkLength::Undefined;
79        length.value = 0;
80        if (len.type() == WebCore::Percent) {
81            length.type = SkLength::Percent;
82            length.value = len.percent();
83        }
84        if (len.type() == WebCore::Fixed) {
85            length.type = SkLength::Fixed;
86            length.value = len.value();
87        }
88        return length;
89    }
90
91};
92
93class FixedPositioning {
94
95public:
96    FixedPositioning(LayerAndroid* layer = 0) : m_layer(layer) {}
97    FixedPositioning(LayerAndroid* layer, const FixedPositioning& position);
98    virtual ~FixedPositioning() {};
99
100    virtual bool isBackgroundImagePositioning() { return true; }
101    virtual FixedPositioning* copy(LayerAndroid* layer) const {
102        return new FixedPositioning(layer, *this);
103    }
104
105    void setFixedPosition(SkLength left, // CSS left property
106                          SkLength top, // CSS top property
107                          SkLength right, // CSS right property
108                          SkLength bottom, // CSS bottom property
109                          SkLength marginLeft, // CSS margin-left property
110                          SkLength marginTop, // CSS margin-top property
111                          SkLength marginRight, // CSS margin-right property
112                          SkLength marginBottom, // CSS margin-bottom property
113                          const IntPoint& renderLayerPos, // For undefined fixed position
114                          SkRect viewRect) { // view rect, can be smaller than the layer's
115        m_fixedLeft = left;
116        m_fixedTop = top;
117        m_fixedRight = right;
118        m_fixedBottom = bottom;
119        m_fixedMarginLeft = marginLeft;
120        m_fixedMarginTop = marginTop;
121        m_fixedMarginRight = marginRight;
122        m_fixedMarginBottom = marginBottom;
123        m_fixedRect = viewRect;
124        m_renderLayerPos = renderLayerPos;
125    }
126
127    SkRect getViewport(SkRect viewport, IFrameLayerAndroid* parentIframeLayer);
128    virtual IFrameLayerAndroid* updatePosition(SkRect viewPort,
129                                               IFrameLayerAndroid* parentIframeLayer);
130
131    void contentDraw(SkCanvas* canvas, Layer::PaintStyle style);
132
133    void dumpLayer(LayerDumper*) const;
134
135    // ViewStateSerializer friends
136    friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
137    friend LayerAndroid* android::deserializeLayer(int version, SkMemoryStream* stream);
138
139protected:
140    LayerAndroid* m_layer;
141
142    SkLength m_fixedLeft;
143    SkLength m_fixedTop;
144    SkLength m_fixedRight;
145    SkLength m_fixedBottom;
146    SkLength m_fixedMarginLeft;
147    SkLength m_fixedMarginTop;
148    SkLength m_fixedMarginRight;
149    SkLength m_fixedMarginBottom;
150    SkRect m_fixedRect;
151
152    // When fixed element is undefined or auto, the render layer's position
153    // is needed for offset computation
154    IntPoint m_renderLayerPos;
155};
156
157class BackgroundImagePositioning : public FixedPositioning {
158public:
159    BackgroundImagePositioning(LayerAndroid* layer)
160        : FixedPositioning(layer)
161        , m_repeatX(false)
162        , m_repeatY(false)
163        , m_nbRepeatX(0)
164        , m_nbRepeatY(0)
165        , m_offsetX(0)
166        , m_offsetY(0)
167    {}
168    BackgroundImagePositioning(LayerAndroid* layer, const BackgroundImagePositioning& position);
169    virtual bool isBackgroundImagePositioning() { return true; }
170    virtual FixedPositioning* copy(LayerAndroid* layer) const {
171        return new BackgroundImagePositioning(layer, *this);
172    }
173    void setPosition(SkLength left, SkLength top) {
174        m_fixedLeft = left;
175        m_fixedTop = top;
176    }
177    virtual IFrameLayerAndroid* updatePosition(SkRect viewPort,
178                                               IFrameLayerAndroid* parentIframeLayer);
179
180    // Measures the background image repetition
181    void setRepeatX(bool repeat) { m_repeatX = repeat; }
182    void setRepeatY(bool repeat) { m_repeatY = repeat; }
183    bool repeatX() { return m_repeatX; }
184    bool repeatY() { return m_repeatY; }
185    int nbRepeatX() { return m_nbRepeatX; }
186    int offsetX() { return m_offsetX; }
187    int nbRepeatY() { return m_nbRepeatY; }
188    int offsetY() { return m_offsetY; }
189
190private:
191    bool m_repeatX;
192    bool m_repeatY;
193    int  m_nbRepeatX;
194    int  m_nbRepeatY;
195    int  m_offsetX;
196    int  m_offsetY;
197};
198
199}
200
201#endif // USE(ACCELERATED_COMPOSITING)
202
203#endif // FixedPositioning_h
204