Bug 505115 - Part 11b - Layout changes to use a z component for -moz-transform-origin. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 03 Aug 2011 15:04:23 +1200
changeset 73741 ad334152010a5d6f8f602d38a398ac7c4ec0f0c2
parent 73740 ea882f18d8ac5020db9af2bca4e7d252de2dc766
child 73742 2d3b6382054d41f104cab872860644a59cb07ed2
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersroc
bugs505115
milestone8.0a1
Bug 505115 - Part 11b - Layout changes to use a z component for -moz-transform-origin. r=roc
gfx/thebes/gfx3DMatrix.cpp
gfx/thebes/gfx3DMatrix.h
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/gfx/thebes/gfx3DMatrix.cpp
+++ b/gfx/thebes/gfx3DMatrix.cpp
@@ -143,16 +143,27 @@ gfx3DMatrix::Translation(float aX, float
 
   matrix._41 = aX;
   matrix._42 = aY;
   matrix._43 = aZ;
   return matrix;
 }
 
 gfx3DMatrix
+gfx3DMatrix::Translation(const gfxPoint3D& aPoint)
+{
+  gfx3DMatrix matrix;
+
+  matrix._41 = aPoint.x;
+  matrix._42 = aPoint.y;
+  matrix._43 = aPoint.z;
+  return matrix;
+}
+
+gfx3DMatrix
 gfx3DMatrix::Scale(float aFactor)
 {
   gfx3DMatrix matrix;
 
   matrix._11 = matrix._22 = matrix._33 = aFactor;
   return matrix;
 }
 
--- a/gfx/thebes/gfx3DMatrix.h
+++ b/gfx/thebes/gfx3DMatrix.h
@@ -148,16 +148,17 @@ public:
   /**
    * Create a translation matrix.
    *
    * \param aX Translation on X-axis.
    * \param aY Translation on Y-axis.
    * \param aZ Translation on Z-axis.
    */
   static gfx3DMatrix Translation(float aX, float aY, float aZ);
+  static gfx3DMatrix Translation(const gfxPoint3D& aPoint);
 
   /**
    * Create a scale matrix. Scales uniformly along all axes.
    *
    * \param aScale Scale factor
    */
   static gfx3DMatrix Scale(float aFactor);
 
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2293,35 +2293,35 @@ nsDisplayTransform::GetFrameBoundsForTra
 
 #endif
 
 /* Returns the delta specified by the -moz-transform-origin property.
  * This is a positive delta, meaning that it indicates the direction to move
  * to get from (0, 0) of the frame to the transform origin.
  */
 static
-gfxPoint GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
-                                      float aFactor,
-                                      const nsRect* aBoundsOverride)
+gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
+                                        float aFactor,
+                                        const nsRect* aBoundsOverride)
 {
   NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
   NS_PRECONDITION(aFrame->GetStyleDisplay()->HasTransform(),
                   "Can't get a delta for an untransformed frame!");
 
   /* For both of the coordinates, if the value of -moz-transform is a
    * percentage, it's relative to the size of the frame.  Otherwise, if it's
    * a distance, it's already computed for us!
    */
   const nsStyleDisplay* display = aFrame->GetStyleDisplay();
   nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride :
                          nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
 
   /* Allows us to access named variables by index. */
-  gfxPoint result;
-  gfxFloat* coords[2] = {&result.x, &result.y};
+  gfxPoint3D result;
+  gfxFloat* coords[3] = {&result.x, &result.y, &result.z};
   const nscoord* dimensions[2] =
     {&boundingRect.width, &boundingRect.height};
 
   for (PRUint8 index = 0; index < 2; ++index) {
     /* If the -moz-transform-origin specifies a percentage, take the percentage
      * of the size of the box.
      */
     const nsStyleCoord &coord = display->mTransformOrigin[index];
@@ -2333,16 +2333,18 @@ gfxPoint GetDeltaToMozTransformOrigin(co
     } else if (coord.GetUnit() == eStyleUnit_Percent) {
       *coords[index] = NSAppUnitsToFloatPixels(*dimensions[index], aFactor) *
         coord.GetPercentValue();
     } else {
       NS_ABORT_IF_FALSE(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
       *coords[index] = NSAppUnitsToFloatPixels(coord.GetCoordValue(), aFactor);
     }
   }
+
+  *coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(), aFactor);
   
   /* Adjust based on the origin of the rectangle. */
   result.x += NSAppUnitsToFloatPixels(boundingRect.x, aFactor);
   result.y += NSAppUnitsToFloatPixels(boundingRect.y, aFactor);
 
   return result;
 }
 
@@ -2358,19 +2360,20 @@ nsDisplayTransform::GetResultingTransfor
 {
   NS_PRECONDITION(aFrame, "Cannot get transform matrix for a null frame!");
   NS_PRECONDITION(aFrame->GetStyleDisplay()->HasTransform(),
                   "Cannot get transform matrix if frame isn't transformed!");
 
   /* Account for the -moz-transform-origin property by translating the
    * coordinate space to the new origin.
    */
-  gfxPoint toMozOrigin = GetDeltaToMozTransformOrigin(aFrame, aFactor, aBoundsOverride);
-  gfxPoint newOrigin = gfxPoint(NSAppUnitsToFloatPixels(aOrigin.x, aFactor),
-                                NSAppUnitsToFloatPixels(aOrigin.y, aFactor));
+  gfxPoint3D toMozOrigin = GetDeltaToMozTransformOrigin(aFrame, aFactor, aBoundsOverride);
+  gfxPoint3D newOrigin = gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aFactor),
+                                    NSAppUnitsToFloatPixels(aOrigin.y, aFactor),
+                                    0.0f);
 
   /* Get the underlying transform matrix.  This requires us to get the
    * bounds of the frame.
    */
   const nsStyleDisplay* disp = aFrame->GetStyleDisplay();
   nsRect bounds = (aBoundsOverride ? *aBoundsOverride :
                    nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -997,26 +997,24 @@ nsLayoutUtils::GetPopupFrameForEventCoor
       return popup;
     }
   }
 #endif
   return nsnull;
 }
 
 gfx3DMatrix
-nsLayoutUtils::ChangeMatrixBasis(const gfxPoint &aOrigin,
+nsLayoutUtils::ChangeMatrixBasis(const gfxPoint3D &aOrigin,
                                  const gfx3DMatrix &aMatrix)
 {
   /* These are translation matrices from world-to-origin of relative frame and
-   * vice-versa.  Although I could use the gfxMatrix::Translate function to
-   * accomplish this, I'm hoping to reduce the overall number of matrix
-   * operations by hardcoding as many of the matrices as possible.
+   * vice-versa.
    */
-  gfx3DMatrix worldToOrigin = gfx3DMatrix::From2D(gfxMatrix(1.0, 0.0, 0.0, 1.0, -aOrigin.x, -aOrigin.y));
-  gfx3DMatrix originToWorld = gfx3DMatrix::From2D(gfxMatrix(1.0, 0.0, 0.0, 1.0,  aOrigin.x,  aOrigin.y));
+  gfx3DMatrix worldToOrigin = gfx3DMatrix::Translation(-aOrigin);
+  gfx3DMatrix originToWorld = gfx3DMatrix::Translation(aOrigin);
 
   /* Multiply all three to get the transform! */
   return worldToOrigin * aMatrix * originToWorld;
 }
 
 /**
  * Given a gfxFloat, constrains its value to be between nscoord_MIN and nscoord_MAX.
  *
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -456,17 +456,17 @@ public:
    * that's equivalent to aMatrix but in the coordinate space that treats aOrigin
    * as the origin.
    *
    * @param aOrigin The origin to translate to.
    * @param aMatrix The matrix to change the basis of.
    * @return A matrix equivalent to aMatrix, but operating in the coordinate system with
    *         origin aOrigin.
    */
-  static gfx3DMatrix ChangeMatrixBasis(const gfxPoint &aOrigin, const gfx3DMatrix &aMatrix);
+  static gfx3DMatrix ChangeMatrixBasis(const gfxPoint3D &aOrigin, const gfx3DMatrix &aMatrix);
 
   /**
    * Find IDs corresponding to a scrollable content element in the child process.
    * In correspondence with the shadow layer tree, you can use this to perform a
    * hit test that corresponds to a specific shadow layer that you can then perform
    * transformations on to do parent-side scrolling.
    *
    * @param aFrame The root frame of a stack context