| Index: Source/core/layout/LayoutObject.cpp
|
| diff --git a/Source/core/layout/LayoutObject.cpp b/Source/core/layout/LayoutObject.cpp
|
| index abd4d61201124cc82585b605cd753adc344d9950..7054ed37332a49fc9c6fc1a9a480dc596a89c534 100644
|
| --- a/Source/core/layout/LayoutObject.cpp
|
| +++ b/Source/core/layout/LayoutObject.cpp
|
| @@ -2040,22 +2040,63 @@ void LayoutObject::mapLocalToContainer(const LayoutBoxModelObject* paintInvalida
|
| if (paintInvalidationContainer == this)
|
| return;
|
|
|
| - LayoutObject* o = parent();
|
| + if (paintInvalidationState && paintInvalidationState->canMapToContainer(paintInvalidationContainer)) {
|
| + LayoutSize offset = paintInvalidationState->paintOffset();
|
| + if (isBox())
|
| + offset += toLayoutBox(this)->locationOffset();
|
| + if (!isText() && style()->hasInFlowPosition() && hasLayer())
|
| + offset += toLayoutBoxModelObject(this)->layer()->offsetForInFlowPosition();
|
| + transformState.move(offset);
|
| + return;
|
| + }
|
| +
|
| + bool containerSkipped;
|
| + LayoutObject* o = container(paintInvalidationContainer, &containerSkipped);
|
| if (!o)
|
| return;
|
|
|
| - // FIXME: this should call offsetFromContainer to share code, but I'm not sure it's ever called.
|
| - LayoutPoint centerPoint = roundedLayoutPoint(transformState.mappedPoint());
|
| - if (mode & ApplyContainerFlip && o->isBox()) {
|
| - if (o->style()->isFlippedBlocksWritingMode())
|
| - transformState.move(toLayoutBox(o)->flipForWritingMode(roundedLayoutPoint(transformState.mappedPoint())) - centerPoint);
|
| + if (isBox()) {
|
| + bool isFixedPos = style()->position() == FixedPosition;
|
| + bool hasTransform = hasLayer() && toLayoutBox(this)->layer()->transform();
|
| + // If this box has a transform, it acts as a fixed position container for fixed descendants,
|
| + // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
|
| + if (hasTransform && !isFixedPos)
|
| + mode &= ~IsFixed;
|
| + else if (isFixedPos)
|
| + mode |= IsFixed;
|
| +
|
| + if (wasFixed)
|
| + *wasFixed = mode & IsFixed;
|
| +
|
| + mode &= ~ApplyContainerFlip;
|
| + paintInvalidationState = nullptr;
|
| + } else if (mode & ApplyContainerFlip && o->isBox()) {
|
| + if (o->style()->isFlippedBlocksWritingMode()) {
|
| + IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
|
| + transformState.move(toLayoutBox(o)->flipForWritingMode(LayoutPoint(centerPoint)) - centerPoint);
|
| + }
|
| mode &= ~ApplyContainerFlip;
|
| }
|
|
|
| - transformState.move(o->columnOffset(roundedLayoutPoint(transformState.mappedPoint())));
|
| + LayoutSize containerOffset = offsetFromContainer(o);
|
| + containerOffset += o->columnOffset(roundedLayoutPoint(transformState.mappedPoint()) + containerOffset);
|
|
|
| - if (o->hasOverflowClip())
|
| - transformState.move(-toLayoutBox(o)->scrolledContentOffset());
|
| + bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || (!isText() && style()->preserves3D()));
|
| + if (mode & UseTransforms && shouldUseTransformFromContainer(o)) {
|
| + TransformationMatrix t;
|
| + getTransformFromContainer(o, containerOffset, t);
|
| + transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
|
| + } else {
|
| + transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
|
| + }
|
| +
|
| + if (containerSkipped) {
|
| + // There can't be a transform between paintInvalidationContainer and o, because transforms create containers, so it should be safe
|
| + // to just subtract the delta between the paintInvalidationContainer and o.
|
| + LayoutSize containerOffset = paintInvalidationContainer->offsetFromAncestorContainer(o);
|
| + transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform);
|
| + return;
|
| + }
|
|
|
| o->mapLocalToContainer(paintInvalidationContainer, transformState, mode, wasFixed, paintInvalidationState);
|
| }
|
| @@ -2107,8 +2148,8 @@ void LayoutObject::getTransformFromContainer(const LayoutObject* containerObject
|
|
|
| FloatQuad LayoutObject::localToContainerQuad(const FloatQuad& localQuad, const LayoutBoxModelObject* paintInvalidationContainer, MapCoordinatesFlags mode, bool* wasFixed) const
|
| {
|
| - // Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
|
| - // it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
|
| + // Track the point at the center of the quad's bounding box. mapLocalToContainer() will use
|
| + // that point as the reference point to decide which column we're in for multiple-column blocks.
|
| TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
|
| mapLocalToContainer(paintInvalidationContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
|
| transformState.flatten();
|
| @@ -2143,19 +2184,12 @@ FloatPoint LayoutObject::localToInvalidationBackingPoint(const LayoutPoint& loca
|
| return containerPoint;
|
| }
|
|
|
| -LayoutSize LayoutObject::offsetFromContainer(const LayoutObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
|
| +LayoutSize LayoutObject::offsetFromContainer(const LayoutObject* o) const
|
| {
|
| ASSERT(o == container());
|
| -
|
| - LayoutSize offset = o->columnOffset(point);
|
| -
|
| if (o->hasOverflowClip())
|
| - offset -= toLayoutBox(o)->scrolledContentOffset();
|
| -
|
| - if (offsetDependsOnPoint)
|
| - *offsetDependsOnPoint = o->isLayoutFlowThread();
|
| -
|
| - return offset;
|
| + return LayoutSize(-toLayoutBox(o)->scrolledContentOffset());
|
| + return LayoutSize();
|
| }
|
|
|
| LayoutSize LayoutObject::offsetFromAncestorContainer(const LayoutObject* container) const
|
| @@ -2172,7 +2206,8 @@ LayoutSize LayoutObject::offsetFromAncestorContainer(const LayoutObject* contain
|
| if (!nextContainer)
|
| break;
|
| ASSERT(!currContainer->hasTransformRelatedProperty());
|
| - LayoutSize currentOffset = currContainer->offsetFromContainer(nextContainer, referencePoint);
|
| + LayoutSize currentOffset = currContainer->offsetFromContainer(nextContainer);
|
| + currentOffset += container->columnOffset(referencePoint + currentOffset);
|
| offset += currentOffset;
|
| referencePoint.move(currentOffset);
|
| currContainer = nextContainer;
|
|
|