- Revision
- 208062
- Author
- hy...@apple.com
- Date
- 2016-10-28 12:40:44 -0700 (Fri, 28 Oct 2016)
Log Message
[CSS Parser] Clean up gradient parsing
https://bugs.webkit.org/show_bug.cgi?id=164139
Reviewed by Dean Jackson.
* css/CSSGradientValue.cpp:
(WebCore::positionFromValue):
(WebCore::CSSGradientValue::computeEndPoint):
* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradient):
(WebCore::CSSPropertyParserHelpers::consumeGradientColorStops):
(WebCore::CSSPropertyParserHelpers::consumeDeprecatedRadialGradient):
(WebCore::CSSPropertyParserHelpers::consumeRadialGradient):
(WebCore::CSSPropertyParserHelpers::consumeLinearGradient):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (208061 => 208062)
--- trunk/Source/WebCore/ChangeLog 2016-10-28 18:58:23 UTC (rev 208061)
+++ trunk/Source/WebCore/ChangeLog 2016-10-28 19:40:44 UTC (rev 208062)
@@ -1,3 +1,20 @@
+2016-10-28 Dave Hyatt <hy...@apple.com>
+
+ [CSS Parser] Clean up gradient parsing
+ https://bugs.webkit.org/show_bug.cgi?id=164139
+
+ Reviewed by Dean Jackson.
+
+ * css/CSSGradientValue.cpp:
+ (WebCore::positionFromValue):
+ (WebCore::CSSGradientValue::computeEndPoint):
+ * css/parser/CSSPropertyParserHelpers.cpp:
+ (WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeGradientColorStops):
+ (WebCore::CSSPropertyParserHelpers::consumeDeprecatedRadialGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeRadialGradient):
+ (WebCore::CSSPropertyParserHelpers::consumeLinearGradient):
+
2016-10-28 Dean Jackson <d...@apple.com>
New CSS Parser should use Colors not RGBA32s
Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (208061 => 208062)
--- trunk/Source/WebCore/css/CSSGradientValue.cpp 2016-10-28 18:58:23 UTC (rev 208061)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp 2016-10-28 19:40:44 UTC (rev 208062)
@@ -35,6 +35,7 @@
#include "GradientImage.h"
#include "Image.h"
#include "NodeRenderStyle.h"
+#include "Pair.h"
#include "RenderElement.h"
#include "RenderView.h"
#include "StyleResolver.h"
@@ -494,21 +495,37 @@
gradient.setStopsSorted(true);
}
-static float positionFromValue(CSSPrimitiveValue& value, const CSSToLengthConversionData& conversionData, const FloatSize& size, bool isHorizontal)
+static float positionFromValue(const CSSPrimitiveValue* value, const CSSToLengthConversionData& conversionData, const FloatSize& size, bool isHorizontal)
{
- if (value.isNumber())
- return value.floatValue() * conversionData.zoom();
-
+ int origin = 0;
+ int sign = 1;
int edgeDistance = isHorizontal ? size.width() : size.height();
- if (value.isPercentage())
- return value.floatValue() / 100.f * edgeDistance;
+
+ // 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 (value->isPair()) {
+ CSSValueID originID = value->pairValue()->first()->valueID();
+ value = value->pairValue()->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 origin + sign * value->floatValue() * conversionData.zoom();
+
+ if (value->isPercentage())
+ return origin + sign * value->floatValue() / 100.f * edgeDistance;
- if (value.isCalculatedPercentageWithLength()) {
- Ref<CalculationValue> calculationValue { value.cssCalcValue()->createCalculationValue(conversionData) };
- return calculationValue->evaluate(edgeDistance);
+ if (value->isCalculatedPercentageWithLength()) {
+ Ref<CalculationValue> calculationValue { value->cssCalcValue()->createCalculationValue(conversionData) };
+ return origin + sign * calculationValue->evaluate(edgeDistance);
}
-
- switch (value.valueID()) {
+
+ switch (value->valueID()) {
case CSSValueTop:
ASSERT(!isHorizontal);
return 0;
@@ -521,11 +538,13 @@
case CSSValueRight:
ASSERT(isHorizontal);
return size.width();
+ case CSSValueCenter:
+ return origin + sign * .5f * edgeDistance;
default:
break;
}
- return value.computeLength<float>(conversionData);
+ return origin + sign * value->computeLength<float>(conversionData);
}
FloatPoint CSSGradientValue::computeEndPoint(CSSPrimitiveValue* horizontal, CSSPrimitiveValue* vertical, const CSSToLengthConversionData& conversionData, const FloatSize& size)
@@ -533,10 +552,10 @@
FloatPoint result;
if (horizontal)
- result.setX(positionFromValue(*horizontal, conversionData, size, true));
+ result.setX(positionFromValue(horizontal, conversionData, size, true));
if (vertical)
- result.setY(positionFromValue(*vertical, conversionData, size, false));
+ result.setY(positionFromValue(vertical, conversionData, size, false));
return result;
}
Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (208061 => 208062)
--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2016-10-28 18:58:23 UTC (rev 208061)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2016-10-28 19:40:44 UTC (rev 208062)
@@ -753,11 +753,11 @@
RefPtr<CSSPrimitiveValue> point = consumeDeprecatedGradientPoint(args, true);
if (!point)
return nullptr;
- result->setFirstX(WTFMove(point));
+ result->setFirstX(point.copyRef());
point = consumeDeprecatedGradientPoint(args, false);
if (!point)
return nullptr;
- result->setFirstY(WTFMove(point));
+ result->setFirstY(point.copyRef());
if (!consumeCommaIncludingWhitespace(args))
return nullptr;
@@ -767,17 +767,17 @@
RefPtr<CSSPrimitiveValue> radius = consumeNumber(args, ValueRangeAll);
if (!radius || !consumeCommaIncludingWhitespace(args))
return nullptr;
- downcast<CSSRadialGradientValue>(result.get())->setFirstRadius(WTFMove(radius));
+ downcast<CSSRadialGradientValue>(result.get())->setFirstRadius(radius.copyRef());
}
point = consumeDeprecatedGradientPoint(args, true);
if (!point)
return nullptr;
- result->setSecondX(WTFMove(point));
+ result->setSecondX(point.copyRef());
point = consumeDeprecatedGradientPoint(args, false);
if (!point)
return nullptr;
- result->setSecondY(WTFMove(point));
+ result->setSecondY(point.copyRef());
// For radial gradients only, we now expect the second radius.
if (isDeprecatedRadialGradient) {
@@ -786,7 +786,7 @@
RefPtr<CSSPrimitiveValue> radius = consumeNumber(args, ValueRangeAll);
if (!radius)
return nullptr;
- downcast<CSSRadialGradientValue>(result.get())->setSecondRadius(WTFMove(radius));
+ downcast<CSSRadialGradientValue>(result.get())->setSecondRadius(radius.copyRef());
}
CSSGradientColorStop stop;
@@ -811,7 +811,12 @@
// Two hints in a row are not allowed.
if (!stop.m_color && (!supportsColorHints || previousStopWasColorHint))
return false;
+
previousStopWasColorHint = !stop.m_color;
+
+ // FIXME-NEWPARSER: This boolean could be removed. Null checking color would be sufficient.
+ stop.isMidpoint = !stop.m_color;
+
stop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll);
if (!stop.m_color && !stop.m_position)
return false;
@@ -835,17 +840,17 @@
if ((centerX || centerY) && !consumeCommaIncludingWhitespace(args))
return nullptr;
- result->setFirstX(WTFMove(centerX));
- result->setFirstY(WTFMove(centerY));
- result->setSecondX(WTFMove(centerX));
- result->setSecondY(WTFMove(centerY));
+ result->setFirstX(centerX.copyRef());
+ result->setFirstY(centerY.copyRef());
+ result->setSecondX(centerX.copyRef());
+ result->setSecondY(centerY.copyRef());
RefPtr<CSSPrimitiveValue> shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(args);
RefPtr<CSSPrimitiveValue> sizeKeyword = consumeIdent<CSSValueClosestSide, CSSValueClosestCorner, CSSValueFarthestSide, CSSValueFarthestCorner, CSSValueContain, CSSValueCover>(args);
if (!shape)
shape = consumeIdent<CSSValueCircle, CSSValueEllipse>(args);
- result->setShape(WTFMove(shape));
- result->setSizingBehavior(WTFMove(sizeKeyword));
+ result->setShape(shape.copyRef());
+ result->setSizingBehavior(sizeKeyword.copyRef());
// Or, two lengths or percentages
if (!shape && !sizeKeyword) {
@@ -856,8 +861,8 @@
if (!verticalSize)
return nullptr;
consumeCommaIncludingWhitespace(args);
- result->setEndHorizontalSize(WTFMove(horizontalSize));
- result->setEndVerticalSize(WTFMove(verticalSize));
+ result->setEndHorizontalSize(horizontalSize.copyRef());
+ result->setEndVerticalSize(verticalSize.copyRef());
}
} else {
consumeCommaIncludingWhitespace(args);
@@ -926,10 +931,10 @@
|| (verticalSize && verticalSize->isCalculatedPercentageWithLength()))
return nullptr;
- result->setShape(WTFMove(shape));
- result->setSizingBehavior(WTFMove(sizeKeyword));
- result->setEndHorizontalSize(WTFMove(horizontalSize));
- result->setEndVerticalSize(WTFMove(verticalSize));
+ result->setShape(shape.copyRef());
+ result->setSizingBehavior(sizeKeyword.copyRef());
+ result->setEndHorizontalSize(horizontalSize.copyRef());
+ result->setEndVerticalSize(verticalSize.copyRef());
RefPtr<CSSPrimitiveValue> centerX;
RefPtr<CSSPrimitiveValue> centerY;
@@ -939,12 +944,12 @@
if (!(centerX && centerY))
return nullptr;
- result->setFirstX(WTFMove(centerX));
- result->setFirstY(WTFMove(centerY));
+ result->setFirstX(centerX.copyRef());
+ result->setFirstY(centerY.copyRef());
// Right now, CSS radial gradients have the same start and end centers.
- result->setSecondX(WTFMove(centerX));
- result->setSecondY(WTFMove(centerY));
+ result->setSecondX(centerX.copyRef());
+ result->setSecondY(centerY.copyRef());
}
if ((shape || sizeKeyword || horizontalSize || centerX || centerY) && !consumeCommaIncludingWhitespace(args))
@@ -974,8 +979,8 @@
endX = consumeIdent<CSSValueLeft, CSSValueRight>(args);
}
- result->setFirstX(WTFMove(endX));
- result->setFirstY(WTFMove(endY));
+ result->setFirstX(endX.copyRef());
+ result->setFirstY(endY.copyRef());
} else {
expectComma = false;
}