summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/layers/FixedPositioning.cpp
blob: aa204f8f5349af3e0c7e5617d39e680cb805486e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#define LOG_TAG "FixedPositioning"
#define LOG_NDEBUG 1

#include "config.h"
#include "FixedPositioning.h"

#include "AndroidLog.h"
#include "DumpLayer.h"
#include "IFrameLayerAndroid.h"
#include "TilesManager.h"
#include "SkCanvas.h"

#if USE(ACCELERATED_COMPOSITING)

namespace WebCore {

// Called when copying the layer tree to the UI
FixedPositioning::FixedPositioning(LayerAndroid* layer, const FixedPositioning& position)
        : m_layer(layer)
        , m_fixedLeft(position.m_fixedLeft)
        , m_fixedTop(position.m_fixedTop)
        , m_fixedRight(position.m_fixedRight)
        , m_fixedBottom(position.m_fixedBottom)
        , m_fixedMarginLeft(position.m_fixedMarginLeft)
        , m_fixedMarginTop(position.m_fixedMarginTop)
        , m_fixedMarginRight(position.m_fixedMarginRight)
        , m_fixedMarginBottom(position.m_fixedMarginBottom)
        , m_fixedRect(position.m_fixedRect)
        , m_renderLayerPos(position.m_renderLayerPos)
{
}

SkRect FixedPositioning::getViewport(SkRect aViewport, IFrameLayerAndroid* parentIframeLayer)
{
    // So if this is a fixed layer inside a iframe, use the iframe offset
    // and the iframe's size as the viewport and pass to the children
    if (parentIframeLayer)
        return SkRect::MakeXYWH(parentIframeLayer->iframeOffset().x(),
                                parentIframeLayer->iframeOffset().y(),
                                parentIframeLayer->getSize().width(),
                                parentIframeLayer->getSize().height());
    return aViewport;
}

// Executed on the UI
IFrameLayerAndroid* FixedPositioning::updatePosition(SkRect aViewport,
                                                     IFrameLayerAndroid* parentIframeLayer)
{
    SkRect viewport = getViewport(aViewport, parentIframeLayer);

    float w = viewport.width();
    float h = viewport.height();
    float dx = viewport.fLeft;
    float dy = viewport.fTop;
    float x = dx;
    float y = dy;

    // It turns out that when it is 'auto', we should use the webkit value
    // from the original render layer's X,Y, that will take care of alignment
    // with the parent's layer and fix Margin etc.
    if (!(m_fixedLeft.defined() || m_fixedRight.defined()))
        x += m_renderLayerPos.x();
    else if (m_fixedLeft.defined() || !m_fixedRight.defined())
        x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft;
    else
        x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight;

    if (!(m_fixedTop.defined() || m_fixedBottom.defined()))
        y += m_renderLayerPos.y();
    else if (m_fixedTop.defined() || !m_fixedBottom.defined())
        y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop;
    else
        y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom;

    m_layer->setPosition(x, y);

    return parentIframeLayer;
}

void FixedPositioning::contentDraw(SkCanvas* canvas, Layer::PaintStyle style)
{
    if (TilesManager::instance()->getShowVisualIndicator()) {
        SkPaint paint;
        paint.setARGB(80, 255, 0, 0);
        canvas->drawRect(m_fixedRect, paint);
    }
}

void FixedPositioning::dumpLayer(LayerDumper* dumper) const
{
    dumper->writeLength("fixedLeft", m_fixedLeft);
    dumper->writeLength("fixedTop", m_fixedTop);
    dumper->writeLength("fixedRight", m_fixedRight);
    dumper->writeLength("fixedBottom", m_fixedBottom);
    dumper->writeLength("fixedMarginLeft", m_fixedMarginLeft);
    dumper->writeLength("fixedMarginTop", m_fixedMarginTop);
    dumper->writeLength("fixedMarginRight", m_fixedMarginRight);
    dumper->writeLength("fixedMarginBottom", m_fixedMarginBottom);
    dumper->writeRect("fixedRect", m_fixedRect);
}

BackgroundImagePositioning::BackgroundImagePositioning(LayerAndroid* layer, const BackgroundImagePositioning& position)
        : FixedPositioning(layer, position)
        , m_repeatX(position.m_repeatX)
        , m_repeatY(position.m_repeatY)
        , m_nbRepeatX(position.m_nbRepeatX)
        , m_nbRepeatY(position.m_nbRepeatY)
        , m_offsetX(position.m_offsetX)
        , m_offsetY(position.m_offsetY)
{
}

// Executed on the UI
IFrameLayerAndroid* BackgroundImagePositioning::updatePosition(SkRect aViewport,
                                                               IFrameLayerAndroid* parentIframeLayer)
{
    SkRect viewport = getViewport(aViewport, parentIframeLayer);

    float w = viewport.width() - m_layer->getWidth();
    float h = viewport.height() - m_layer->getHeight();
    float x = 0;
    float y = 0;

    if (m_fixedLeft.defined())
        x += m_fixedLeft.calcFloatValue(w);
    if (m_fixedTop.defined())
        y += m_fixedTop.calcFloatValue(h);

    m_nbRepeatX = ceilf((viewport.width() / m_layer->getWidth()) + 1);
    m_offsetX = ceilf(x / m_layer->getWidth());

    m_nbRepeatY = ceilf((viewport.height() / m_layer->getHeight()) + 1);
    m_offsetY = ceilf(y / m_layer->getHeight());

    x += viewport.fLeft;
    y += viewport.fTop;

    m_layer->setPosition(x, y);

    return parentIframeLayer;
}

} // namespace WebCore

#endif // USE(ACCELERATED_COMPOSITING)