mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Part 20 - Add more gfx3DMatrix transformation function and use these in nsStyleTransformMatrix. r=derf
This commit is contained in:
parent
fbf0bfdb94
commit
77eeddfb4e
@ -42,6 +42,40 @@
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
/* Force small values to zero. We do this to avoid having sin(360deg)
|
||||
* evaluate to a tiny but nonzero value.
|
||||
*/
|
||||
static double FlushToZero(double aVal)
|
||||
{
|
||||
if (-FLT_EPSILON < aVal && aVal < FLT_EPSILON)
|
||||
return 0.0f;
|
||||
else
|
||||
return aVal;
|
||||
}
|
||||
|
||||
/* Computes tan(aTheta). For values of aTheta such that tan(aTheta) is
|
||||
* undefined or very large, SafeTangent returns a manageably large value
|
||||
* of the correct sign.
|
||||
*/
|
||||
static double SafeTangent(double aTheta)
|
||||
{
|
||||
const double kEpsilon = 0.0001;
|
||||
|
||||
/* tan(theta) = sin(theta)/cos(theta); problems arise when
|
||||
* cos(theta) is too close to zero. Limit cos(theta) to the
|
||||
* range [-1, -epsilon] U [epsilon, 1].
|
||||
*/
|
||||
double sinTheta = sin(aTheta);
|
||||
double cosTheta = cos(aTheta);
|
||||
|
||||
if (cosTheta >= 0 && cosTheta < kEpsilon)
|
||||
cosTheta = kEpsilon;
|
||||
else if (cosTheta < 0 && cosTheta >= -kEpsilon)
|
||||
cosTheta = -kEpsilon;
|
||||
|
||||
return FlushToZero(sinTheta / cosTheta);
|
||||
}
|
||||
|
||||
gfx3DMatrix::gfx3DMatrix(void)
|
||||
{
|
||||
_11 = _22 = _33 = _44 = 1.0f;
|
||||
@ -182,19 +216,19 @@ gfx3DMatrix::TranslatePost(const gfxPoint3D& aPoint)
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::SkewXY(float aSkew)
|
||||
gfx3DMatrix::SkewXY(double aSkew)
|
||||
{
|
||||
(*this)[1] += (*this)[0] * aSkew;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::SkewXZ(float aSkew)
|
||||
gfx3DMatrix::SkewXZ(double aSkew)
|
||||
{
|
||||
(*this)[2] += (*this)[0] * aSkew;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::SkewYZ(float aSkew)
|
||||
gfx3DMatrix::SkewYZ(double aSkew)
|
||||
{
|
||||
(*this)[2] += (*this)[1] * aSkew;
|
||||
}
|
||||
@ -207,6 +241,144 @@ gfx3DMatrix::Scale(float aX, float aY, float aZ)
|
||||
(*this)[2] *= aZ;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::Perspective(float aDepth)
|
||||
{
|
||||
NS_ASSERTION(aDepth > 0.0f, "Perspective must be positive!");
|
||||
_31 += -1.0/aDepth * _41;
|
||||
_32 += -1.0/aDepth * _42;
|
||||
_33 += -1.0/aDepth * _43;
|
||||
_34 += -1.0/aDepth * _44;
|
||||
}
|
||||
|
||||
void gfx3DMatrix::SkewXY(double aXSkew, double aYSkew)
|
||||
{
|
||||
float tanX = SafeTangent(aXSkew);
|
||||
float tanY = SafeTangent(aYSkew);
|
||||
float temp;
|
||||
|
||||
temp = _11;
|
||||
_11 += tanY * _21;
|
||||
_21 += tanX * temp;
|
||||
|
||||
temp = _12;
|
||||
_12 += tanY * _22;
|
||||
_22 += tanX * temp;
|
||||
|
||||
temp = _13;
|
||||
_13 += tanY * _23;
|
||||
_23 += tanX * temp;
|
||||
|
||||
temp = _14;
|
||||
_14 += tanY * _24;
|
||||
_24 += tanX * temp;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::RotateX(double aTheta)
|
||||
{
|
||||
double cosTheta = FlushToZero(cos(aTheta));
|
||||
double sinTheta = FlushToZero(sin(aTheta));
|
||||
|
||||
float temp;
|
||||
|
||||
temp = _21;
|
||||
_21 = cosTheta * _21 + sinTheta * _31;
|
||||
_31 = -sinTheta * temp + cosTheta * _31;
|
||||
|
||||
temp = _22;
|
||||
_22 = cosTheta * _22 + sinTheta * _32;
|
||||
_32 = -sinTheta * temp + cosTheta * _32;
|
||||
|
||||
temp = _23;
|
||||
_23 = cosTheta * _23 + sinTheta * _33;
|
||||
_33 = -sinTheta * temp + cosTheta * _33;
|
||||
|
||||
temp = _24;
|
||||
_24 = cosTheta * _24 + sinTheta * _34;
|
||||
_34 = -sinTheta * temp + cosTheta * _34;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::RotateY(double aTheta)
|
||||
{
|
||||
double cosTheta = FlushToZero(cos(aTheta));
|
||||
double sinTheta = FlushToZero(sin(aTheta));
|
||||
|
||||
float temp;
|
||||
|
||||
temp = _11;
|
||||
_11 = cosTheta * _11 + -sinTheta * _31;
|
||||
_31 = sinTheta * temp + cosTheta * _31;
|
||||
|
||||
temp = _12;
|
||||
_12 = cosTheta * _12 + -sinTheta * _32;
|
||||
_32 = sinTheta * temp + cosTheta * _32;
|
||||
|
||||
temp = _13;
|
||||
_13 = cosTheta * _13 + -sinTheta * _33;
|
||||
_33 = sinTheta * temp + cosTheta * _33;
|
||||
|
||||
temp = _14;
|
||||
_14 = cosTheta * _14 + -sinTheta * _34;
|
||||
_34 = sinTheta * temp + cosTheta * _34;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::RotateZ(double aTheta)
|
||||
{
|
||||
double cosTheta = FlushToZero(cos(aTheta));
|
||||
double sinTheta = FlushToZero(sin(aTheta));
|
||||
|
||||
float temp;
|
||||
|
||||
temp = _11;
|
||||
_11 = cosTheta * _11 + sinTheta * _21;
|
||||
_21 = -sinTheta * temp + cosTheta * _21;
|
||||
|
||||
temp = _12;
|
||||
_12 = cosTheta * _12 + sinTheta * _22;
|
||||
_22 = -sinTheta * temp + cosTheta * _22;
|
||||
|
||||
temp = _13;
|
||||
_13 = cosTheta * _13 + sinTheta * _23;
|
||||
_23 = -sinTheta * temp + cosTheta * _23;
|
||||
|
||||
temp = _14;
|
||||
_14 = cosTheta * _14 + sinTheta * _24;
|
||||
_24 = -sinTheta * temp + cosTheta * _24;
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::PreMultiply(const gfx3DMatrix& aOther)
|
||||
{
|
||||
*this = aOther * (*this);
|
||||
}
|
||||
|
||||
void
|
||||
gfx3DMatrix::PreMultiply(const gfxMatrix& aOther)
|
||||
{
|
||||
gfx3DMatrix temp;
|
||||
temp._11 = aOther.xx * _11 + aOther.yx * _21;
|
||||
temp._21 = aOther.xy * _11 + aOther.yy * _21;
|
||||
temp._31 = _31;
|
||||
temp._41 = aOther.x0 * _11 + aOther.y0 * _21 + _41;
|
||||
temp._12 = aOther.xx * _12 + aOther.yx * _22;
|
||||
temp._22 = aOther.xy * _12 + aOther.yy * _22;
|
||||
temp._32 = _32;
|
||||
temp._42 = aOther.x0 * _12 + aOther.y0 * _22 + _42;
|
||||
temp._13 = aOther.xx * _13 + aOther.yx * _23;
|
||||
temp._23 = aOther.xy * _13 + aOther.yy * _23;
|
||||
temp._33 = _33;
|
||||
temp._43 = aOther.x0 * _13 + aOther.y0 * _23 + _43;
|
||||
temp._14 = aOther.xx * _14 + aOther.yx * _24;
|
||||
temp._24 = aOther.xy * _14 + aOther.yy * _24;
|
||||
temp._34 = _34;
|
||||
temp._44 = aOther.x0 * _14 + aOther.y0 * _24 + _44;
|
||||
|
||||
*this = temp;
|
||||
}
|
||||
|
||||
gfx3DMatrix
|
||||
gfx3DMatrix::Translation(float aX, float aY, float aZ)
|
||||
{
|
||||
|
@ -126,26 +126,117 @@ public:
|
||||
*/
|
||||
PRBool IsIdentity() const;
|
||||
|
||||
/**
|
||||
* Pre-multiplication transformation functions:
|
||||
*
|
||||
* These functions construct a temporary matrix containing
|
||||
* a single transformation and pre-multiply it onto the current
|
||||
* matrix.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a translation by aPoint to the matrix.
|
||||
* This is functionally equivalent to:
|
||||
* gfx3DMatrix::Translation(aPoint) * matrix
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | 1 0 0 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | aPoint.x aPoint.y aPoint.z 1 |
|
||||
*/
|
||||
void Translate(const gfxPoint3D& aPoint);
|
||||
|
||||
/**
|
||||
* Skew the matrix.
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | 1 tan(aYSkew) 0 0 |
|
||||
* | tan(aXSkew) 1 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
void SkewXY(double aXSkew, double aYSkew);
|
||||
|
||||
void SkewXY(double aSkew);
|
||||
void SkewXZ(double aSkew);
|
||||
void SkewYZ(double aSkew);
|
||||
|
||||
/**
|
||||
* Scale the matrix
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | aX 0 0 0 |
|
||||
* | 0 aY 0 0 |
|
||||
* | 0 0 aZ 0 |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
void Scale(float aX, float aY, float aZ);
|
||||
|
||||
/**
|
||||
* Rotate around the X axis..
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | 1 0 0 0 |
|
||||
* | 0 cos(aTheta) sin(aTheta) 0 |
|
||||
* | 0 -sin(aTheta) cos(aTheta) 0 |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
void RotateX(double aTheta);
|
||||
|
||||
/**
|
||||
* Rotate around the Y axis..
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | cos(aTheta) 0 -sin(aTheta) 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | sin(aTheta) 0 cos(aTheta) 0 |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
void RotateY(double aTheta);
|
||||
|
||||
/**
|
||||
* Rotate around the Z axis..
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | cos(aTheta) sin(aTheta) 0 0 |
|
||||
* | -sin(aTheta) cos(aTheta) 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
void RotateZ(double aTheta);
|
||||
|
||||
/**
|
||||
* Apply perspective to the matrix.
|
||||
*
|
||||
* This creates this temporary matrix:
|
||||
* | 1 0 0 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | 0 0 1 -1/aDepth |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
void Perspective(float aDepth);
|
||||
|
||||
/**
|
||||
* Pre multiply an existing matrix onto the current
|
||||
* matrix
|
||||
*/
|
||||
void PreMultiply(const gfx3DMatrix& aOther);
|
||||
void PreMultiply(const gfxMatrix& aOther);
|
||||
|
||||
/**
|
||||
* Post-multiplication transformation functions:
|
||||
*
|
||||
* These functions construct a temporary matrix containing
|
||||
* a single transformation and post-multiply it onto the current
|
||||
* matrix.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add a translation by aPoint after the matrix.
|
||||
* This is functionally equivalent to:
|
||||
* matrix *gfx3DMatrix::Translation(aPoint)
|
||||
* matrix * gfx3DMatrix::Translation(aPoint)
|
||||
*/
|
||||
void TranslatePost(const gfxPoint3D& aPoint);
|
||||
|
||||
void SkewXY(float aSkew);
|
||||
void SkewXZ(float aSkew);
|
||||
void SkewYZ(float aSkew);
|
||||
|
||||
void Scale(float aX, float aY, float aZ);
|
||||
|
||||
/**
|
||||
* Transforms a point according to this matrix.
|
||||
*/
|
||||
|
@ -52,6 +52,8 @@
|
||||
|
||||
namespace css = mozilla::css;
|
||||
|
||||
namespace nsStyleTransformMatrix {
|
||||
|
||||
/* Note on floating point precision: The transform matrix is an array
|
||||
* of single precision 'float's, and so are most of the input values
|
||||
* we get from the style system, but intermediate calculations
|
||||
@ -69,29 +71,6 @@ static double FlushToZero(double aVal)
|
||||
return aVal;
|
||||
}
|
||||
|
||||
/* Computes tan(aTheta). For values of aTheta such that tan(aTheta) is
|
||||
* undefined or very large, SafeTangent returns a manageably large value
|
||||
* of the correct sign.
|
||||
*/
|
||||
static double SafeTangent(double aTheta)
|
||||
{
|
||||
const double kEpsilon = 0.0001;
|
||||
|
||||
/* tan(theta) = sin(theta)/cos(theta); problems arise when
|
||||
* cos(theta) is too close to zero. Limit cos(theta) to the
|
||||
* range [-1, -epsilon] U [epsilon, 1].
|
||||
*/
|
||||
double sinTheta = sin(aTheta);
|
||||
double cosTheta = cos(aTheta);
|
||||
|
||||
if (cosTheta >= 0 && cosTheta < kEpsilon)
|
||||
cosTheta = kEpsilon;
|
||||
else if (cosTheta < 0 && cosTheta >= -kEpsilon)
|
||||
cosTheta = -kEpsilon;
|
||||
|
||||
return FlushToZero(sinTheta / cosTheta);
|
||||
}
|
||||
|
||||
/* Helper function to fill in an nscoord with the specified nsCSSValue. */
|
||||
static nscoord CalcLength(const nsCSSValue &aValue,
|
||||
nsStyleContext* aContext,
|
||||
@ -113,9 +92,8 @@ static nscoord CalcLength(const nsCSSValue &aValue,
|
||||
aCanStoreInRuleTree);
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessTranslatePart(float& aResult,
|
||||
const nsCSSValue& aValue,
|
||||
static float
|
||||
ProcessTranslatePart(const nsCSSValue& aValue,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
@ -137,51 +115,57 @@ ProcessTranslatePart(float& aResult,
|
||||
aCanStoreInRuleTree);
|
||||
}
|
||||
|
||||
aResult = (percent * NSAppUnitsToFloatPixels(aSize, aAppUnitsPerMatrixUnit)) +
|
||||
NSAppUnitsToFloatPixels(offset, aAppUnitsPerMatrixUnit);
|
||||
return (percent * NSAppUnitsToFloatPixels(aSize, aAppUnitsPerMatrixUnit)) +
|
||||
NSAppUnitsToFloatPixels(offset, aAppUnitsPerMatrixUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper functions to process all the transformation function types.
|
||||
*
|
||||
* These take a matrix parameter to accumulate the current matrix.
|
||||
*/
|
||||
|
||||
/* Helper function to process a matrix entry. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessMatrix(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit,
|
||||
PRBool *aPercentX, PRBool *aPercentY)
|
||||
static void
|
||||
ProcessMatrix(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 7, "Invalid array!");
|
||||
|
||||
gfx3DMatrix result;
|
||||
gfxMatrix result;
|
||||
|
||||
/* Take the first four elements out of the array as floats and store
|
||||
* them.
|
||||
*/
|
||||
result._11 = aData->Item(1).GetFloatValue();
|
||||
result._12 = aData->Item(2).GetFloatValue();
|
||||
result._21 = aData->Item(3).GetFloatValue();
|
||||
result._22 = aData->Item(4).GetFloatValue();
|
||||
result.xx = aData->Item(1).GetFloatValue();
|
||||
result.yx = aData->Item(2).GetFloatValue();
|
||||
result.xy = aData->Item(3).GetFloatValue();
|
||||
result.yy = aData->Item(4).GetFloatValue();
|
||||
|
||||
/* The last two elements have their length parts stored in aDelta
|
||||
* and their percent parts stored in aX[0] and aY[1].
|
||||
*/
|
||||
ProcessTranslatePart(result._41, aData->Item(5),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslatePart(result._42, aData->Item(6),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
result.x0 = ProcessTranslatePart(aData->Item(5),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
result.y0 = ProcessTranslatePart(aData->Item(6),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
|
||||
return result;
|
||||
aMatrix.PreMultiply(result);
|
||||
}
|
||||
|
||||
/*static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessMatrix3D(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit,
|
||||
PRBool *aPercentX, PRBool *aPercentY)
|
||||
static void
|
||||
ProcessMatrix3D(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 17, "Invalid array!");
|
||||
|
||||
@ -201,31 +185,33 @@ nsStyleTransformMatrix::ProcessMatrix3D(const nsCSSValue::Array* aData,
|
||||
temp._34 = aData->Item(12).GetFloatValue();
|
||||
temp._44 = aData->Item(16).GetFloatValue();
|
||||
|
||||
ProcessTranslatePart(temp._41, aData->Item(13),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslatePart(temp._42, aData->Item(14),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslatePart(temp._43, aData->Item(15),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
return temp;
|
||||
temp._41 = ProcessTranslatePart(aData->Item(13),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
temp._42 = ProcessTranslatePart(aData->Item(14),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
temp._43 = ProcessTranslatePart(aData->Item(15),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
|
||||
aMatrix.PreMultiply(temp);
|
||||
}
|
||||
|
||||
/* Helper function to process two matrices that we need to interpolate between */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessInterpolateMatrix(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
ProcessInterpolateMatrix(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 4, "Invalid array!");
|
||||
|
||||
gfx3DMatrix matrix1, matrix2;
|
||||
if (aData->Item(1).GetUnit() == eCSSUnit_List) {
|
||||
matrix1 = ReadTransforms(aData->Item(1).GetListValue(),
|
||||
matrix1 = nsStyleTransformMatrix::ReadTransforms(aData->Item(1).GetListValue(),
|
||||
aContext, aPresContext,
|
||||
aCanStoreInRuleTree,
|
||||
aBounds, aAppUnitsPerMatrixUnit);
|
||||
@ -238,190 +224,164 @@ nsStyleTransformMatrix::ProcessInterpolateMatrix(const nsCSSValue::Array* aData,
|
||||
}
|
||||
double progress = aData->Item(3).GetPercentValue();
|
||||
|
||||
return nsStyleAnimation::InterpolateTransformMatrix(matrix1, matrix2, progress);
|
||||
aMatrix = nsStyleAnimation::InterpolateTransformMatrix(matrix1, matrix2, progress) * aMatrix;
|
||||
}
|
||||
|
||||
/* Helper function to process a translatex function. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessTranslateX(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
ProcessTranslateX(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
gfx3DMatrix temp;
|
||||
gfxPoint3D temp;
|
||||
|
||||
/* There are two cases. If we have a number, we want our matrix to look
|
||||
* like this:
|
||||
*
|
||||
* | 1 0 0 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | dx 0 0 1 |
|
||||
* So E = value
|
||||
*
|
||||
* Otherwise, we might have a percentage, so we want to set the dX component
|
||||
* to the percent.
|
||||
*/
|
||||
ProcessTranslatePart(temp._41, aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
return temp;
|
||||
temp.x = ProcessTranslatePart(aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
aMatrix.Translate(temp);
|
||||
}
|
||||
|
||||
/* Helper function to process a translatey function. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessTranslateY(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
ProcessTranslateY(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
gfx3DMatrix temp;
|
||||
gfxPoint3D temp;
|
||||
|
||||
/* There are two cases. If we have a number, we want our matrix to look
|
||||
* like this:
|
||||
*
|
||||
* | 1 0 0 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | 0 dy 0 1 |
|
||||
* So E = value
|
||||
*
|
||||
* Otherwise, we might have a percentage, so we want to set the dY component
|
||||
* to the percent.
|
||||
*/
|
||||
ProcessTranslatePart(temp._42, aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
return temp;
|
||||
temp.y = ProcessTranslatePart(aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
aMatrix.Translate(temp);
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessTranslateZ(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
static void
|
||||
ProcessTranslateZ(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
gfx3DMatrix temp;
|
||||
gfxPoint3D temp;
|
||||
|
||||
ProcessTranslatePart(temp._43, aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
0, aAppUnitsPerMatrixUnit);
|
||||
return temp;
|
||||
temp.z = ProcessTranslatePart(aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
0, aAppUnitsPerMatrixUnit);
|
||||
aMatrix.Translate(temp);
|
||||
}
|
||||
|
||||
/* Helper function to process a translate function. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessTranslate(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
ProcessTranslate(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2 || aData->Count() == 3, "Invalid array!");
|
||||
|
||||
gfx3DMatrix temp;
|
||||
gfxPoint3D temp;
|
||||
|
||||
ProcessTranslatePart(temp._41, aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
temp.x = ProcessTranslatePart(aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
|
||||
/* If we read in a Y component, set it appropriately */
|
||||
if (aData->Count() == 3) {
|
||||
ProcessTranslatePart(temp._42, aData->Item(2),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
temp.y = ProcessTranslatePart(aData->Item(2),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
}
|
||||
return temp;
|
||||
aMatrix.Translate(temp);
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessTranslate3D(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
ProcessTranslate3D(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 4, "Invalid array!");
|
||||
|
||||
gfx3DMatrix temp;
|
||||
gfxPoint3D temp;
|
||||
|
||||
ProcessTranslatePart(temp._41, aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
temp.x = ProcessTranslatePart(aData->Item(1),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Width(), aAppUnitsPerMatrixUnit);
|
||||
|
||||
ProcessTranslatePart(temp._42, aData->Item(2),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
temp.y = ProcessTranslatePart(aData->Item(2),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
aBounds.Height(), aAppUnitsPerMatrixUnit);
|
||||
|
||||
ProcessTranslatePart(temp._43, aData->Item(3),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
0, aAppUnitsPerMatrixUnit);
|
||||
temp.z = ProcessTranslatePart(aData->Item(3),
|
||||
aContext, aPresContext, aCanStoreInRuleTree,
|
||||
0, aAppUnitsPerMatrixUnit);
|
||||
|
||||
return temp;
|
||||
aMatrix.Translate(temp);
|
||||
}
|
||||
|
||||
/* Helper function to set up a scale matrix. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessScaleHelper(float aXScale, float aYScale, float aZScale)
|
||||
static void
|
||||
ProcessScaleHelper(gfx3DMatrix& aMatrix,
|
||||
float aXScale,
|
||||
float aYScale,
|
||||
float aZScale)
|
||||
{
|
||||
/* We want our matrix to look like this:
|
||||
* | dx 0 0 0 |
|
||||
* | 0 dy 0 0 |
|
||||
* | 0 0 dz 0 |
|
||||
* | 0 0 0 1 |
|
||||
* So A = value
|
||||
*/
|
||||
gfx3DMatrix temp;
|
||||
temp._11 = aXScale;
|
||||
temp._22 = aYScale;
|
||||
temp._33 = aZScale;
|
||||
return temp;
|
||||
aMatrix.Scale(aXScale, aYScale, aZScale);
|
||||
}
|
||||
|
||||
/* Process a scalex function. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessScaleX(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessScaleX(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Bad array!");
|
||||
return ProcessScaleHelper(aData->Item(1).GetFloatValue(), 1.0f, 1.0f);
|
||||
ProcessScaleHelper(aMatrix, aData->Item(1).GetFloatValue(), 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
/* Process a scaley function. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessScaleY(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessScaleY(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Bad array!");
|
||||
return ProcessScaleHelper(1.0f, aData->Item(1).GetFloatValue(), 1.0f);
|
||||
ProcessScaleHelper(aMatrix, 1.0f, aData->Item(1).GetFloatValue(), 1.0f);
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessScaleZ(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessScaleZ(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Bad array!");
|
||||
return ProcessScaleHelper(1.0f, 1.0f, aData->Item(1).GetFloatValue());
|
||||
ProcessScaleHelper(aMatrix, 1.0f, 1.0f, aData->Item(1).GetFloatValue());
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessScale3D(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessScale3D(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 4, "Bad array!");
|
||||
return ProcessScaleHelper(aData->Item(1).GetFloatValue(),
|
||||
aData->Item(2).GetFloatValue(),
|
||||
aData->Item(3).GetFloatValue());
|
||||
ProcessScaleHelper(aMatrix,
|
||||
aData->Item(1).GetFloatValue(),
|
||||
aData->Item(2).GetFloatValue(),
|
||||
aData->Item(3).GetFloatValue());
|
||||
}
|
||||
|
||||
/* Process a scale function. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessScale(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessScale(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2 || aData->Count() == 3, "Bad array!");
|
||||
/* We either have one element or two. If we have one, it's for both X and Y.
|
||||
@ -431,50 +391,40 @@ nsStyleTransformMatrix::ProcessScale(const nsCSSValue::Array* aData)
|
||||
const nsCSSValue& scaleY = (aData->Count() == 2 ? scaleX :
|
||||
aData->Item(2));
|
||||
|
||||
return ProcessScaleHelper(scaleX.GetFloatValue(),
|
||||
scaleY.GetFloatValue(),
|
||||
1.0f);
|
||||
ProcessScaleHelper(aMatrix,
|
||||
scaleX.GetFloatValue(),
|
||||
scaleY.GetFloatValue(),
|
||||
1.0f);
|
||||
}
|
||||
|
||||
/* Helper function that, given a set of angles, constructs the appropriate
|
||||
* skew matrix.
|
||||
*/
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessSkewHelper(double aXAngle, double aYAngle)
|
||||
static void
|
||||
ProcessSkewHelper(gfx3DMatrix& aMatrix, double aXAngle, double aYAngle)
|
||||
{
|
||||
/* We want our matrix to look like this:
|
||||
* | 1 tan(ThetaY) 0 0 |
|
||||
* | tan(ThetaX) 1 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | 0 0 0 1 |
|
||||
* However, to avoid infinite values, we'll use the SafeTangent function
|
||||
* instead of the C standard tan function.
|
||||
*/
|
||||
gfx3DMatrix temp;
|
||||
temp._12 = SafeTangent(aYAngle);
|
||||
temp._21 = SafeTangent(aXAngle);
|
||||
return temp;
|
||||
aMatrix.SkewXY(aXAngle, aYAngle);
|
||||
}
|
||||
|
||||
/* Function that converts a skewx transform into a matrix. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessSkewX(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessSkewX(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_ASSERTION(aData->Count() == 2, "Bad array!");
|
||||
return ProcessSkewHelper(aData->Item(1).GetAngleValueInRadians(), 0.0);
|
||||
ProcessSkewHelper(aMatrix, aData->Item(1).GetAngleValueInRadians(), 0.0);
|
||||
}
|
||||
|
||||
/* Function that converts a skewy transform into a matrix. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessSkewY(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessSkewY(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_ASSERTION(aData->Count() == 2, "Bad array!");
|
||||
return ProcessSkewHelper(0.0, aData->Item(1).GetAngleValueInRadians());
|
||||
ProcessSkewHelper(aMatrix, 0.0, aData->Item(1).GetAngleValueInRadians());
|
||||
}
|
||||
|
||||
/* Function that converts a skew transform into a matrix. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessSkew(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessSkew(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_ASSERTION(aData->Count() == 2 || aData->Count() == 3, "Bad array!");
|
||||
|
||||
@ -482,87 +432,36 @@ nsStyleTransformMatrix::ProcessSkew(const nsCSSValue::Array* aData)
|
||||
double ySkew = (aData->Count() == 2
|
||||
? 0.0 : aData->Item(2).GetAngleValueInRadians());
|
||||
|
||||
return ProcessSkewHelper(xSkew, ySkew);
|
||||
ProcessSkewHelper(aMatrix, xSkew, ySkew);
|
||||
}
|
||||
|
||||
/* Function that converts a rotate transform into a matrix. */
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessRotateZ(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessRotateZ(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
/* We want our matrix to look like this:
|
||||
* | cos(theta) sin(theta) 0 0 |
|
||||
* | -sin(theta) cos(theta) 0 0 |
|
||||
* | 0 0 1 0 |
|
||||
* | 0 0 0 1 |
|
||||
* (see http://www.w3.org/TR/SVG/coords.html#RotationDefined)
|
||||
*/
|
||||
double theta = aData->Item(1).GetAngleValueInRadians();
|
||||
float cosTheta = FlushToZero(cos(theta));
|
||||
float sinTheta = FlushToZero(sin(theta));
|
||||
|
||||
gfx3DMatrix temp;
|
||||
|
||||
temp._11 = cosTheta;
|
||||
temp._12 = sinTheta;
|
||||
temp._21 = -sinTheta;
|
||||
temp._22 = cosTheta;
|
||||
return temp;
|
||||
aMatrix.RotateZ(theta);
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessRotateX(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessRotateX(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
/* We want our matrix to look like this:
|
||||
* | 1 0 0 0 |
|
||||
* | 0 cos(theta) sin(theta) 0 |
|
||||
* | 0 -sin(theta) cos(theta) 0 |
|
||||
* | 0 0 0 1 |
|
||||
* (see http://www.w3.org/TR/SVG/coords.html#RotationDefined)
|
||||
*/
|
||||
double theta = aData->Item(1).GetAngleValueInRadians();
|
||||
float cosTheta = FlushToZero(cos(theta));
|
||||
float sinTheta = FlushToZero(sin(theta));
|
||||
|
||||
gfx3DMatrix temp;
|
||||
|
||||
temp._22 = cosTheta;
|
||||
temp._23 = sinTheta;
|
||||
temp._32 = -sinTheta;
|
||||
temp._33 = cosTheta;
|
||||
return temp;
|
||||
aMatrix.RotateX(theta);
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessRotateY(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessRotateY(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
/* We want our matrix to look like this:
|
||||
* | cos(theta) 0 -sin(theta) 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | sin(theta) 0 cos(theta) 0 |
|
||||
* | 0 0 0 1 |
|
||||
* (see http://www.w3.org/TR/SVG/coords.html#RotationDefined)
|
||||
*/
|
||||
double theta = aData->Item(1).GetAngleValueInRadians();
|
||||
float cosTheta = FlushToZero(cos(theta));
|
||||
float sinTheta = FlushToZero(sin(theta));
|
||||
|
||||
gfx3DMatrix temp;
|
||||
|
||||
temp._11 = cosTheta;
|
||||
temp._13 = -sinTheta;
|
||||
temp._31 = sinTheta;
|
||||
temp._33 = cosTheta;
|
||||
return temp;
|
||||
aMatrix.RotateY(theta);
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessRotate3D(const nsCSSValue::Array* aData)
|
||||
static void
|
||||
ProcessRotate3D(gfx3DMatrix& aMatrix, const nsCSSValue::Array* aData)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 5, "Invalid array!");
|
||||
|
||||
@ -584,7 +483,7 @@ nsStyleTransformMatrix::ProcessRotate3D(const nsCSSValue::Array* aData)
|
||||
/* Normalize [x,y,z] */
|
||||
float length = sqrt(x*x + y*y + z*z);
|
||||
if (length == 0.0) {
|
||||
return gfx3DMatrix();
|
||||
return;
|
||||
}
|
||||
x /= length;
|
||||
y /= length;
|
||||
@ -609,60 +508,39 @@ nsStyleTransformMatrix::ProcessRotate3D(const nsCSSValue::Array* aData)
|
||||
temp._42 = 0.0f;
|
||||
temp._43 = 0.0f;
|
||||
temp._44 = 1.0f;
|
||||
return temp;
|
||||
|
||||
aMatrix = temp * aMatrix;
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ProcessPerspective(const nsCSSValue::Array* aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
ProcessPerspective(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array* aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
|
||||
|
||||
/* We want our matrix to look like this:
|
||||
* | 1 0 0 0 |
|
||||
* | 0 1 0 0 |
|
||||
* | 0 0 1 -1/depth |
|
||||
* | 0 0 0 1 |
|
||||
*/
|
||||
|
||||
gfx3DMatrix temp;
|
||||
|
||||
float depth;
|
||||
ProcessTranslatePart(depth, aData->Item(1), aContext,
|
||||
aPresContext, aCanStoreInRuleTree,
|
||||
0, aAppUnitsPerMatrixUnit);
|
||||
NS_ASSERTION(depth > 0.0, "Perspective must be positive!");
|
||||
temp._34 = -1.0/depth;
|
||||
|
||||
return temp;
|
||||
float depth = ProcessTranslatePart(aData->Item(1), aContext,
|
||||
aPresContext, aCanStoreInRuleTree,
|
||||
0, aAppUnitsPerMatrixUnit);
|
||||
aMatrix.Perspective(depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the transform function, as an nsCSSKeyword, for the given
|
||||
* nsCSSValue::Array from a transform list.
|
||||
*/
|
||||
/* static */ nsCSSKeyword
|
||||
nsStyleTransformMatrix::TransformFunctionOf(const nsCSSValue::Array* aData)
|
||||
{
|
||||
nsAutoString keyword;
|
||||
aData->Item(0).GetStringValue(keyword);
|
||||
return nsCSSKeywords::LookupKeyword(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* SetToTransformFunction is essentially a giant switch statement that fans
|
||||
* out to many smaller helper functions.
|
||||
*/
|
||||
gfx3DMatrix
|
||||
nsStyleTransformMatrix::MatrixForTransformFunction(const nsCSSValue::Array * aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
static void
|
||||
MatrixForTransformFunction(gfx3DMatrix& aMatrix,
|
||||
const nsCSSValue::Array * aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
NS_PRECONDITION(aData, "Why did you want to get data from a null array?");
|
||||
// It's OK if aContext and aPresContext are null if the caller already
|
||||
@ -673,70 +551,102 @@ nsStyleTransformMatrix::MatrixForTransformFunction(const nsCSSValue::Array * aDa
|
||||
/* Get the keyword for the transform. */
|
||||
switch (TransformFunctionOf(aData)) {
|
||||
case eCSSKeyword_translatex:
|
||||
return ProcessTranslateX(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslateX(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_translatey:
|
||||
return ProcessTranslateY(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslateY(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_translatez:
|
||||
return ProcessTranslateZ(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslateZ(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_translate:
|
||||
return ProcessTranslate(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslate(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_translate3d:
|
||||
return ProcessTranslate3D(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessTranslate3D(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_scalex:
|
||||
return ProcessScaleX(aData);
|
||||
ProcessScaleX(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scaley:
|
||||
return ProcessScaleY(aData);
|
||||
ProcessScaleY(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scalez:
|
||||
return ProcessScaleZ(aData);
|
||||
ProcessScaleZ(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scale:
|
||||
return ProcessScale(aData);
|
||||
ProcessScale(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scale3d:
|
||||
return ProcessScale3D(aData);
|
||||
ProcessScale3D(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_skewx:
|
||||
return ProcessSkewX(aData);
|
||||
ProcessSkewX(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_skewy:
|
||||
return ProcessSkewY(aData);
|
||||
ProcessSkewY(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_skew:
|
||||
return ProcessSkew(aData);
|
||||
ProcessSkew(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotatex:
|
||||
return ProcessRotateX(aData);
|
||||
ProcessRotateX(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotatey:
|
||||
return ProcessRotateY(aData);
|
||||
ProcessRotateY(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotatez:
|
||||
case eCSSKeyword_rotate:
|
||||
return ProcessRotateZ(aData);
|
||||
ProcessRotateZ(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotate3d:
|
||||
return ProcessRotate3D(aData);
|
||||
ProcessRotate3D(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_matrix:
|
||||
return ProcessMatrix(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessMatrix(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_matrix3d:
|
||||
return ProcessMatrix3D(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessMatrix3D(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_interpolatematrix:
|
||||
return ProcessInterpolateMatrix(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
ProcessInterpolateMatrix(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
case eCSSKeyword_perspective:
|
||||
return ProcessPerspective(aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aAppUnitsPerMatrixUnit);
|
||||
ProcessPerspective(aMatrix, aData, aContext, aPresContext,
|
||||
aCanStoreInRuleTree, aAppUnitsPerMatrixUnit);
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown transform function!");
|
||||
}
|
||||
return gfx3DMatrix();
|
||||
}
|
||||
|
||||
/* static */ gfx3DMatrix
|
||||
nsStyleTransformMatrix::ReadTransforms(const nsCSSValueList* aList,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
/**
|
||||
* Return the transform function, as an nsCSSKeyword, for the given
|
||||
* nsCSSValue::Array from a transform list.
|
||||
*/
|
||||
nsCSSKeyword
|
||||
TransformFunctionOf(const nsCSSValue::Array* aData)
|
||||
{
|
||||
nsAutoString keyword;
|
||||
aData->Item(0).GetStringValue(keyword);
|
||||
return nsCSSKeywords::LookupKeyword(keyword);
|
||||
}
|
||||
|
||||
gfx3DMatrix
|
||||
ReadTransforms(const nsCSSValueList* aList,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
gfx3DMatrix result;
|
||||
|
||||
@ -747,12 +657,13 @@ nsStyleTransformMatrix::ReadTransforms(const nsCSSValueList* aList,
|
||||
NS_ASSERTION(currElem.GetArrayValue()->Count() >= 1,
|
||||
"Incoming function is too short!");
|
||||
|
||||
/* Read in a single transform matrix, then accumulate it with the total. */
|
||||
result = MatrixForTransformFunction(currElem.GetArrayValue(), aContext,
|
||||
aPresContext, aCanStoreInRuleTree,
|
||||
aBounds, aAppUnitsPerMatrixUnit) * result;
|
||||
/* Read in a single transform matrix. */
|
||||
MatrixForTransformFunction(result, currElem.GetArrayValue(), aContext,
|
||||
aPresContext, aCanStoreInRuleTree,
|
||||
aBounds, aAppUnitsPerMatrixUnit);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace nsStyleTransformMatrix
|
||||
|
@ -52,22 +52,21 @@ class nsStyleContext;
|
||||
class nsPresContext;
|
||||
|
||||
/**
|
||||
* A helper class to generate gfxMatrixes from css transform functions.
|
||||
* A helper to generate gfxMatrixes from css transform functions.
|
||||
*/
|
||||
class nsStyleTransformMatrix
|
||||
{
|
||||
public:
|
||||
namespace nsStyleTransformMatrix {
|
||||
|
||||
/**
|
||||
* Return the transform function, as an nsCSSKeyword, for the given
|
||||
* nsCSSValue::Array from a transform list.
|
||||
*/
|
||||
static nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
|
||||
nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
|
||||
|
||||
/**
|
||||
* Given an nsCSSValue::Array* containing a -moz-transform function,
|
||||
* returns a matrix containing the value of that function.
|
||||
* Given an nsCSSValueList containing -moz-transform functions,
|
||||
* returns a matrix containing the value of those functions.
|
||||
*
|
||||
* @param aData The nsCSSValue::Array* containing the transform function.
|
||||
* @param aData The nsCSSValueList containing the transform functions
|
||||
* @param aContext The style context, used for unit conversion.
|
||||
* @param aPresContext The presentation context, used for unit conversion.
|
||||
* @param aCanStoreInRuleTree Set to false if the result cannot be cached
|
||||
@ -79,88 +78,13 @@ class nsStyleTransformMatrix
|
||||
* length values in aData are already known to have been converted to
|
||||
* eCSSUnit_Pixel (as they are in an nsStyleAnimation::Value)
|
||||
*/
|
||||
static gfx3DMatrix MatrixForTransformFunction(const nsCSSValue::Array* aData,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
gfx3DMatrix ReadTransforms(const nsCSSValueList* aList,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
|
||||
/**
|
||||
* The same as MatrixForTransformFunction, but for a list of transform
|
||||
* functions.
|
||||
*/
|
||||
static gfx3DMatrix ReadTransforms(const nsCSSValueList* aList,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
|
||||
private:
|
||||
static gfx3DMatrix ProcessMatrix(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit,
|
||||
PRBool *aPercentX = nsnull,
|
||||
PRBool *aPercentY = nsnull);
|
||||
static gfx3DMatrix ProcessMatrix3D(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit,
|
||||
PRBool *aPercentX = nsnull,
|
||||
PRBool *aPercentY = nsnull);
|
||||
static gfx3DMatrix ProcessInterpolateMatrix(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit);
|
||||
static gfx3DMatrix ProcessTranslateX(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit);
|
||||
static gfx3DMatrix ProcessTranslateY(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit);
|
||||
static gfx3DMatrix ProcessTranslateZ(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
static gfx3DMatrix ProcessTranslate(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit);
|
||||
static gfx3DMatrix ProcessTranslate3D(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
nsRect& aBounds, float aAppUnitsPerMatrixUnit);
|
||||
static gfx3DMatrix ProcessScaleHelper(float aXScale, float aYScale, float aZScale);
|
||||
static gfx3DMatrix ProcessScaleX(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessScaleY(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessScaleZ(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessScale(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessScale3D(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessSkewHelper(double aXAngle, double aYAngle);
|
||||
static gfx3DMatrix ProcessSkewX(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessSkewY(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessSkew(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessRotateX(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessRotateY(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessRotateZ(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessRotate3D(const nsCSSValue::Array *aData);
|
||||
static gfx3DMatrix ProcessPerspective(const nsCSSValue::Array *aData,
|
||||
nsStyleContext *aContext,
|
||||
nsPresContext *aPresContext,
|
||||
PRBool &aCanStoreInRuleTree,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
};
|
||||
} // namespace nsStyleTransformMatrix
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user