mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1521579 - Only transform one bounding rect for text nodes when computing scroll anchoring bounding rect. r=dholbert
When visiting a text frame with many continuations, traversing ancestors to compute the transform to the ancestor scroll frame can become very hot. This commit changes the algorithm to translate all the text continuations to an ancestor that can then be transformed just once. Differential Revision: https://phabricator.services.mozilla.com/D17730 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
092461a72f
commit
585289697d
@ -98,16 +98,38 @@ static nsRect FindScrollAnchoringBoundingRect(const nsIFrame* aScrollFrame,
|
||||
nsIFrame* aCandidate) {
|
||||
MOZ_ASSERT(nsLayoutUtils::IsProperAncestorFrame(aScrollFrame, aCandidate));
|
||||
if (!!Text::FromNodeOrNull(aCandidate->GetContent())) {
|
||||
// This is a frame for a text node. The spec says we need to accumulate the
|
||||
// union of all line boxes in the coordinate space of the scroll frame
|
||||
// accounting for transforms.
|
||||
//
|
||||
// To do this, we translate and accumulate the overflow rect for each text
|
||||
// continuation to the coordinate space of the nearest ancestor block
|
||||
// frame. Then we transform the resulting rect into the coordinate space of
|
||||
// the scroll frame.
|
||||
//
|
||||
// Transforms aren't allowed on non-replaced inline boxes, so we can assume
|
||||
// that these text node continuations will have the same transform as their
|
||||
// nearest block ancestor. And it should be faster to transform their union
|
||||
// rather than individually transforming each overflow rect
|
||||
//
|
||||
// XXX for fragmented blocks, blockAncestor will be an ancestor only to the
|
||||
// text continuations in the first block continuation. GetOffsetTo
|
||||
// should continue to work, but is it correct with transforms or a
|
||||
// performance hazard?
|
||||
nsIFrame* blockAncestor =
|
||||
nsLayoutUtils::FindNearestBlockAncestor(aCandidate);
|
||||
MOZ_ASSERT(
|
||||
nsLayoutUtils::IsProperAncestorFrame(aScrollFrame, blockAncestor));
|
||||
nsRect bounding;
|
||||
for (nsIFrame* continuation = aCandidate->FirstContinuation(); continuation;
|
||||
continuation = continuation->GetNextContinuation()) {
|
||||
nsRect overflowRect =
|
||||
continuation->GetScrollableOverflowRectRelativeToSelf();
|
||||
nsRect transformed = nsLayoutUtils::TransformFrameRectToAncestor(
|
||||
continuation, overflowRect, aScrollFrame);
|
||||
bounding = bounding.Union(transformed);
|
||||
overflowRect += continuation->GetOffsetTo(blockAncestor);
|
||||
bounding = bounding.Union(overflowRect);
|
||||
}
|
||||
return bounding;
|
||||
return nsLayoutUtils::TransformFrameRectToAncestor(blockAncestor, bounding,
|
||||
aScrollFrame);
|
||||
}
|
||||
|
||||
nsRect borderRect = aCandidate->GetRectRelativeToSelf();
|
||||
|
Loading…
Reference in New Issue
Block a user