FixedPositioning.cpp revision 576098317db607e1d3b32a0e53d2551ea0e7ef21
1#define LOG_TAG "FixedPositioning"
2#define LOG_NDEBUG 1
3
4#include "config.h"
5#include "FixedPositioning.h"
6
7#include "AndroidLog.h"
8#include "DumpLayer.h"
9#include "IFrameLayerAndroid.h"
10#include "TilesManager.h"
11#include "SkCanvas.h"
12
13#if USE(ACCELERATED_COMPOSITING)
14
15namespace WebCore {
16
17// Called when copying the layer tree to the UI
18FixedPositioning::FixedPositioning(LayerAndroid* layer, const FixedPositioning& position)
19        : m_layer(layer)
20        , m_fixedLeft(position.m_fixedLeft)
21        , m_fixedTop(position.m_fixedTop)
22        , m_fixedRight(position.m_fixedRight)
23        , m_fixedBottom(position.m_fixedBottom)
24        , m_fixedMarginLeft(position.m_fixedMarginLeft)
25        , m_fixedMarginTop(position.m_fixedMarginTop)
26        , m_fixedMarginRight(position.m_fixedMarginRight)
27        , m_fixedMarginBottom(position.m_fixedMarginBottom)
28        , m_fixedRect(position.m_fixedRect)
29        , m_renderLayerPos(position.m_renderLayerPos)
30{
31}
32
33SkRect FixedPositioning::getViewport(SkRect aViewport, IFrameLayerAndroid* parentIframeLayer)
34{
35    // So if this is a fixed layer inside a iframe, use the iframe offset
36    // and the iframe's size as the viewport and pass to the children
37    if (parentIframeLayer)
38        return SkRect::MakeXYWH(parentIframeLayer->iframeOffset().x(),
39                                parentIframeLayer->iframeOffset().y(),
40                                parentIframeLayer->getSize().width(),
41                                parentIframeLayer->getSize().height());
42    return aViewport;
43}
44
45// Executed on the UI
46IFrameLayerAndroid* FixedPositioning::updatePosition(SkRect aViewport,
47                                                     IFrameLayerAndroid* parentIframeLayer)
48{
49    SkRect viewport = getViewport(aViewport, parentIframeLayer);
50
51    float w = viewport.width();
52    float h = viewport.height();
53    float dx = viewport.fLeft;
54    float dy = viewport.fTop;
55    float x = dx;
56    float y = dy;
57
58    // It turns out that when it is 'auto', we should use the webkit value
59    // from the original render layer's X,Y, that will take care of alignment
60    // with the parent's layer and fix Margin etc.
61    if (!(m_fixedLeft.defined() || m_fixedRight.defined()))
62        x += m_renderLayerPos.x();
63    else if (m_fixedLeft.defined() || !m_fixedRight.defined())
64        x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft;
65    else
66        x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight;
67
68    if (!(m_fixedTop.defined() || m_fixedBottom.defined()))
69        y += m_renderLayerPos.y();
70    else if (m_fixedTop.defined() || !m_fixedBottom.defined())
71        y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop;
72    else
73        y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom;
74
75    m_layer->setPosition(x, y);
76
77    return parentIframeLayer;
78}
79
80void FixedPositioning::contentDraw(SkCanvas* canvas, Layer::PaintStyle style)
81{
82    if (TilesManager::instance()->getShowVisualIndicator()) {
83        SkPaint paint;
84        paint.setARGB(80, 255, 0, 0);
85        canvas->drawRect(m_fixedRect, paint);
86    }
87}
88
89void writeLength(FILE* file, int indentLevel, const char* str, SkLength length)
90{
91    if (!length.defined())
92        return;
93    writeIndent(file, indentLevel);
94    fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value);
95}
96
97void FixedPositioning::dumpLayer(FILE* file, int indentLevel) const
98{
99    writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft);
100    writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop);
101    writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight);
102    writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom);
103    writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft);
104    writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop);
105    writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight);
106    writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom);
107    writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect);
108}
109
110BackgroundImagePositioning::BackgroundImagePositioning(LayerAndroid* layer, const BackgroundImagePositioning& position)
111        : FixedPositioning(layer, position)
112        , m_repeatX(position.m_repeatX)
113        , m_repeatY(position.m_repeatY)
114        , m_nbRepeatX(position.m_nbRepeatX)
115        , m_nbRepeatY(position.m_nbRepeatY)
116        , m_offsetX(position.m_offsetX)
117        , m_offsetY(position.m_offsetY)
118{
119}
120
121// Executed on the UI
122IFrameLayerAndroid* BackgroundImagePositioning::updatePosition(SkRect aViewport,
123                                                          IFrameLayerAndroid* parentIframeLayer)
124{
125    SkRect viewport = getViewport(aViewport, parentIframeLayer);
126
127    float w = viewport.width() - m_layer->getWidth();
128    float h = viewport.height() - m_layer->getHeight();
129    float x = 0;
130    float y = 0;
131
132    if (m_fixedLeft.defined())
133        x += m_fixedLeft.calcFloatValue(w);
134    if (m_fixedTop.defined())
135        y += m_fixedTop.calcFloatValue(h);
136
137    m_nbRepeatX = ceilf((viewport.width() / m_layer->getWidth()) + 1);
138    m_offsetX = ceilf(x / m_layer->getWidth());
139
140    m_nbRepeatY = ceilf((viewport.height() / m_layer->getHeight()) + 1);
141    m_offsetY = ceilf(y / m_layer->getHeight());
142
143    x += viewport.fLeft;
144    y += viewport.fTop;
145
146    m_layer->setPosition(x, y);
147
148    return parentIframeLayer;
149}
150
151} // namespace WebCore
152
153#endif // USE(ACCELERATED_COMPOSITING)
154