Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(326)

Unified Diff: third_party/WebKit/Source/core/svg/SVGTransformList.cpp

Issue 1643243002: Refactor parsing in SVGTransformList (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix signedness "issue". Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/svg/SVGTransformList.cpp
diff --git a/third_party/WebKit/Source/core/svg/SVGTransformList.cpp b/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
index 10ec3125c7459f9d29adf03d1b64f4aa411e703e..ad281f0b6720f545954effb619f98c7a166c216b 100644
--- a/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
@@ -46,9 +46,7 @@ PassRefPtrWillBeRawPtr<SVGTransform> SVGTransformList::consolidate()
if (!concatenate(matrix))
return SVGTransform::create();
- RefPtrWillBeRawPtr<SVGTransform> transform = SVGTransform::create(matrix);
- clear();
- return appendItem(transform);
+ return initialize(SVGTransform::create(matrix));
}
bool SVGTransformList::concatenate(AffineTransform& result) const
@@ -74,111 +72,122 @@ const LChar rotateDesc[] = {'r', 'o', 't', 'a', 't', 'e'};
const LChar matrixDesc[] = {'m', 'a', 't', 'r', 'i', 'x'};
template<typename CharType>
-bool parseAndSkipTransformType(const CharType*& ptr, const CharType* end, SVGTransformType& type)
+SVGTransformType parseAndSkipTransformType(const CharType*& ptr, const CharType* end)
{
if (ptr >= end)
- return false;
+ return SVG_TRANSFORM_UNKNOWN;
if (*ptr == 's') {
if (skipString(ptr, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc)))
- type = SVG_TRANSFORM_SKEWX;
- else if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc)))
- type = SVG_TRANSFORM_SKEWY;
- else if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc)))
- type = SVG_TRANSFORM_SCALE;
- else
- return false;
- } else if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDesc))) {
- type = SVG_TRANSFORM_TRANSLATE;
- } else if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc))) {
- type = SVG_TRANSFORM_ROTATE;
- } else if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc))) {
- type = SVG_TRANSFORM_MATRIX;
- } else {
- return false;
+ return SVG_TRANSFORM_SKEWX;
+ if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc)))
+ return SVG_TRANSFORM_SKEWY;
+ if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc)))
+ return SVG_TRANSFORM_SCALE;
+
+ return SVG_TRANSFORM_UNKNOWN;
}
- return true;
+ if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDesc)))
+ return SVG_TRANSFORM_TRANSLATE;
+ if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc)))
+ return SVG_TRANSFORM_ROTATE;
+ if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc)))
+ return SVG_TRANSFORM_MATRIX;
+
+ return SVG_TRANSFORM_UNKNOWN;
}
+// These should be kept in sync with enum SVGTransformType
+const unsigned requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1};
+const unsigned optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0};
+static_assert(SVG_TRANSFORM_UNKNOWN == 0, "index of SVG_TRANSFORM_UNKNOWN has changed");
+static_assert(SVG_TRANSFORM_MATRIX == 1, "index of SVG_TRANSFORM_MATRIX has changed");
+static_assert(SVG_TRANSFORM_TRANSLATE == 2, "index of SVG_TRANSFORM_TRANSLATE has changed");
+static_assert(SVG_TRANSFORM_SCALE == 3, "index of SVG_TRANSFORM_SCALE has changed");
+static_assert(SVG_TRANSFORM_ROTATE == 4, "index of SVG_TRANSFORM_ROTATE has changed");
+static_assert(SVG_TRANSFORM_SKEWX == 5, "index of SVG_TRANSFORM_SKEWX has changed");
+static_assert(SVG_TRANSFORM_SKEWY == 6, "index of SVG_TRANSFORM_SKEWY has changed");
+static_assert(WTF_ARRAY_LENGTH(requiredValuesForType) - 1 == SVG_TRANSFORM_SKEWY, "the number of transform types have changed");
+static_assert(WTF_ARRAY_LENGTH(requiredValuesForType) == WTF_ARRAY_LENGTH(optionalValuesForType), "the arrays should have the same number of elements");
+
+const unsigned kMaxTransformArguments = 6;
+
+using TransformArguments = Vector<float, kMaxTransformArguments>;
+
template<typename CharType>
-int parseTransformParamList(const CharType*& ptr, const CharType* end, float* values, int required, int optional)
+int parseTransformArgumentsForType(
+ SVGTransformType type,
+ const CharType*& ptr, const CharType* end,
+ TransformArguments& arguments)
{
- int parsedParams = 0;
- int maxPossibleParams = required + optional;
+ const size_t required = requiredValuesForType[type];
+ const size_t optional = optionalValuesForType[type];
+ const size_t maxPossibleParams = required + optional;
+ ASSERT(maxPossibleParams <= kMaxTransformArguments);
+ ASSERT(arguments.isEmpty());
bool trailingDelimiter = false;
- skipOptionalSVGSpaces(ptr, end);
- while (parsedParams < maxPossibleParams) {
- if (!parseNumber(ptr, end, values[parsedParams], DisallowWhitespace))
+ while (arguments.size() < maxPossibleParams) {
+ float argumentValue = 0;
+ if (!parseNumber(ptr, end, argumentValue, AllowLeadingWhitespace))
break;
- ++parsedParams;
+ arguments.append(argumentValue);
+ trailingDelimiter = false;
+
+ if (arguments.size() == maxPossibleParams)
+ break;
if (skipOptionalSVGSpaces(ptr, end) && *ptr == ',') {
++ptr;
- skipOptionalSVGSpaces(ptr, end);
-
trailingDelimiter = true;
- } else {
- trailingDelimiter = false;
}
}
- if (trailingDelimiter || !(parsedParams == required || parsedParams == maxPossibleParams))
+ if (trailingDelimiter || !(arguments.size() == required || arguments.size() == maxPossibleParams))
return -1;
- return parsedParams;
+ return safeCast<int>(arguments.size());
}
-// These should be kept in sync with enum SVGTransformType
-const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1};
-const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0};
-
-template<typename CharType>
-PassRefPtrWillBeRawPtr<SVGTransform> parseTransformOfType(unsigned type, const CharType*& ptr, const CharType* end)
+PassRefPtrWillBeRawPtr<SVGTransform> createTransformFromValues(SVGTransformType type, const TransformArguments& arguments)
{
- if (type == SVG_TRANSFORM_UNKNOWN)
- return nullptr;
-
- int valueCount = 0;
- float values[] = {0, 0, 0, 0, 0, 0};
- if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0) {
- return nullptr;
- }
-
RefPtrWillBeRawPtr<SVGTransform> transform = SVGTransform::create();
-
switch (type) {
case SVG_TRANSFORM_SKEWX:
- transform->setSkewX(values[0]);
+ transform->setSkewX(arguments[0]);
break;
case SVG_TRANSFORM_SKEWY:
- transform->setSkewY(values[0]);
+ transform->setSkewY(arguments[0]);
break;
case SVG_TRANSFORM_SCALE:
- if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
- transform->setScale(values[0], values[0]);
+ // Spec: if only one param given, assume uniform scaling.
+ if (arguments.size() == 1)
+ transform->setScale(arguments[0], arguments[0]);
else
- transform->setScale(values[0], values[1]);
+ transform->setScale(arguments[0], arguments[1]);
break;
case SVG_TRANSFORM_TRANSLATE:
- if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
- transform->setTranslate(values[0], 0);
+ // Spec: if only one param given, assume 2nd param to be 0.
+ if (arguments.size() == 1)
+ transform->setTranslate(arguments[0], 0);
else
- transform->setTranslate(values[0], values[1]);
+ transform->setTranslate(arguments[0], arguments[1]);
break;
case SVG_TRANSFORM_ROTATE:
- if (valueCount == 1)
- transform->setRotate(values[0], 0, 0);
+ if (arguments.size() == 1)
+ transform->setRotate(arguments[0], 0, 0);
else
- transform->setRotate(values[0], values[1], values[2]);
+ transform->setRotate(arguments[0], arguments[1], arguments[2]);
break;
case SVG_TRANSFORM_MATRIX:
- transform->setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
+ transform->setMatrix(AffineTransform(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]));
+ break;
+ case SVG_TRANSFORM_UNKNOWN:
+ ASSERT_NOT_REACHED();
break;
}
-
return transform.release();
}
@@ -190,36 +199,34 @@ bool SVGTransformList::parseInternal(const CharType*& ptr, const CharType* end)
clear();
bool delimParsed = false;
- while (ptr < end) {
+ while (skipOptionalSVGSpaces(ptr, end)) {
delimParsed = false;
- SVGTransformType transformType = SVG_TRANSFORM_UNKNOWN;
- skipOptionalSVGSpaces(ptr, end);
- if (!parseAndSkipTransformType(ptr, end, transformType))
+ SVGTransformType transformType = parseAndSkipTransformType(ptr, end);
+ if (transformType == SVG_TRANSFORM_UNKNOWN)
return false;
if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(')
return false;
ptr++;
- RefPtrWillBeRawPtr<SVGTransform> transform = parseTransformOfType(transformType, ptr, end);
- if (!transform)
+ TransformArguments arguments;
+ int valueCount = parseTransformArgumentsForType(transformType, ptr, end, arguments);
+ if (valueCount < 0)
return false;
+ ASSERT(static_cast<unsigned>(valueCount) >= requiredValuesForType[transformType]);
if (!skipOptionalSVGSpaces(ptr, end) || *ptr != ')')
return false;
ptr++;
- append(transform.release());
+ append(createTransformFromValues(transformType, arguments));
- skipOptionalSVGSpaces(ptr, end);
- if (ptr < end && *ptr == ',') {
- delimParsed = true;
+ if (skipOptionalSVGSpaces(ptr, end) && *ptr == ',') {
++ptr;
- skipOptionalSVGSpaces(ptr, end);
+ delimParsed = true;
}
}
-
return !delimParsed;
}
@@ -237,17 +244,14 @@ SVGTransformType parseTransformType(const String& string)
{
if (string.isEmpty())
return SVG_TRANSFORM_UNKNOWN;
- SVGTransformType type = SVG_TRANSFORM_UNKNOWN;
if (string.is8Bit()) {
const LChar* ptr = string.characters8();
const LChar* end = ptr + string.length();
- parseAndSkipTransformType(ptr, end, type);
- } else {
- const UChar* ptr = string.characters16();
- const UChar* end = ptr + string.length();
- parseAndSkipTransformType(ptr, end, type);
+ return parseAndSkipTransformType(ptr, end);
}
- return type;
+ const UChar* ptr = string.characters16();
+ const UChar* end = ptr + string.length();
+ return parseAndSkipTransformType(ptr, end);
}
String SVGTransformList::valueAsString() const
@@ -300,21 +304,25 @@ PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGTransformList::cloneForAnimation(cons
PassRefPtrWillBeRawPtr<SVGTransformList> SVGTransformList::create(SVGTransformType transformType, const String& value)
{
- RefPtrWillBeRawPtr<SVGTransform> transform = nullptr;
+ TransformArguments arguments;
+ bool atEndOfValue = false;
+ int valueCount = -1;
if (value.isEmpty()) {
} else if (value.is8Bit()) {
const LChar* ptr = value.characters8();
const LChar* end = ptr + value.length();
- transform = parseTransformOfType(transformType, ptr, end);
+ valueCount = parseTransformArgumentsForType(transformType, ptr, end, arguments);
+ atEndOfValue = !skipOptionalSVGSpaces(ptr, end);
} else {
const UChar* ptr = value.characters16();
const UChar* end = ptr + value.length();
- transform = parseTransformOfType(transformType, ptr, end);
+ valueCount = parseTransformArgumentsForType(transformType, ptr, end, arguments);
+ atEndOfValue = !skipOptionalSVGSpaces(ptr, end);
}
RefPtrWillBeRawPtr<SVGTransformList> svgTransformList = SVGTransformList::create();
- if (transform)
- svgTransformList->append(transform);
+ if (atEndOfValue && valueCount > 0)
+ svgTransformList->append(createTransformFromValues(transformType, arguments));
return svgTransformList.release();
}
@@ -332,8 +340,7 @@ void SVGTransformList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGEle
RefPtrWillBeRawPtr<SVGTransform> toTransform = otherList->at(0);
ASSERT(fromTransform->transformType() == toTransform->transformType());
- clear();
- append(SVGTransformDistance::addSVGTransforms(fromTransform, toTransform));
+ initialize(SVGTransformDistance::addSVGTransforms(fromTransform, toTransform));
}
void SVGTransformList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698