Index: Source/core/css/CSSGradientValue.cpp |
diff --git a/Source/core/css/CSSGradientValue.cpp b/Source/core/css/CSSGradientValue.cpp |
index 277162fd89ba49b8b354817c3e4bca249a68a349..632f97cdbf8d952aee0e3eb55bafc0f438994e38 100644 |
--- a/Source/core/css/CSSGradientValue.cpp |
+++ b/Source/core/css/CSSGradientValue.cpp |
@@ -29,6 +29,7 @@ |
#include "core/CSSValueKeywords.h" |
#include "core/css/CSSCalculationValue.h" |
#include "core/css/CSSToLengthConversionData.h" |
+#include "core/css/Pair.h" |
#include "core/dom/NodeRenderStyle.h" |
#include "core/dom/TextLinkColors.h" |
#include "core/rendering/RenderObject.h" |
@@ -389,15 +390,31 @@ void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD |
static float positionFromValue(CSSPrimitiveValue* value, const CSSToLengthConversionData& conversionData, const IntSize& size, bool isHorizontal) |
{ |
+ int origin = 0; |
+ int sign = 1; |
+ int edgeDistance = isHorizontal ? size.width() : size.height(); |
+ |
+ // In this case the center of the gradient is given relative to an edge in the form of: |
+ // [ top | bottom | right | left ] [ <percentage> | <length> ]. |
+ if (Pair* pair = value->getPairValue()) { |
+ CSSValueID originID = pair->first()->getValueID(); |
+ value = pair->second(); |
+ |
+ if (originID == CSSValueRight || originID == CSSValueBottom) { |
+ // For right/bottom, the offset is relative to the far edge. |
+ origin = edgeDistance; |
+ sign = -1; |
+ } |
+ } |
+ |
if (value->isNumber()) |
- return value->getFloatValue() * conversionData.zoom(); |
+ return origin + sign * value->getFloatValue() * conversionData.zoom(); |
- int edgeDistance = isHorizontal ? size.width() : size.height(); |
if (value->isPercentage()) |
- return value->getFloatValue() / 100.f * edgeDistance; |
+ return origin + sign * value->getFloatValue() / 100.f * edgeDistance; |
if (value->isCalculatedPercentageWithLength()) |
- return value->cssCalcValue()->toCalcValue(conversionData)->evaluate(edgeDistance); |
+ return origin + sign * value->cssCalcValue()->toCalcValue(conversionData)->evaluate(edgeDistance); |
switch (value->getValueID()) { |
case CSSValueTop: |
@@ -416,7 +433,7 @@ static float positionFromValue(CSSPrimitiveValue* value, const CSSToLengthConver |
break; |
} |
- return value->computeLength<float>(conversionData); |
+ return origin + sign * value->computeLength<float>(conversionData); |
} |
FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* horizontal, CSSPrimitiveValue* vertical, const CSSToLengthConversionData& conversionData, const IntSize& size) |