summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Scott <phanna@android.com>2010-08-16 09:40:57 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-08-16 09:40:57 -0700
commit96b9354838038389fdab0383662e91575e3daa6c (patch)
tree798b195792b6e077c86f0831a6d35d65355b6e0f
parent9a8d8723cd9c45c526a7c46d1e7d343e50e4e119 (diff)
parent726264480d16a18c02f405aff63a32ba06fb0476 (diff)
downloadexternal_webkit-96b9354838038389fdab0383662e91575e3daa6c.zip
external_webkit-96b9354838038389fdab0383662e91575e3daa6c.tar.gz
external_webkit-96b9354838038389fdab0383662e91575e3daa6c.tar.bz2
Merge "Update navigation in scrollable layers."
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp38
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.h2
-rw-r--r--WebCore/rendering/RenderLayer.cpp35
-rw-r--r--WebCore/rendering/RenderLayer.h3
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp51
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp7
-rw-r--r--WebKit/android/jni/WebViewCore.cpp37
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp23
-rw-r--r--WebKit/android/nav/CacheBuilder.h1
-rw-r--r--WebKit/android/nav/CachedLayer.cpp25
-rw-r--r--WebKit/android/nav/CachedLayer.h6
-rw-r--r--WebKit/android/nav/CachedRoot.h5
12 files changed, 155 insertions, 78 deletions
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index a5ca972..adbd18b 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -106,6 +106,12 @@ SkLength convertLength(Length l) {
return length;
}
+static RenderLayer* renderLayerFromClient(GraphicsLayerClient* client) {
+ if (client)
+ return static_cast<RenderLayerBacking*>(client)->owningLayer();
+ return 0;
+}
+
GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
GraphicsLayer(client),
m_needsSyncChildren(false),
@@ -122,9 +128,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_currentPosition(0, 0)
{
m_contentLayer = new LayerAndroid(true);
- if (m_client) {
- RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
- RenderLayer* renderLayer = backing->owningLayer();
+ RenderLayer* renderLayer = renderLayerFromClient(m_client);
+ if (renderLayer) {
m_contentLayer->setIsRootLayer(renderLayer->isRootLayer() &&
!(renderLayer->renderer()->frame()->ownerElement()));
}
@@ -224,8 +229,7 @@ void GraphicsLayerAndroid::updateFixedPosition()
if (!m_client)
return;
- RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
- RenderLayer* renderLayer = backing->owningLayer();
+ RenderLayer* renderLayer = renderLayerFromClient(m_client);
RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
// If we are a fixed position layer, just set it
@@ -293,9 +297,6 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
GraphicsLayer::setSize(size);
m_contentLayer->setSize(size.width(), size.height());
- m_contentLayer->setForegroundClip(
- SkRect::MakeWH(SkFloatToScalar(size.width()),
- SkFloatToScalar(size.height())));
updateFixedPosition();
askForSync();
}
@@ -473,6 +474,22 @@ bool GraphicsLayerAndroid::repaint()
m_needsRepaint = false;
m_invalidatedRects.clear();
+ RenderLayer* layer = renderLayerFromClient(m_client);
+ // Use the absolute bounds of the renderer instead of the layer's
+ // bounds because the layer will add in the outline. What we want
+ // is the content bounds inside the outline.
+ FloatRect clip = layer->renderer()->absoluteBoundingBoxRect();
+ // Move the clip local to the layer position.
+ clip.move(-m_position.x(), -m_position.y());
+ if (layer->hasOverflowScroll()) {
+ // If this is a scrollable layer, inset the clip by the border.
+ RenderBox* box = layer->renderBox();
+ clip.move(box->borderLeft(), box->borderTop());
+ clip.setWidth(clip.width() - box->borderLeft() - box->borderRight());
+ clip.setHeight(clip.height() - box->borderTop() - box->borderBottom());
+ }
+ m_contentLayer->setForegroundClip(clip);
+
return true;
}
return false;
@@ -927,11 +944,6 @@ void GraphicsLayerAndroid::notifyClientAnimationStarted()
}
}
-void GraphicsLayerAndroid::setContentsClip(const IntRect& clip)
-{
- m_contentLayer->setForegroundClip(clip);
-}
-
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 7482969..80c92f3 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -115,8 +115,6 @@ public:
static int instancesCount();
- void setContentsClip(const IntRect& clip);
-
private:
void askForSync();
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)
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 1ed885a..31c6120 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2360,7 +2360,8 @@ void WebViewCore::touchUp(int touchGeneration,
// Return the RenderLayer for the given RenderObject only if the layer is
// composited and it contains a scrollable content layer.
-static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* renderer)
+static WebCore::RenderLayer* getLayerFromRenderer(
+ WebCore::RenderObject* renderer, LayerAndroid** aLayer)
{
if (!renderer)
return 0;
@@ -2371,9 +2372,10 @@ static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* rendere
static_cast<GraphicsLayerAndroid*>(layer->backing()->graphicsLayer());
if (!graphicsLayer)
return 0;
- LayerAndroid* aLayer = graphicsLayer->contentLayer();
- if (!aLayer || !aLayer->contentIsScrollable())
+ LayerAndroid* layerAndroid = graphicsLayer->contentLayer();
+ if (!layerAndroid || !layerAndroid->contentIsScrollable())
return 0;
+ *aLayer = layerAndroid;
return layer;
}
@@ -2381,34 +2383,27 @@ static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* rendere
// done so that the node is visible when it is clicked.
static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos)
{
- WebCore::RenderLayer* layer = getLayerFromRenderer(renderer);
+ LayerAndroid* aLayer;
+ WebCore::RenderLayer* layer = getLayerFromRenderer(renderer, &aLayer);
if (!layer)
return;
WebCore::IntRect absBounds = renderer->absoluteBoundingBoxRect();
- WebCore::IntRect layerBounds = layer->absoluteBoundingBox();
+ // Do not include the outline when moving the node's bounds.
+ WebCore::IntRect layerBounds = layer->renderer()->absoluteBoundingBoxRect();
// Move the node's bounds into the layer's coordinates.
absBounds.move(-layerBounds.x(), -layerBounds.y());
+ int diffX = layer->scrollXOffset();
+ int diffY = layer->scrollYOffset();
// Scroll the layer to the node's position. The false parameters tell the
// layer not to invalidate.
- layer->scrollToOffset(absBounds.x(), absBounds.y(), false, false);
+ layer->scrollToOffset(absBounds.x(), absBounds.y(), false, true);
+ diffX = layer->scrollXOffset() - diffX;
+ diffY = layer->scrollYOffset() - diffY;
// Update the mouse position to the layer offset.
- pos->move(-layer->scrollXOffset(), -layer->scrollYOffset());
-}
-
-static void restoreScrolledLayer(WebCore::RenderObject* renderer,
- WebCore::IntPoint* pos)
-{
- WebCore::RenderLayer* layer = getLayerFromRenderer(renderer);
- if (!layer)
- return;
- // Move the mouse position back to it's original position.
- pos->move(layer->scrollXOffset(), layer->scrollYOffset());
-
- // Scroll the layer back to 0,0.
- layer->scrollToOffset(0, 0, false, false);
+ pos->move(-diffX, -diffY);
}
// Common code for both clicking with the trackball and touchUp
@@ -2508,8 +2503,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
requestKeyboard(true);
}
}
- if (nodePtr && valid)
- restoreScrolledLayer(nodePtr->renderer(), &m_mousePos);
return handled;
}
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index e76c729..c05395c 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -915,7 +915,7 @@ static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
#if USE(ACCELERATED_COMPOSITING)
static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
- int id)
+ const IntPoint& scroll, int id)
{
DBG_NAV_LOGD("frame=%p index=%d loc=(%d,%d) id=%d", frame, index,
location.x(), location.y(), id);
@@ -923,6 +923,7 @@ static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
cachedLayer.reset();
cachedLayer.setCachedNodeIndex(index);
cachedLayer.setOffset(location);
+ cachedLayer.setScrollOffset(scroll);
cachedLayer.setUniqueId(id);
frame->add(cachedLayer);
}
@@ -1063,12 +1064,16 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
TrackLayer(layerTracker, nodeRenderer, lastChild,
globalOffsetX, globalOffsetY);
size_t size = tracker.size();
- const LayerAndroid* layer = layerTracker.last().mLayer;
+ LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
int id = layer->uniqueId();
- IntPoint loc = nodeRenderer->
- absoluteBoundingBoxRect().location();
+ const RenderLayer* renderLayer =
+ layerTracker.last().mRenderLayer;
+ IntPoint loc(SkScalarRound(layer->getPosition().fX),
+ SkScalarRound(layer->getPosition().fY));
loc.move(globalOffsetX, globalOffsetY);
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
// if this is a child of a CachedNode, add a layer
size_t limit = cachedFrame->layerCount() == 0 ? 0 :
cachedFrame->lastLayer()->cachedNodeIndex();
@@ -1084,7 +1089,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
CachedNode* trackedNode = cachedFrame->getIndex(index);
trackedNode->setIsInLayer(true);
trackedNode->setIsUnclipped(true);
- AddLayer(cachedFrame, index, loc, id);
+ AddLayer(cachedFrame, index, loc, scroll, id);
}
}
}
@@ -1327,6 +1332,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
const IntRect& layerClip = layerTracker.last().mBounds;
+ const RenderLayer* renderLayer = layerTracker.last().mRenderLayer;
if (!layer->contentIsScrollable() && !layerClip.isEmpty() &&
!cachedNode.clip(layerClip)) {
DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex);
@@ -1334,8 +1340,10 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
}
isInLayer = true;
isUnclipped = true; // assume that layers do not have occluded nodes
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
AddLayer(cachedFrame, cachedFrame->size(), layerClip.location(),
- layer->uniqueId());
+ scroll, layer->uniqueId());
}
#endif
cachedNode.setNavableRects();
@@ -2838,7 +2846,8 @@ void CacheBuilder::TrackLayer(WTF::Vector<LayerTracker>& layerTracker,
layerTracker.grow(layerTracker.size() + 1);
LayerTracker& indexTracker = layerTracker.last();
indexTracker.mLayer = aLayer;
- indexTracker.mBounds = nodeRenderer->absoluteBoundingBoxRect();
+ indexTracker.mRenderLayer = layer;
+ indexTracker.mBounds = IntRect(FloatRect(aLayer->bounds()));
indexTracker.mBounds.move(offsetX, offsetY);
indexTracker.mLastChild = lastChild ? OneAfter(lastChild) : 0;
DBG_NAV_LOGD("layer=%p [%d] bounds=(%d,%d,w=%d,h=%d)", aLayer,
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 5324187..d19e0c9 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -198,6 +198,7 @@ private:
};
struct LayerTracker : Tracker {
LayerAndroid* mLayer;
+ RenderLayer* mRenderLayer;
IntRect mBounds;
};
struct TabIndexTracker : Tracker {
diff --git a/WebKit/android/nav/CachedLayer.cpp b/WebKit/android/nav/CachedLayer.cpp
index 9c7d59b..c4293a5 100644
--- a/WebKit/android/nav/CachedLayer.cpp
+++ b/WebKit/android/nav/CachedLayer.cpp
@@ -49,6 +49,10 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
// First, remove the original offset from the bounds.
temp.move(-mOffset.x(), -mOffset.y());
+ // Now, add in the original scroll position. This moves the node to the
+ // original location within the layer.
+ temp.move(mScrollOffset.x(), mScrollOffset.y());
+
// Next, add in the new position of the layer (could be different due to a
// fixed position layer).
const FloatPoint& position = aLayer->getPosition();
@@ -72,12 +76,17 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
DBG_NAV_LOGD("root=%p aLayer=%p [%d]"
" bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g)"
+ " pos=(%f,%f)"
" offset=(%d,%d) clip=(%d,%d,w=%d,h=%d)"
+ " scroll=(%d,%d) origScroll=(%d,%d)"
" result=(%d,%d,w=%d,h=%d)",
root, aLayer, aLayer->uniqueId(),
bounds.x(), bounds.y(), bounds.width(), bounds.height(),
- translation.x(), translation.y(), mOffset.x(), mOffset.y(),
+ translation.x(), translation.y(), position.x(), position.y(),
+ mOffset.x(), mOffset.y(),
clip.x(), clip.y(), clip.width(), clip.height(),
+ SkScalarRound(scroll.fX), SkScalarRound(scroll.fY),
+ mScrollOffset.x(), mScrollOffset.y(),
result.x(), result.y(), result.width(), result.height());
return result;
}
@@ -104,6 +113,9 @@ IntRect CachedLayer::unadjustBounds(const LayerAndroid* root,
// Move it back to the original offset.
temp.move(mOffset.x(), mOffset.y());
+
+ // Move the bounds by the original scroll.
+ temp.move(-mScrollOffset.x(), -mScrollOffset.y());
return temp;
}
@@ -122,6 +134,10 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
// Remove the original offset from the bounds.
temp.move(-mOffset.x(), -mOffset.y());
+ // We add in the original scroll position in order to position the node
+ // relative to the current internal scroll position.
+ temp.move(mScrollOffset.x(), mScrollOffset.y());
+
const LayerAndroid* aLayer = layer(root);
if (aLayer) {
// Move the bounds by the scroll position of the layer.
@@ -134,7 +150,12 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
temp.intersect(IntRect(aLayer->foregroundClip()));
}
- return enclosingIntRect(temp);
+ DBG_NAV_LOGD("bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)"
+ " result=(%d,%d,w=%d,h=%d)", bounds.x(), bounds.y(),
+ bounds.width(), bounds.height(), mOffset.x(), mOffset.y(),
+ temp.x(), temp.y(), temp.width(), temp.height());
+
+ return temp;
}
SkPicture* CachedLayer::picture(const LayerAndroid* root) const
diff --git a/WebKit/android/nav/CachedLayer.h b/WebKit/android/nav/CachedLayer.h
index 8bfe922..0a56ea1 100644
--- a/WebKit/android/nav/CachedLayer.h
+++ b/WebKit/android/nav/CachedLayer.h
@@ -58,12 +58,18 @@ public:
void reset() { mLayer = 0; }
void setCachedNodeIndex(int index) { mCachedNodeIndex = index; }
void setOffset(const IntPoint& offset) { mOffset = offset; }
+ void setScrollOffset(const IntPoint& scrollOffset) {
+ mScrollOffset = scrollOffset;
+ }
void setUniqueId(int uniqueId) { mUniqueId = uniqueId; }
int uniqueId() const { return mUniqueId; }
private:
int mCachedNodeIndex;
mutable const LayerAndroid* mLayer;
+ // mOffset and mScrollOffset are the position and scroll offset of the
+ // layer when recorded by the nav cache.
IntPoint mOffset;
+ IntPoint mScrollOffset;
int mUniqueId;
#if DUMP_NAV_CACHE
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 2853241..a6420f9 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -96,7 +96,10 @@ public:
void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; }
void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; }
void setPicture(SkPicture* picture) { mPicture = picture; }
- void setRootLayer(WebCore::LayerAndroid* layer) { mRootLayer = layer; }
+ void setRootLayer(WebCore::LayerAndroid* layer) {
+ mRootLayer = layer;
+ resetLayers();
+ }
void setScrollOnly(bool state) { mScrollOnly = state; }
void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; }
void setupScrolledBounds() const { mScrolledBounds = mViewBounds; }