Source/core/rendering/RenderLayer.cpp
// Returns the layer reached on the walk up towards the ancestor.
Returns the layer reached on the walk up towards the ancestor.
Returns the layer reached on the walk up towards the ancestor .
static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
{
    ASSERT(ancestorLayer != layer);
    const RenderLayerModelObject* renderer = layer->renderer();
    EPosition position = renderer->style()->position();
    RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer->flowThreadContainingBlock() : 0;
    if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
        fixedFlowThreadContainer = 0;
    if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
        FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed);
        location += LayoutSize(absPos.x(), absPos.y());
        return ancestorLayer;
    }
    if (position == FixedPosition && !fixedFlowThreadContainer) {
        RenderLayer* fixedPositionContainerLayer = 0;
        bool foundAncestor = false;
        for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
            if (currLayer == ancestorLayer)
                foundAncestor = true;
            if (isFixedPositionedContainer(currLayer)) {
                fixedPositionContainerLayer = currLayer;
                ASSERT_UNUSED(foundAncestor, foundAncestor);
                break;
            }
        }
        ASSERT(fixedPositionContainerLayer); 
        if (fixedPositionContainerLayer != ancestorLayer) {
            LayoutPoint fixedContainerCoords;
            layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
            LayoutPoint ancestorCoords;
            ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
            location += (fixedContainerCoords - ancestorCoords);
        } else {
            location += toSize(layer->location());
        }
        return ancestorLayer;
    }
    RenderLayer* parentLayer;
    if (position == AbsolutePosition || position == FixedPosition) {
        parentLayer = layer->parent();
        bool foundAncestorFirst = false;
        while (parentLayer) {
            if (parentLayer->isPositionedContainer())
                break;
            if (parentLayer == ancestorLayer) {
                foundAncestorFirst = true;
                break;
            }
            parentLayer = parentLayer->parent();
        }
        ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer());
        if (foundAncestorFirst) {
            RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
            LayoutPoint thisCoords;
            layer->convertToLayerCoords(positionedAncestor, thisCoords);
            LayoutPoint ancestorCoords;
            ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
            location += (thisCoords - ancestorCoords);
            return ancestorLayer;
        }
    } else
        parentLayer = layer->parent();
    if (!parentLayer)
        return 0;
    location += toSize(layer->location());
    return parentLayer;
}
static inline const RenderLayer * accumulateOffsetTowardsAncestor ( const RenderLayer * layer , const RenderLayer * ancestorLayer , LayoutPoint & location ) { ASSERT ( ancestorLayer != layer ) ; const RenderLayerModelObject * renderer = layer -> renderer ( ) ; EPosition position = renderer -> style ( ) -> position ( ) ; RenderFlowThread * fixedFlowThreadContainer = position == FixedPosition ? renderer -> flowThreadContainingBlock ( ) : 0 ; if ( fixedFlowThreadContainer && ! fixedFlowThreadContainer -> isOutOfFlowPositioned ( ) ) fixedFlowThreadContainer = 0 ; if ( position == FixedPosition && ! fixedFlowThreadContainer && ( ! ancestorLayer || ancestorLayer == renderer -> view ( ) -> layer ( ) ) ) { FloatPoint absPos = renderer -> localToAbsolute ( FloatPoint ( ) , IsFixed ) ; location += LayoutSize ( absPos . x ( ) , absPos . y ( ) ) ; return ancestorLayer ; } if ( position == FixedPosition && ! fixedFlowThreadContainer ) { RenderLayer * fixedPositionContainerLayer = 0 ; bool foundAncestor = false ; for ( RenderLayer * currLayer = layer -> parent ( ) ; currLayer ; currLayer = currLayer -> parent ( ) ) { if ( currLayer == ancestorLayer ) foundAncestor = true ; if ( isFixedPositionedContainer ( currLayer ) ) { fixedPositionContainerLayer = currLayer ; ASSERT_UNUSED ( foundAncestor , foundAncestor ) ; break ; } } ASSERT ( fixedPositionContainerLayer ) ; if ( fixedPositionContainerLayer != ancestorLayer ) { LayoutPoint fixedContainerCoords ; layer -> convertToLayerCoords ( fixedPositionContainerLayer , fixedContainerCoords ) ; LayoutPoint ancestorCoords ; ancestorLayer -> convertToLayerCoords ( fixedPositionContainerLayer , ancestorCoords ) ; location += ( fixedContainerCoords - ancestorCoords ) ; } else { location += toSize ( layer -> location ( ) ) ; } return ancestorLayer ; } RenderLayer * parentLayer ; if ( position == AbsolutePosition || position == FixedPosition ) { parentLayer = layer -> parent ( ) ; bool foundAncestorFirst = false ; while ( parentLayer ) { if ( parentLayer -> isPositionedContainer ( ) ) break ; if ( parentLayer == ancestorLayer ) { foundAncestorFirst = true ; break ; } parentLayer = parentLayer -> parent ( ) ; } ASSERT ( ! renderer -> flowThreadContainingBlock ( ) || parentLayer != renderer -> view ( ) -> layer ( ) ) ; if ( foundAncestorFirst ) { RenderLayer * positionedAncestor = parentLayer -> enclosingPositionedAncestor ( ) ; LayoutPoint thisCoords ; layer -> convertToLayerCoords ( positionedAncestor , thisCoords ) ; LayoutPoint ancestorCoords ; ancestorLayer -> convertToLayerCoords ( positionedAncestor , ancestorCoords ) ; location += ( thisCoords - ancestorCoords ) ; return ancestorLayer ; } } else parentLayer = layer -> parent ( ) ; if ( ! parentLayer ) return 0 ; location += toSize ( layer -> location ( ) ) ; return parentLayer ; }
Returns the layer reached on the walk up towards the ancestor.
Returns the layer reached on the walk up towards the ancestor .
// FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great. // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread // may need to be revisited in a future patch. // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute, // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be // positioned in a completely different place in the viewport (RenderView). // 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. // For the fixed positioned elements inside a render flow thread, we should also skip the code path below // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer. // 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. // We should have hit the RenderView's layer at least. // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way. // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0). // This implies that, for out-of-flow positioned elements inside a RenderFlowThread, // we are bailing out before reaching root layer. // We should not reach RenderView layer past the RenderFlowThread layer for any // children of the RenderFlowThread. // Found ancestorLayer before the abs. positioned container, so compute offset of both relative // to enclosingPositionedAncestor and subtract.