summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderLayer.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-02 14:57:50 +0000
committerSteve Block <steveblock@google.com>2010-02-04 15:06:55 +0000
commitd0825bca7fe65beaee391d30da42e937db621564 (patch)
tree7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/rendering/RenderLayer.cpp
parent3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff)
downloadexternal_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz
external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/rendering/RenderLayer.cpp')
-rw-r--r--WebCore/rendering/RenderLayer.cpp114
1 files changed, 88 insertions, 26 deletions
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 7e0fee9..38e5f44 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -73,11 +73,13 @@
#include "RenderScrollbar.h"
#include "RenderScrollbarPart.h"
#include "RenderTheme.h"
+#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "ScaleTransformOperation.h"
#include "Scrollbar.h"
#include "ScrollbarTheme.h"
#include "SelectionController.h"
+#include "TextStream.h"
#include "TransformationMatrix.h"
#include "TransformState.h"
#include "TranslateTransformOperation.h"
@@ -657,6 +659,12 @@ static inline bool isPositionedContainer(RenderLayer* layer)
return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
}
+static inline bool isFixedPositionedContainer(RenderLayer* layer)
+{
+ RenderObject* o = layer->renderer();
+ return o->isRenderView() || layer->hasTransform();
+}
+
RenderLayer* RenderLayer::enclosingPositionedAncestor() const
{
RenderLayer* curr = parent();
@@ -826,7 +834,7 @@ void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer*
p->clip(clipRect);
p->beginTransparencyLayer(renderer()->opacity());
#ifdef REVEAL_TRANSPARENCY_LAYERS
- p->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
+ p->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), DeviceColorSpace);
p->fillRect(clipRect);
#endif
}
@@ -986,9 +994,10 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
{
if (ancestorLayer == this)
return;
-
- if (renderer()->style()->position() == FixedPosition) {
- // Add in the offset of the view. We can obtain this by calling
+
+ EPosition position = renderer()->style()->position();
+ if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer()->view()->layer())) {
+ // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
// localToAbsolute() on the RenderView.
FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
xPos += absPos.x();
@@ -996,9 +1005,43 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
return;
}
+ if (position == FixedPosition) {
+ // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
+ // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
+ // so we should always find the ancestor at or before we find the fixed position container.
+ RenderLayer* fixedPositionContainerLayer = 0;
+ bool foundAncestor = false;
+ for (RenderLayer* currLayer = parent(); currLayer; currLayer = currLayer->parent()) {
+ if (currLayer == ancestorLayer)
+ foundAncestor = true;
+
+ if (isFixedPositionedContainer(currLayer)) {
+ fixedPositionContainerLayer = currLayer;
+ ASSERT(foundAncestor);
+ break;
+ }
+ }
+
+ ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
+
+ if (fixedPositionContainerLayer != ancestorLayer) {
+ int fixedContainerX = 0;
+ int fixedContainerY = 0;
+ convertToLayerCoords(fixedPositionContainerLayer, fixedContainerX, fixedContainerY);
+
+ int ancestorX = 0;
+ int ancestorY = 0;
+ ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorX, ancestorY);
+
+ xPos += (fixedContainerX - ancestorX);
+ yPos += (fixedContainerY - ancestorY);
+ return;
+ }
+ }
+
RenderLayer* parentLayer;
- if (renderer()->style()->position() == AbsolutePosition) {
- // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way
+ if (position == AbsolutePosition || position == FixedPosition) {
+ // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
parentLayer = parent();
bool foundAncestorFirst = false;
while (parentLayer) {
@@ -1114,7 +1157,7 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
frame->eventHandler()->updateAutoscrollRenderer();
}
} else if (renderer()->view()->frameView()) {
- // If we are here, we were called on a renderer that can be programatically scrolled, but doesn't
+ // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
// have an overflow clip. Which means that it is a document node that can be scrolled.
renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));
// FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement?
@@ -1198,7 +1241,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// The caret rect needs to be invalidated after scrolling
Frame* frame = renderer()->document()->frame();
if (frame)
- frame->invalidateSelection();
+ frame->selection()->setNeedsLayout();
// Just schedule a full repaint of our object.
if (repaint)
@@ -1701,6 +1744,11 @@ IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
return localPoint - bottomRight;
}
+bool RenderLayer::hasOverflowControls() const
+{
+ return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
+}
+
void RenderLayer::positionOverflowControls(int tx, int ty)
{
if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
@@ -1886,16 +1934,22 @@ RenderLayer::updateScrollInfoAfterLayout()
// Set up the range (and page step/line step).
if (m_hBar) {
int clientWidth = box->clientWidth();
- int pageStep = (clientWidth - cAmountToKeepWhenPaging);
- if (pageStep < 0) pageStep = clientWidth;
+ int pageStep = max(clientWidth * cFractionToStepWhenPaging, 1.f);
m_hBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
m_hBar->setProportion(clientWidth, m_scrollWidth);
+ // Explicitly set the horizontal scroll value. This ensures that when a
+ // right-to-left scrollable area's width (or content width) changes, the
+ // top right corner of the content doesn't shift with respect to the top
+ // right corner of the area. Conceptually, right-to-left areas have
+ // their origin at the top-right, but RenderLayer is top-left oriented,
+ // so this is needed to keep everything working (see how scrollXOffset()
+ // differs from scrollYOffset() to get an idea of why the horizontal and
+ // vertical scrollbars need to be treated differently).
m_hBar->setValue(scrollXOffset());
}
if (m_vBar) {
int clientHeight = box->clientHeight();
- int pageStep = (clientHeight - cAmountToKeepWhenPaging);
- if (pageStep < 0) pageStep = clientHeight;
+ int pageStep = max(clientHeight * cFractionToStepWhenPaging, 1.f);
m_vBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
@@ -2228,7 +2282,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
// is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
// Else, our renderer tree may or may not contain the painting root, so we pass that root along
- // so it will be tested against as we decend through the renderers.
+ // so it will be tested against as we descend through the renderers.
RenderObject* paintingRootForRenderer = 0;
if (paintingRoot && !renderer()->isDescendantOf(paintingRoot))
paintingRootForRenderer = paintingRoot;
@@ -2351,15 +2405,10 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
}
}
- // Now determine if the result is inside an anchor; make sure an image map wins if
- // it already set URLElement and only use the innermost.
+ // Now determine if the result is inside an anchor - if the urlElement isn't already set.
Node* node = result.innerNode();
- while (node) {
- // for imagemaps, URLElement is the associated area element not the image itself
- if (node->isLink() && !result.URLElement() && !node->hasTagName(imgTag))
- result.setURLElement(static_cast<Element*>(node));
- node = node->eventParentNode();
- }
+ if (node && !result.URLElement())
+ result.setURLElement(static_cast<Element*>(node->enclosingLinkEventParentOrSelf()));
// Next set up the correct :hover/:active state along the new chain.
updateHoverActiveState(request, result);
@@ -2603,7 +2652,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
if (fgRect.contains(hitTestPoint) && isSelfPaintingLayer()) {
- // Hit test with a temporary HitTestResult, because we onlyl want to commit to 'result' if we know we're frontmost.
+ // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
HitTestResult tempResult(result.point());
if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
@@ -3238,7 +3287,7 @@ void RenderLayer::updateCompositingAndLayerListsIfNeeded()
#if USE(ACCELERATED_COMPOSITING)
if (compositor()->inCompositingMode()) {
if ((isStackingContext() && m_zOrderListsDirty) || m_normalFlowListDirty)
- compositor()->updateCompositingLayers(this);
+ compositor()->updateCompositingLayers(CompositingUpdateOnPaitingOrHitTest, this);
return;
}
#endif
@@ -3299,7 +3348,7 @@ void RenderLayer::repaintIncludingNonCompositingDescendants(RenderBoxModelObject
bool RenderLayer::shouldBeNormalFlowOnly() const
{
- return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo()) &&
+ return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isVideo() || renderer()->isEmbeddedObject()) &&
!renderer()->isPositioned() &&
!renderer()->isRelPositioned() &&
!renderer()->hasTransform() &&
@@ -3308,7 +3357,7 @@ bool RenderLayer::shouldBeNormalFlowOnly() const
bool RenderLayer::isSelfPaintingLayer() const
{
- return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo();
+ return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject();
}
void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
@@ -3322,7 +3371,7 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
dirtyStackingContextZOrderLists();
}
- if (renderer()->style()->overflowX() == OMARQUEE && renderer()->style()->marqueeBehavior() != MNONE) {
+ if (renderer()->style()->overflowX() == OMARQUEE && renderer()->style()->marqueeBehavior() != MNONE && renderer()->isBox()) {
if (!m_marquee)
m_marquee = new RenderMarquee(this);
m_marquee->updateMarqueeStyle();
@@ -3456,3 +3505,16 @@ void RenderLayer::updateReflectionStyle()
}
} // namespace WebCore
+
+#ifndef NDEBUG
+void showLayerTree(const WebCore::RenderLayer* layer)
+{
+ if (!layer)
+ return;
+
+ if (WebCore::Frame* frame = layer->renderer()->document()->frame()) {
+ WebCore::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers);
+ fprintf(stderr, "%s\n", output.utf8().data());
+ }
+}
+#endif