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 FixedPositioning::dumpLayer(LayerDumper* dumper) const
90{
91    dumper->writeLength("fixedLeft", m_fixedLeft);
92    dumper->writeLength("fixedTop", m_fixedTop);
93    dumper->writeLength("fixedRight", m_fixedRight);
94    dumper->writeLength("fixedBottom", m_fixedBottom);
95    dumper->writeLength("fixedMarginLeft", m_fixedMarginLeft);
96    dumper->writeLength("fixedMarginTop", m_fixedMarginTop);
97    dumper->writeLength("fixedMarginRight", m_fixedMarginRight);
98    dumper->writeLength("fixedMarginBottom", m_fixedMarginBottom);
99    dumper->writeRect("fixedRect", m_fixedRect);
100}
101
102BackgroundImagePositioning::BackgroundImagePositioning(LayerAndroid* layer, const BackgroundImagePositioning& position)
103        : FixedPositioning(layer, position)
104        , m_repeatX(position.m_repeatX)
105        , m_repeatY(position.m_repeatY)
106        , m_nbRepeatX(position.m_nbRepeatX)
107        , m_nbRepeatY(position.m_nbRepeatY)
108        , m_offsetX(position.m_offsetX)
109        , m_offsetY(position.m_offsetY)
110{
111}
112
113// Executed on the UI
114IFrameLayerAndroid* BackgroundImagePositioning::updatePosition(SkRect aViewport,
115                                                               IFrameLayerAndroid* parentIframeLayer)
116{
117    SkRect viewport = getViewport(aViewport, parentIframeLayer);
118
119    float w = viewport.width() - m_layer->getWidth();
120    float h = viewport.height() - m_layer->getHeight();
121    float x = 0;
122    float y = 0;
123
124    if (m_fixedLeft.defined())
125        x += m_fixedLeft.calcFloatValue(w);
126    if (m_fixedTop.defined())
127        y += m_fixedTop.calcFloatValue(h);
128
129    m_nbRepeatX = ceilf((viewport.width() / m_layer->getWidth()) + 1);
130    m_offsetX = ceilf(x / m_layer->getWidth());
131
132    m_nbRepeatY = ceilf((viewport.height() / m_layer->getHeight()) + 1);
133    m_offsetY = ceilf(y / m_layer->getHeight());
134
135    x += viewport.fLeft;
136    y += viewport.fTop;
137
138    m_layer->setPosition(x, y);
139
140    return parentIframeLayer;
141}
142
143} // namespace WebCore
144
145#endif // USE(ACCELERATED_COMPOSITING)
146