diff options
author | Patrick Scott <phanna@android.com> | 2010-08-13 16:17:40 -0400 |
---|---|---|
committer | Patrick Scott <phanna@android.com> | 2010-08-16 12:39:44 -0400 |
commit | 726264480d16a18c02f405aff63a32ba06fb0476 (patch) | |
tree | 97f7b473af2ce50a7165849008c1a4f385da3c5f /WebCore/rendering | |
parent | a01792f8060881461b672472ba3dfdd77044e0a5 (diff) | |
download | external_webkit-726264480d16a18c02f405aff63a32ba06fb0476.zip external_webkit-726264480d16a18c02f405aff63a32ba06fb0476.tar.gz external_webkit-726264480d16a18c02f405aff63a32ba06fb0476.tar.bz2 |
Update navigation in scrollable layers.
Set the foreground clip after drawing. Use the absolute bounds to
compute the local foreground clip in order to compensate for any
outline.
Consolidate the check for overflow scrolling into RenderLayer.
Request a compositing update after computing the scroll dimensions.
Only change the foregroundRect of the layer during paint so that the
outline rect (and background/layerBounds) are correct.
Draw the outline as part of the background phase. During painting of
a layer, scroll to (0,0), paint, then scroll back.
When clicking on an element in a layer, scroll to the position of the
element but do not scroll back. This makes text input fields visible
to the tree and will properly update when typing. Record the original
scroll position of layers in order to offset the bounds of nodes when
checking the nav cache. Make sure to reset all cached layers during
setRootLayer. Otherwise we were reaching into layers from the wrong
thread.
Change-Id: Id9827ec461989b0869a8252d4d2563ecd12c5fac
Diffstat (limited to 'WebCore/rendering')
-rw-r--r-- | WebCore/rendering/RenderLayer.cpp | 35 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayer.h | 3 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayerBacking.cpp | 51 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayerCompositor.cpp | 7 |
4 files changed, 65 insertions, 31 deletions
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index cc7eed0..ee1f1d4 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -1881,6 +1881,22 @@ bool RenderLayer::hasOverflowControls() const { return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE; } +#if ENABLE(ANDROID_OVERFLOW_SCROLL) +bool RenderLayer::hasOverflowScroll() const +{ + if (!enclosingElement()->hasTagName(HTMLNames::divTag)) + return false; + if (m_scrollDimensionsDirty) + return false; + EOverflow x = renderer()->style()->overflowX(); + if ((x == OSCROLL || x == OAUTO) && m_scrollWidth > renderBox()->clientWidth()) + return true; + EOverflow y = renderer()->style()->overflowY(); + if ((y == OSCROLL || y == OAUTO) && m_scrollHeight > renderBox()->clientHeight()) + return true; + return false; +} +#endif void RenderLayer::positionOverflowControls(int tx, int ty) { @@ -1954,6 +1970,13 @@ void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar) *needHBar = rightPos > clientWidth; if (needVBar) *needVBar = bottomPos > clientHeight; +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (hasOverflowScroll()) { + compositor()->setCompositingLayersNeedRebuild(true); + compositor()->enableCompositingMode(true); + compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange, this); + } +#endif } void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow) @@ -3219,13 +3242,11 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa if (renderer()->hasOverflowClip() || renderer()->hasClip()) { // This layer establishes a clip of some kind. #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (renderer()->hasOverflowClip() && - !m_scrollDimensionsDirty && - (m_scrollWidth > renderBox()->clientWidth() || - m_scrollHeight > renderBox()->clientHeight())) { + if (hasOverflowScroll()) { RenderBox* box = toRenderBox(renderer()); - layerBounds = backgroundRect = foregroundRect = outlineRect = - IntRect(x, y, box->borderLeft() + box->borderRight() + m_scrollWidth, + foregroundRect = + IntRect(x, y, + box->borderLeft() + box->borderRight() + m_scrollWidth, box->borderTop() + box->borderBottom() + m_scrollHeight); } else #endif @@ -3743,7 +3764,7 @@ bool RenderLayer::shouldBeNormalFlowOnly() const bool RenderLayer::isSelfPaintingLayer() const { #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (renderer()->hasOverflowClip()) + if (hasOverflowScroll()) return true; #endif return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject() || renderer()->isRenderIFrame(); diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h index e8c290b..ba79292 100644 --- a/WebCore/rendering/RenderLayer.h +++ b/WebCore/rendering/RenderLayer.h @@ -265,6 +265,9 @@ public: int horizontalScrollbarHeight() const; bool hasOverflowControls() const; +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + bool hasOverflowScroll() const; +#endif void positionOverflowControls(int tx, int ty); bool isPointInResizeControl(const IntPoint& absolutePoint) const; bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint); diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp index 421196b..0db94dc 100644 --- a/WebCore/rendering/RenderLayerBacking.cpp +++ b/WebCore/rendering/RenderLayerBacking.cpp @@ -441,18 +441,6 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() } m_graphicsLayer->setContentsRect(contentsBox()); -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (m_owningLayer->hasOverflowControls()) { - RenderBoxModelObject* box = renderer(); - IntRect clip = compositedBounds(); - IntPoint location = clip.location(); - location.move(box->borderLeft(), box->borderTop()); - clip.setLocation(location); - clip.setWidth(clip.width() - box->borderLeft() - box->borderRight()); - clip.setHeight(clip.height() - box->borderTop() - box->borderBottom()); - static_cast<GraphicsLayerAndroid*>(m_graphicsLayer.get())->setContentsClip(clip); - } -#endif updateDrawsContent(); updateAfterWidgetResize(); } @@ -882,21 +870,17 @@ IntRect RenderLayerBacking::contentsBox() const #endif contentsRect = toRenderBox(renderer())->contentBoxRect(); #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (m_owningLayer->hasOverflowControls()) { + if (m_owningLayer->hasOverflowScroll()) { // Update the contents rect to have the width and height of the entire // contents. This rect is only used by the platform GraphicsLayer and // the position of the rectangle is ignored. Use the layer's scroll // width/height (which contain the padding). RenderBox* box = toRenderBox(renderer()); + int outline = box->view()->maximalOutlineSize() << 1; contentsRect.setWidth(box->borderLeft() + box->borderRight() + - m_owningLayer->scrollWidth()); + m_owningLayer->scrollWidth() + outline); contentsRect.setHeight(box->borderTop() + box->borderBottom() + - m_owningLayer->scrollHeight()); - // Move the contents rect by the padding since - // RenderBox::contentBoxRect includes the padding. The end result is - // to have a box representing the entires contents plus border and - // padding. This will be the size of the underlying picture. - contentsRect.setLocation(IntPoint(0, 0)); + m_owningLayer->scrollHeight() + outline); } #endif @@ -1021,6 +1005,17 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* // Restore the clip. restoreClip(context, paintDirtyRect, damageRect); +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + // Paint the outline as part of the background phase in order for the + // outline to not be a part of the scrollable content. + if (!outlineRect.isEmpty()) { + // Paint our own outline + PaintInfo paintInfo(context, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0); + setClip(context, paintDirtyRect, outlineRect); + renderer()->paint(paintInfo, tx, ty); + restoreClip(context, paintDirtyRect, outlineRect); + } +#endif // Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint. m_owningLayer->paintList(m_owningLayer->negZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0); @@ -1030,6 +1025,13 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly; if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) { +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + // Scroll to 0,0 and paint the entire contents, then scroll back the + // the original offset. + int x = m_owningLayer->scrollXOffset(); + int y = m_owningLayer->scrollYOffset(); + m_owningLayer->scrollToOffset(0, 0, false, false); +#endif // Set up the clip used when painting our children. setClip(context, paintDirtyRect, clipRectToApply); PaintInfo paintInfo(context, clipRectToApply, @@ -1051,6 +1053,9 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* // Now restore our clip. restoreClip(context, paintDirtyRect, clipRectToApply); +#if !ENABLE(ANDROID_OVERFLOW_SCROLL) + // Do not paint the outline as part of the foreground since it will + // appear inside the scrollable content. if (!outlineRect.isEmpty()) { // Paint our own outline PaintInfo paintInfo(context, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0); @@ -1058,12 +1063,16 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* renderer()->paint(paintInfo, tx, ty); restoreClip(context, paintDirtyRect, outlineRect); } +#endif // Paint any child layers that have overflow. m_owningLayer->paintList(m_owningLayer->normalFlowList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0); // Now walk the sorted list of children with positive z-indices. m_owningLayer->paintList(m_owningLayer->posZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0); +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + m_owningLayer->scrollToOffset(x, y, false, false); +#endif } if (shouldPaint && (paintingPhase & GraphicsLayerPaintMask)) { @@ -1107,7 +1116,7 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co // can compute and cache clipRects. IntRect enclosingBBox = compositedBounds(); #if ENABLE(ANDROID_OVERFLOW_SCROLL) - if (m_owningLayer->hasOverflowControls()) { + if (m_owningLayer->hasOverflowScroll()) { enclosingBBox.setSize(contentsBox().size()); enclosingBBox.setLocation(m_compositedBounds.location()); } diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index 12c8a56..72a2d32 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -1135,6 +1135,10 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const #if PLATFORM(ANDROID) bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* layer) const { +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (layer->hasOverflowScroll()) + return true; +#endif #if ENABLE(COMPOSITED_FIXED_ELEMENTS) // First, check if we are in an iframe, and if so bail out if (m_renderView->document()->frame()->tree()->parent()) @@ -1174,9 +1178,6 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c return requiresCompositingForTransform(renderer) #if PLATFORM(ANDROID) || requiresCompositingForMobileSites(layer) -#if ENABLE(ANDROID_OVERFLOW_SCROLL) - || renderer->hasOverflowClip() -#endif #endif || requiresCompositingForVideo(renderer) || requiresCompositingForCanvas(renderer) |