Bug 952011 - Add gfx3DMatrix API for untransformed rects and points. r=bjacob

This commit is contained in:
Matt Woodrow 2014-02-04 12:25:22 +13:00
parent d9d558f8f0
commit 2587a356d2
2 changed files with 50 additions and 4 deletions

View File

@ -788,10 +788,9 @@ gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
gfxPoint points[4];
points[0] = ProjectPoint(aRect.TopLeft());
points[1] = ProjectPoint(gfxPoint(aRect.X() + aRect.Width(), aRect.Y()));
points[2] = ProjectPoint(gfxPoint(aRect.X(), aRect.Y() + aRect.Height()));
points[3] = ProjectPoint(gfxPoint(aRect.X() + aRect.Width(),
aRect.Y() + aRect.Height()));
points[1] = ProjectPoint(aRect.TopRight());
points[2] = ProjectPoint(aRect.BottomLeft());
points[3] = ProjectPoint(aRect.BottomRight());
gfxFloat min_x, max_x;
gfxFloat min_y, max_y;
@ -809,6 +808,34 @@ gfxRect gfx3DMatrix::ProjectRectBounds(const gfxRect& aRect) const
return gfxRect(min_x, min_y, max_x - min_x, max_y - min_y);
}
gfxRect gfx3DMatrix::UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const
{
if (Is2D()) {
return Inverse().TransformBounds(aRect);
}
gfxRect bounds = TransformBounds(aChildBounds);
gfxRect rect = aRect.Intersect(bounds);
return Inverse().ProjectRectBounds(rect);
}
bool gfx3DMatrix::UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const
{
if (Is2D()) {
*aOut = Inverse().Transform(aPoint);
return true;
}
gfxRect bounds = TransformBounds(aChildBounds);
if (!bounds.Contains(aPoint)) {
return false;
}
*aOut = Inverse().ProjectPoint(aPoint);
return true;
}
gfxPoint3D gfx3DMatrix::GetNormalVector() const
{
// Define a plane in transformed space as the transformations

View File

@ -250,6 +250,25 @@ public:
gfxPoint ProjectPoint(const gfxPoint& aPoint) const;
gfxRect ProjectRectBounds(const gfxRect& aRect) const;
/**
* Transforms a point by the inverse of this matrix. In the case of perspective transforms, some screen
* points have no equivalent in the untransformed plane (if they exist past the vanishing point). To
* avoid this, we need to specify the bounds of the untransformed plane to restrict the search area.
*
* @param aPoint Point to untransform.
* @param aChildBounds Bounds of the untransformed plane.
* @param aOut Untransformed point.
* @return Returns true if a point was found within a ChildBounds, false otherwise.
*/
bool UntransformPoint(const gfxPoint& aPoint, const gfxRect& aChildBounds, gfxPoint* aOut) const;
/**
* Same as UntransformPoint, but untransforms a rect and returns the bounding rect of the result.
* Returns an empty rect if the result doesn't intersect aChildBounds.
*/
gfxRect UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const;
/**
* Inverts this matrix, if possible. Otherwise, the matrix is left