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