# HG changeset patch # Parent 3b919614e684e4dfa42a311fe201b45a9991b0ea # User Matt Woodrow Bug 505115 - Part 19 - Make the matrix*() transform function handles both length and number values. r?dbaron diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -154,17 +154,19 @@ using namespace mozilla; #define VARIANT_HPN (VARIANT_INHERIT | VARIANT_PERCENT | VARIANT_NUMBER) #define VARIANT_HN (VARIANT_INHERIT | VARIANT_NUMBER) #define VARIANT_HON (VARIANT_HN | VARIANT_NONE) #define VARIANT_HOS (VARIANT_INHERIT | VARIANT_NONE | VARIANT_STRING) #define VARIANT_LPN (VARIANT_LP | VARIANT_NUMBER) #define VARIANT_UK (VARIANT_URL | VARIANT_KEYWORD) #define VARIANT_UO (VARIANT_URL | VARIANT_NONE) #define VARIANT_ANGLE_OR_ZERO (VARIANT_ANGLE | VARIANT_ZERO_ANGLE) -#define VARIANT_TRANSFORM_LPCALC (VARIANT_LP | VARIANT_CALC) +#define VARIANT_LPCALC (VARIANT_LENGTH | VARIANT_CALC | VARIANT_PERCENT) +#define VARIANT_LNCALC (VARIANT_LENGTH | VARIANT_CALC | VARIANT_NUMBER) +#define VARIANT_LPNCALC (VARIANT_LNCALC | VARIANT_PERCENT) #define VARIANT_IMAGE (VARIANT_URL | VARIANT_NONE | VARIANT_GRADIENT | \ VARIANT_IMAGE_RECT | VARIANT_ELEMENT) // This lives here because it depends on the above macros. const PRUint32 nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP(name_, id_, method_, flags_, parsevariant_, kwtable_, \ stylestruct_, stylestructoffset_, animtype_) \ @@ -7338,33 +7340,33 @@ static PRBool GetFunctionParseInformatio eTwoNumbers, eThreeNumbers, eThreeNumbersOneAngle, eMatrix, eMatrix3d, eNumVariantMasks }; static const PRInt32 kMaxElemsPerFunction = 16; static const PRInt32 kVariantMasks[eNumVariantMasks][kMaxElemsPerFunction] = { - {VARIANT_TRANSFORM_LPCALC}, + {VARIANT_LPCALC}, {VARIANT_LENGTH|VARIANT_CALC}, - {VARIANT_TRANSFORM_LPCALC, VARIANT_TRANSFORM_LPCALC}, - {VARIANT_TRANSFORM_LPCALC, VARIANT_TRANSFORM_LPCALC, VARIANT_LENGTH|VARIANT_CALC}, + {VARIANT_LPCALC, VARIANT_LPCALC}, + {VARIANT_LPCALC, VARIANT_LPCALC, VARIANT_LENGTH|VARIANT_CALC}, {VARIANT_ANGLE_OR_ZERO}, {VARIANT_ANGLE_OR_ZERO, VARIANT_ANGLE_OR_ZERO}, {VARIANT_NUMBER}, {VARIANT_LENGTH|VARIANT_POSITIVE_LENGTH}, {VARIANT_NUMBER, VARIANT_NUMBER}, {VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER}, {VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_ANGLE_OR_ZERO}, {VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, - VARIANT_TRANSFORM_LPCALC, VARIANT_TRANSFORM_LPCALC}, + VARIANT_LPNCALC, VARIANT_LPNCALC}, {VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, - VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER}}; + VARIANT_LPNCALC, VARIANT_LPNCALC, VARIANT_LNCALC, VARIANT_NUMBER}}; #ifdef DEBUG static const PRUint8 kVariantMaskLengths[eNumVariantMasks] = {1, 1, 2, 3, 1, 2, 1, 1, 2, 3, 4, 6, 16}; #endif PRInt32 variantIndex = eNumVariantMasks; diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp --- a/layout/style/nsStyleTransformMatrix.cpp +++ b/layout/style/nsStyleTransformMatrix.cpp @@ -93,22 +93,25 @@ static double SafeTangent(double aTheta) } /* Helper function to fill in an nscoord with the specified nsCSSValue. */ static nscoord CalcLength(const nsCSSValue &aValue, nsStyleContext* aContext, nsPresContext* aPresContext, PRBool &aCanStoreInRuleTree) { - if (aValue.GetUnit() == eCSSUnit_Pixel) { + if (aValue.GetUnit() == eCSSUnit_Pixel || + aValue.GetUnit() == eCSSUnit_Number) { // Handle this here (even though nsRuleNode::CalcLength handles it // fine) so that callers are allowed to pass a null style context // and pres context to SetToTransformFunction if they know (as // nsStyleAnimation does) that all lengths within the transform // function have already been computed to pixels and percents. + // + // Raw numbers are treated as being pixels. return nsPresContext::CSSPixelsToAppUnits(aValue.GetFloatValue()); } return nsRuleNode::CalcLength(aValue, aContext, aPresContext, aCanStoreInRuleTree); } static void ProcessTranslatePart(float& aResult, @@ -168,17 +171,22 @@ nsStyleTransformMatrix::ProcessMatrix(co ProcessTranslatePart(result._42, aData->Item(6), aContext, aPresContext, aCanStoreInRuleTree, aBounds.Height(), aAppUnitsPerMatrixUnit); return result; } /*static */ gfx3DMatrix -nsStyleTransformMatrix::ProcessMatrix3D(const nsCSSValue::Array* aData) +nsStyleTransformMatrix::ProcessMatrix3D(const nsCSSValue::Array* aData, + nsStyleContext* aContext, + nsPresContext* aPresContext, + PRBool& aCanStoreInRuleTree, + nsRect& aBounds, float aAppUnitsPerMatrixUnit, + PRBool *aPercentX, PRBool *aPercentY) { NS_PRECONDITION(aData->Count() == 17, "Invalid array!"); gfx3DMatrix temp; temp._11 = aData->Item(1).GetFloatValue(); temp._12 = aData->Item(2).GetFloatValue(); temp._13 = aData->Item(3).GetFloatValue(); @@ -186,20 +194,27 @@ nsStyleTransformMatrix::ProcessMatrix3D( temp._21 = aData->Item(5).GetFloatValue(); temp._22 = aData->Item(6).GetFloatValue(); temp._23 = aData->Item(7).GetFloatValue(); temp._24 = aData->Item(8).GetFloatValue(); temp._31 = aData->Item(9).GetFloatValue(); temp._32 = aData->Item(10).GetFloatValue(); temp._33 = aData->Item(11).GetFloatValue(); temp._34 = aData->Item(12).GetFloatValue(); - temp._41 = aData->Item(13).GetFloatValue(); - temp._42 = aData->Item(14).GetFloatValue(); - temp._43 = aData->Item(15).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; } /* Helper function to process two matrices that we need to interpolate between */ /* static */ gfx3DMatrix nsStyleTransformMatrix::ProcessInterpolateMatrix(const nsCSSValue::Array* aData, nsStyleContext* aContext, nsPresContext* aPresContext, @@ -696,17 +711,18 @@ nsStyleTransformMatrix::MatrixForTransfo case eCSSKeyword_rotate: return ProcessRotateZ(aData); case eCSSKeyword_rotate3d: return ProcessRotate3D(aData); case eCSSKeyword_matrix: return ProcessMatrix(aData, aContext, aPresContext, aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit); case eCSSKeyword_matrix3d: - return ProcessMatrix3D(aData); + return ProcessMatrix3D(aData, aContext, aPresContext, + aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit); case eCSSKeyword_interpolatematrix: return ProcessInterpolateMatrix(aData, aContext, aPresContext, aCanStoreInRuleTree, aBounds, aAppUnitsPerMatrixUnit); case eCSSKeyword_perspective: return ProcessPerspective(aData, aContext, aPresContext, aCanStoreInRuleTree, aAppUnitsPerMatrixUnit); default: NS_NOTREACHED("Unknown transform function!"); diff --git a/layout/style/nsStyleTransformMatrix.h b/layout/style/nsStyleTransformMatrix.h --- a/layout/style/nsStyleTransformMatrix.h +++ b/layout/style/nsStyleTransformMatrix.h @@ -100,17 +100,23 @@ class nsStyleTransformMatrix 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); + 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, diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -926,28 +926,28 @@ var gCSSProperties = { invalid_values: [ "-1", "-808", "3.0", "17.5" ] }, "-moz-transform": { domProp: "MozTransform", inherited: false, type: CSS_TYPE_LONGHAND, prerequisites: { "width": "300px", "height": "50px" }, initial_values: [ "none" ], - other_values: [ "translatex(1px)", "translatex(4em)", "translatex(-4px)", "translatex(3px)", "translatex(0px) translatex(1px) translatex(2px) translatex(3px) translatex(4px)", "translatey(4em)", "translate(3px)", "translate(10px, -3px)", "rotate(45deg)", "rotate(45grad)", "rotate(45rad)", "rotate(0)", "scalex(10)", "scaley(10)", "scale(10)", "scale(10, 20)", "skewx(30deg)", "skewx(0)", "skewy(0)", "skewx(30grad)", "skewx(30rad)", "skewy(30deg)", "skewy(30grad)", "skewy(30rad)", "matrix(1, 2, 3, 4, 5px, 6em)", "rotate(45deg) scale(2, 1)", "skewx(45deg) skewx(-50grad)", "translate(0, 0) scale(1, 1) skewx(0) skewy(0) matrix(1, 0, 0, 1, 0, 0)", "translatex(50%)", "translatey(50%)", "translate(50%)", "translate(3%, 5px)", "translate(5px, 3%)", "matrix(1, 2, 3, 4, 5px, 6%)", "matrix(1, 2, 3, 4, 5%, 6px)", "matrix(1, 2, 3, 4, 5%, 6%)", + other_values: [ "translatex(1px)", "translatex(4em)", "translatex(-4px)", "translatex(3px)", "translatex(0px) translatex(1px) translatex(2px) translatex(3px) translatex(4px)", "translatey(4em)", "translate(3px)", "translate(10px, -3px)", "rotate(45deg)", "rotate(45grad)", "rotate(45rad)", "rotate(0)", "scalex(10)", "scaley(10)", "scale(10)", "scale(10, 20)", "skewx(30deg)", "skewx(0)", "skewy(0)", "skewx(30grad)", "skewx(30rad)", "skewy(30deg)", "skewy(30grad)", "skewy(30rad)", "matrix(1, 2, 3, 4, 5px, 6em)", "rotate(45deg) scale(2, 1)", "skewx(45deg) skewx(-50grad)", "translate(0, 0) scale(1, 1) skewx(0) skewy(0) matrix(1, 0, 0, 1, 0, 0)", "translatex(50%)", "translatey(50%)", "translate(50%)", "translate(3%, 5px)", "translate(5px, 3%)", "matrix(1, 2, 3, 4, 5px, 6%)", "matrix(1, 2, 3, 4, 5%, 6px)", "matrix(1, 2, 3, 4, 5%, 6%)", "matrix(1, 2, 3, 4, 5, 6)", /* valid calc() values */ "translatex(-moz-calc(5px + 10%))", "translatey(-moz-calc(0.25 * 5px + 10% / 3))", "translate(-moz-calc(5px - 10% * 3))", "translate(-moz-calc(5px - 3 * 10%), 50px)", "translate(-50px, -moz-calc(5px - 10% * 3))", "matrix(1, 0, 0, 1, -moz-calc(5px * 3), -moz-calc(10% - 3px))" ].concat(SpecialPowers.getBoolPref("layout.3d-transforms.enabled") ? [ - "translatez(1px)", "translatez(4em)", "translatez(-4px)", "translatez(0px)", "translatez(2px) translatez(5px)", "translate3d(3px, 4px, 5px)", "translate3d(2em, 3px, 1em)", "translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)", "scale3d(4, 4, 4)", "scale3d(-2, 3, -7)", "scalez(4)", "scalez(-6)", "rotate3d(2, 3, 4, 45deg)", "rotate3d(-3, 7, 0, 12rad)", "rotatex(15deg)", "rotatey(-12grad)", "rotatez(72rad)", "perspective(1000px)", "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)" + "translatez(1px)", "translatez(4em)", "translatez(-4px)", "translatez(0px)", "translatez(2px) translatez(5px)", "translate3d(3px, 4px, 5px)", "translate3d(2em, 3px, 1em)", "translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)", "scale3d(4, 4, 4)", "scale3d(-2, 3, -7)", "scalez(4)", "scalez(-6)", "rotate3d(2, 3, 4, 45deg)", "rotate3d(-3, 7, 0, 12rad)", "rotatex(15deg)", "rotatey(-12grad)", "rotatez(72rad)", "perspective(1000px)", "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)", "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13px, 14em, 15px, 16)", "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20%, 10%, 15, 16)" ] : []), - invalid_values: ["1px", "#0000ff", "red", "auto", "translatex(1px 1px)", "translatex(translatex(1px))", "translatex(#0000ff)", "translatex(red)", "translatey()", "matrix(1, 2, 3, 4, 5, 6)", "matrix(1px, 2px, 3px, 4px, 5px, 6px)", "scale(150%)", "skewx(red)", "matrix(1%, 0, 0, 0, 0px, 0px)", "matrix(0, 1%, 2, 3, 4px,5px)", "matrix(0, 1, 2%, 3, 4px, 5px)", "matrix(0, 1, 2, 3%, 4%, 5%)", + invalid_values: ["1px", "#0000ff", "red", "auto", "translatex(1px 1px)", "translatex(translatex(1px))", "translatex(#0000ff)", "translatex(red)", "translatey()", "matrix(1px, 2px, 3px, 4px, 5px, 6px)", "scale(150%)", "skewx(red)", "matrix(1%, 0, 0, 0, 0px, 0px)", "matrix(0, 1%, 2, 3, 4px,5px)", "matrix(0, 1, 2%, 3, 4px, 5px)", "matrix(0, 1, 2, 3%, 4%, 5%)", /* invalid calc() values */ "translatey(-moz-min(5px,10%))", "translatex(-moz-max(5px,10%))", "translate(10px, -moz-calc(min(5px,10%)))", "translate(-moz-calc(max(5px,10%)), 10%)", "matrix(1, 0, 0, 1, -moz-max(5px * 3), -moz-calc(10% - 3px))" ].concat(SpecialPowers.getBoolPref("layout.3d-transforms.enabled") ? [ "perspective(0px)", "perspective(-10px)", "matrix3d(dinosaur)", "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)", "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)", "rotatey(words)", "rotatex(7)", "translate3d(3px, 4px, 1px, 7px)"