diff options
author | Steve Block <steveblock@google.com> | 2010-02-02 14:57:50 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-04 15:06:55 +0000 |
commit | d0825bca7fe65beaee391d30da42e937db621564 (patch) | |
tree | 7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/rendering/RenderLayer.cpp | |
parent | 3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff) | |
download | external_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.cpp | 114 |
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 |