From 85d5ae2b8fabff7cf4b9a9439c1c0661226c632d Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Sat, 7 Jul 2012 10:27:08 -0400 Subject: [PATCH] Bug 752187 - Part 10: Implement rendering unprefixed gradients. r=dbaron --- layout/base/nsCSSRendering.cpp | 14 +++++++++++++- layout/base/nsStyleConsts.h | 1 + layout/style/nsComputedDOMStyle.cpp | 2 +- layout/style/nsRuleNode.cpp | 20 +++++++++++++++++--- layout/style/nsStyleStruct.cpp | 8 +++++--- layout/style/nsStyleStruct.h | 5 ++++- 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 4bece50b4b8f..3a5781c2ea1e 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -1675,13 +1675,16 @@ ComputeLinearGradientLine(nsPresContext* aPresContext, double angle; if (aGradient->mAngle.IsAngleValue()) { angle = aGradient->mAngle.GetAngleValueInRadians(); + if (!aGradient->mLegacySyntax) { + angle = M_PI_2 - angle; + } } else { angle = -M_PI_2; // defaults to vertical gradient starting from top } gfxPoint center(aBoxSize.width/2, aBoxSize.height/2); *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize); *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd; - } else if (aGradient->mToCorner) { + } else if (!aGradient->mLegacySyntax) { float xSign = aGradient->mBgPosX.GetPercentValue() * 2 - 1; float ySign = 1 - aGradient->mBgPosY.GetPercentValue() * 2; double angle = atan2(ySign * aBoxSize.width, xSign * aBoxSize.height); @@ -1696,6 +1699,7 @@ ComputeLinearGradientLine(nsPresContext* aPresContext, ConvertGradientValueToPixels(aGradient->mBgPosY, aBoxSize.height, appUnitsPerPixel)); if (aGradient->mAngle.IsAngleValue()) { + MOZ_ASSERT(aGradient->mLegacySyntax); double angle = aGradient->mAngle.GetAngleValueInRadians(); *aLineEnd = ComputeGradientLineEndFromAngle(*aLineStart, angle, aBoxSize); } else { @@ -1777,6 +1781,14 @@ ComputeRadialGradientLine(nsPresContext* aPresContext, } break; } + case NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE: { + PRInt32 appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel(); + radiusX = ConvertGradientValueToPixels(aGradient->mRadiusX, + aBoxSize.width, appUnitsPerPixel); + radiusY = ConvertGradientValueToPixels(aGradient->mRadiusY, + aBoxSize.height, appUnitsPerPixel); + break; + } default: NS_ABORT_IF_FALSE(false, "unknown radial gradient sizing method"); } diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h index 4b17faec8409..c34a4063b0af 100644 --- a/layout/base/nsStyleConsts.h +++ b/layout/base/nsStyleConsts.h @@ -822,6 +822,7 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER 1 #define NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE 2 #define NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER 3 +#define NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE 4 // See nsStyleSVG diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index de868c2a53a4..27fdfb243ace 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1441,7 +1441,7 @@ nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient, nsAutoString tokenString; nsROCSSPrimitiveValue *tmpVal = GetROCSSPrimitiveValue(); - if (aGradient->mToCorner) { + if (!aGradient->mLegacySyntax) { AppendCSSGradientToBoxPosition(aGradient, aString, needSep); } else { if (aGradient->mBgPosX.GetUnit() != eStyleUnit_None) { diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 25c16ef73020..be9908cf3e4d 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -834,7 +834,21 @@ static void SetGradient(const nsCSSValue& aValue, nsPresContext* aPresContext, const nsCSSValueGradient* gradient = aValue.GetGradientValue(); - if (gradient->mIsRadial) { + if (gradient->mIsExplicitSize) { + SetCoord(gradient->GetRadiusX(), aResult.mRadiusX, nsStyleCoord(), + SETCOORD_LP | SETCOORD_STORE_CALC, + aContext, aPresContext, aCanStoreInRuleTree); + if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) { + SetCoord(gradient->GetRadiusY(), aResult.mRadiusY, nsStyleCoord(), + SETCOORD_LP | SETCOORD_STORE_CALC, + aContext, aPresContext, aCanStoreInRuleTree); + aResult.mShape = NS_STYLE_GRADIENT_SHAPE_ELLIPTICAL; + } else { + aResult.mRadiusY = aResult.mRadiusX; + aResult.mShape = NS_STYLE_GRADIENT_SHAPE_CIRCULAR; + } + aResult.mSize = NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE; + } else if (gradient->mIsRadial) { if (gradient->GetRadialShape().GetUnit() == eCSSUnit_Enumerated) { aResult.mShape = gradient->GetRadialShape().GetIntValue(); } else { @@ -856,10 +870,10 @@ static void SetGradient(const nsCSSValue& aValue, nsPresContext* aPresContext, "bad unit for linear size"); aResult.mShape = NS_STYLE_GRADIENT_SHAPE_LINEAR; aResult.mSize = NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER; - - aResult.mToCorner = !gradient->mIsLegacySyntax; } + aResult.mLegacySyntax = gradient->mIsLegacySyntax; + // bg-position SetGradientCoord(gradient->mBgPos.mXValue, aPresContext, aContext, aResult.mBgPosX, aCanStoreInRuleTree); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index f57b3c02fe2c..499c9dbd5d27 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1399,10 +1399,12 @@ nsStyleGradient::operator==(const nsStyleGradient& aOther) const if (mShape != aOther.mShape || mSize != aOther.mSize || mRepeating != aOther.mRepeating || - mToCorner != aOther.mToCorner || + mLegacySyntax != aOther.mLegacySyntax || mBgPosX != aOther.mBgPosX || mBgPosY != aOther.mBgPosY || - mAngle != aOther.mAngle) + mAngle != aOther.mAngle || + mRadiusX != aOther.mRadiusX || + mRadiusY != aOther.mRadiusY) return false; if (mStops.Length() != aOther.mStops.Length()) @@ -1421,7 +1423,7 @@ nsStyleGradient::nsStyleGradient(void) : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR) , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) , mRepeating(false) - , mToCorner(false) + , mLegacySyntax(false) { } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index a5fe337ab252..610e9e60b3cc 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -127,12 +127,15 @@ public: PRUint8 mSize; // NS_STYLE_GRADIENT_SIZE_*; // not used (must be FARTHEST_CORNER) for linear shape bool mRepeating; - bool mToCorner; + bool mLegacySyntax; nsStyleCoord mBgPosX; // percent, coord, calc, none nsStyleCoord mBgPosY; // percent, coord, calc, none nsStyleCoord mAngle; // none, angle + nsStyleCoord mRadiusX; // percent, coord, calc, none + nsStyleCoord mRadiusY; // percent, coord, calc, none + // stops are in the order specified in the stylesheet nsTArray mStops;