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 15 namespace WebCore { 16 17 // Called when copying the layer tree to the UI 18 FixedPositioning::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 33 SkRect 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 46 IFrameLayerAndroid* 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 80 void 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 89 void 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 102 BackgroundImagePositioning::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 114 IFrameLayerAndroid* 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