зеркало из https://github.com/mozilla/pjs.git
Bug 591718. Part 1: rename some poorly-named methods, rework global-transform methods to avoid computing bounding-boxes more than once when there are are multiple transformed ancestors, make sure nsIFrame::GetTransformMatrix can stop at any desired ancestor. r=mats
This commit is contained in:
Родитель
bd40ce4849
Коммит
fda2a403ee
|
@ -460,7 +460,7 @@ GetDisplayPortBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
|
|||
}
|
||||
|
||||
const nsRect* displayport = aBuilder->GetDisplayPort();
|
||||
nsRect result = nsLayoutUtils::TransformRectToBoundsInAncestor(
|
||||
nsRect result = nsLayoutUtils::TransformAncestorRectToFrame(
|
||||
frame,
|
||||
nsRect(0, 0, displayport->width, displayport->height),
|
||||
aBuilder->ReferenceFrame());
|
||||
|
|
|
@ -975,7 +975,7 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(const nsEvent* aEvent, nsIFrame* aF
|
|||
* out how to convert back to aFrame's coordinates and must use the CTM.
|
||||
*/
|
||||
if (transformFound)
|
||||
return InvertTransformsToRoot(aFrame, widgetToView);
|
||||
return TransformRootPointToFrame(aFrame, widgetToView);
|
||||
|
||||
/* Otherwise, all coordinate systems are translations of one another,
|
||||
* so we can just subtract out the different.
|
||||
|
@ -1117,68 +1117,62 @@ nsLayoutUtils::MatrixTransformPoint(const nsPoint &aPoint,
|
|||
NSFloatPixelsToAppUnits(float(image.y), aFactor));
|
||||
}
|
||||
|
||||
static gfxPoint
|
||||
InvertTransformsToAncestor(nsIFrame *aFrame,
|
||||
const gfxPoint &aPoint,
|
||||
nsIFrame *aStopAtAncestor = nsnull)
|
||||
static gfx3DMatrix
|
||||
GetTransformToAncestor(nsIFrame *aFrame, nsIFrame *aAncestor)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Why are you inverting transforms when there is no frame?");
|
||||
|
||||
/* To invert everything to the root, we'll get the CTM, invert it, and use it to transform
|
||||
* the point.
|
||||
*/
|
||||
nsIFrame *parent = nsnull;
|
||||
gfx3DMatrix ctm = aFrame->GetTransformMatrix(&parent);
|
||||
gfxPoint result = aPoint;
|
||||
|
||||
if (parent && parent != aStopAtAncestor) {
|
||||
result = InvertTransformsToAncestor(parent, aPoint, aStopAtAncestor);
|
||||
nsIFrame* parent;
|
||||
gfx3DMatrix ctm = aFrame->GetTransformMatrix(aAncestor, &parent);
|
||||
while (parent && parent != aAncestor) {
|
||||
ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent);
|
||||
}
|
||||
return ctm;
|
||||
}
|
||||
|
||||
result = ctm.Inverse().ProjectPoint(result);
|
||||
return result;
|
||||
static gfxPoint
|
||||
TransformGfxPointFromAncestor(nsIFrame *aFrame,
|
||||
const gfxPoint &aPoint,
|
||||
nsIFrame *aAncestor)
|
||||
{
|
||||
gfx3DMatrix ctm = GetTransformToAncestor(aFrame, aAncestor);
|
||||
return ctm.Inverse().ProjectPoint(aPoint);
|
||||
}
|
||||
|
||||
static gfxRect
|
||||
InvertGfxRectToAncestor(nsIFrame *aFrame,
|
||||
const gfxRect &aRect,
|
||||
nsIFrame *aStopAtAncestor = nsnull)
|
||||
TransformGfxRectFromAncestor(nsIFrame *aFrame,
|
||||
const gfxRect &aRect,
|
||||
nsIFrame *aAncestor)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Why are you inverting transforms when there is no frame?");
|
||||
gfx3DMatrix ctm = GetTransformToAncestor(aFrame, aAncestor);
|
||||
return ctm.Inverse().ProjectRectBounds(aRect);
|
||||
}
|
||||
|
||||
/* To invert everything to the root, we'll get the CTM, invert it, and use it to transform
|
||||
* the point.
|
||||
*/
|
||||
nsIFrame *parent = nsnull;
|
||||
gfx3DMatrix ctm = aFrame->GetTransformMatrix(&parent);
|
||||
gfxRect result = aRect;
|
||||
|
||||
if (parent && parent != aStopAtAncestor) {
|
||||
result = InvertGfxRectToAncestor(parent, aRect, aStopAtAncestor);
|
||||
}
|
||||
|
||||
result = ctm.Inverse().ProjectRectBounds(result);
|
||||
return result;
|
||||
static gfxRect
|
||||
TransformGfxRectToAncestor(nsIFrame *aFrame,
|
||||
const gfxRect &aRect,
|
||||
nsIFrame *aAncestor)
|
||||
{
|
||||
gfx3DMatrix ctm = GetTransformToAncestor(aFrame, aAncestor);
|
||||
return ctm.ProjectRectBounds(aRect);
|
||||
}
|
||||
|
||||
nsPoint
|
||||
nsLayoutUtils::InvertTransformsToRoot(nsIFrame *aFrame,
|
||||
const nsPoint &aPoint)
|
||||
nsLayoutUtils::TransformRootPointToFrame(nsIFrame *aFrame,
|
||||
const nsPoint &aPoint)
|
||||
{
|
||||
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
gfxPoint result(NSAppUnitsToFloatPixels(aPoint.x, factor),
|
||||
NSAppUnitsToFloatPixels(aPoint.y, factor));
|
||||
|
||||
result = InvertTransformsToAncestor(aFrame, result);
|
||||
result = TransformGfxPointFromAncestor(aFrame, result, nsnull);
|
||||
|
||||
return nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
|
||||
NSFloatPixelsToAppUnits(float(result.y), factor));
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsLayoutUtils::TransformRectToBoundsInAncestor(nsIFrame* aFrame,
|
||||
const nsRect &aRect,
|
||||
nsIFrame* aStopAtAncestor)
|
||||
nsLayoutUtils::TransformAncestorRectToFrame(nsIFrame* aFrame,
|
||||
const nsRect &aRect,
|
||||
nsIFrame* aAncestor)
|
||||
{
|
||||
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
gfxRect result(NSAppUnitsToFloatPixels(aRect.x, factor),
|
||||
|
@ -1186,7 +1180,7 @@ nsLayoutUtils::TransformRectToBoundsInAncestor(nsIFrame* aFrame,
|
|||
NSAppUnitsToFloatPixels(aRect.width, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.height, factor));
|
||||
|
||||
result = InvertGfxRectToAncestor(aFrame, result, aStopAtAncestor);
|
||||
result = TransformGfxRectFromAncestor(aFrame, result, aAncestor);
|
||||
|
||||
return nsRect(NSFloatPixelsToAppUnits(float(result.x), factor),
|
||||
NSFloatPixelsToAppUnits(float(result.y), factor),
|
||||
|
@ -1194,6 +1188,25 @@ nsLayoutUtils::TransformRectToBoundsInAncestor(nsIFrame* aFrame,
|
|||
NSFloatPixelsToAppUnits(float(result.height), factor));
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
|
||||
const nsRect& aRect,
|
||||
nsIFrame* aAncestor)
|
||||
{
|
||||
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
gfxRect result(NSAppUnitsToFloatPixels(aRect.x, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.y, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.width, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.height, factor));
|
||||
|
||||
result = TransformGfxRectToAncestor(aFrame, result, aAncestor);
|
||||
|
||||
return nsRect(NSFloatPixelsToAppUnits(float(result.x), factor),
|
||||
NSFloatPixelsToAppUnits(float(result.y), factor),
|
||||
NSFloatPixelsToAppUnits(float(result.width), factor),
|
||||
NSFloatPixelsToAppUnits(float(result.height), factor));
|
||||
}
|
||||
|
||||
static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) {
|
||||
nsIntPoint offset(0, 0);
|
||||
nsIWidget* parent = aWidget->GetParent();
|
||||
|
|
|
@ -515,11 +515,21 @@ public:
|
|||
bool aShouldIgnoreSuppression = false,
|
||||
bool aIgnoreRootScrollFrame = false);
|
||||
|
||||
/**
|
||||
* Transform aRect relative to aAncestor down to the coordinate system of
|
||||
* aFrame. Computes the bounding-box of the true quadrilateral.
|
||||
*/
|
||||
static nsRect TransformAncestorRectToFrame(nsIFrame* aFrame,
|
||||
const nsRect& aRect,
|
||||
nsIFrame* aAncestor);
|
||||
|
||||
|
||||
static nsRect TransformRectToBoundsInAncestor(nsIFrame* aFrame,
|
||||
const nsRect& aRect,
|
||||
nsIFrame* aStopAtAncestor);
|
||||
/**
|
||||
* Transform aRect relative to aFrame up to the coordinate system of
|
||||
* aAncestor. Computes the bounding-box of the true quadrilateral.
|
||||
*/
|
||||
static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame,
|
||||
const nsRect& aRect,
|
||||
nsIFrame* aAncestor);
|
||||
|
||||
/**
|
||||
* Given a point in the global coordinate space, returns that point expressed
|
||||
|
@ -530,8 +540,8 @@ public:
|
|||
* @param aPoint The point, in the global space, to get in the frame-local space.
|
||||
* @return aPoint, expressed in aFrame's canonical coordinate space.
|
||||
*/
|
||||
static nsPoint InvertTransformsToRoot(nsIFrame* aFrame,
|
||||
const nsPoint &aPt);
|
||||
static nsPoint TransformRootPointToFrame(nsIFrame* aFrame,
|
||||
const nsPoint &aPt);
|
||||
|
||||
/**
|
||||
* Helper function that, given a rectangle and a matrix, returns the smallest
|
||||
|
|
|
@ -550,8 +550,8 @@ nsComboboxControlFrame::GetCSSTransformTranslation()
|
|||
bool is3DTransform = false;
|
||||
gfxMatrix transform;
|
||||
while (frame) {
|
||||
nsIFrame* parent = nsnull;
|
||||
gfx3DMatrix ctm = frame->GetTransformMatrix(&parent);
|
||||
nsIFrame* parent;
|
||||
gfx3DMatrix ctm = frame->GetTransformMatrix(nsnull, &parent);
|
||||
gfxMatrix matrix;
|
||||
if (ctm.Is2D(&matrix)) {
|
||||
transform = transform * matrix;
|
||||
|
|
|
@ -4541,7 +4541,8 @@ nsIFrame::InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY,
|
|||
}
|
||||
|
||||
gfx3DMatrix
|
||||
nsIFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
|
||||
nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
||||
nsIFrame** aOutAncestor)
|
||||
{
|
||||
NS_PRECONDITION(aOutAncestor, "Need a place to put the ancestor!");
|
||||
|
||||
|
@ -4553,7 +4554,8 @@ nsIFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
|
|||
/* Compute the delta to the parent, which we need because we are converting
|
||||
* coordinates to our parent.
|
||||
*/
|
||||
NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this), "Cannot transform the viewport frame!");
|
||||
NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this),
|
||||
"Cannot transform the viewport frame!");
|
||||
PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
gfx3DMatrix result =
|
||||
|
@ -4582,7 +4584,7 @@ nsIFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
|
|||
return gfx3DMatrix();
|
||||
|
||||
/* Keep iterating while the frame can't possibly be transformed. */
|
||||
while (!(*aOutAncestor)->IsTransformed()) {
|
||||
while (!(*aOutAncestor)->IsTransformed() && *aOutAncestor != aStopAtAncestor) {
|
||||
/* If no parent, stop iterating. Otherwise, update the ancestor. */
|
||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(*aOutAncestor);
|
||||
if (!parent)
|
||||
|
|
|
@ -1932,17 +1932,20 @@ public:
|
|||
virtual nsIAtom* GetType() const = 0;
|
||||
|
||||
/**
|
||||
* Returns a transformation matrix that converts points in this frame's coordinate space
|
||||
* to points in some ancestor frame's coordinate space. The frame decides which ancestor
|
||||
* it will use as a reference point. If this frame has no ancestor, aOutAncestor will be
|
||||
* set to null.
|
||||
* Returns a transformation matrix that converts points in this frame's
|
||||
* coordinate space to points in some ancestor frame's coordinate space.
|
||||
* The frame decides which ancestor it will use as a reference point.
|
||||
* If this frame has no ancestor, aOutAncestor will be set to null.
|
||||
*
|
||||
* @param aOutAncestor [out] The ancestor frame the frame has chosen. If this frame has no
|
||||
* ancestor, aOutAncestor will be nsnull.
|
||||
* @return A gfxMatrix that converts points in this frame's coordinate space into
|
||||
* points in aOutAncestor's coordinate space.
|
||||
* @param aStopAtAncestor don't look further than aStopAtAncestor. If null,
|
||||
* all ancestors (including across documents) will be traversed.
|
||||
* @param aOutAncestor [out] The ancestor frame the frame has chosen. If
|
||||
* this frame has no ancestor, *aOutAncestor will be set to null.
|
||||
* @return A gfxMatrix that converts points in this frame's coordinate space
|
||||
* into points in aOutAncestor's coordinate space.
|
||||
*/
|
||||
virtual gfx3DMatrix GetTransformMatrix(nsIFrame **aOutAncestor);
|
||||
virtual gfx3DMatrix GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
||||
nsIFrame **aOutAncestor);
|
||||
|
||||
/**
|
||||
* Bit-flags to pass to IsFrameOfType()
|
||||
|
|
|
@ -283,7 +283,8 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext,
|
|||
}
|
||||
|
||||
gfx3DMatrix
|
||||
nsSVGForeignObjectFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
|
||||
nsSVGForeignObjectFrame::GetTransformMatrix(nsIFrame* aAncestor,
|
||||
nsIFrame **aOutAncestor)
|
||||
{
|
||||
NS_PRECONDITION(aOutAncestor, "We need an ancestor to write to!");
|
||||
|
||||
|
|
|
@ -93,7 +93,8 @@ public:
|
|||
/**
|
||||
* Foreign objects can return a transform matrix.
|
||||
*/
|
||||
virtual gfx3DMatrix GetTransformMatrix(nsIFrame **aOutAncestor);
|
||||
virtual gfx3DMatrix GetTransformMatrix(nsIFrame* aAncestor,
|
||||
nsIFrame **aOutAncestor);
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
|
|
Загрузка…
Ссылка в новой задаче