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

Unified Diff: Source/core/svg/SVGParserUtilities.cpp

Issue 61753005: Remove SVGLocatable and SVGTransformable (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix nits Created 7 years, 1 month 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
Index: Source/core/svg/SVGParserUtilities.cpp
diff --git a/Source/core/svg/SVGParserUtilities.cpp b/Source/core/svg/SVGParserUtilities.cpp
index cf7c225cda92c206228cb35cc3bfeef47450c3a4..262ef622f91ae42975f0ee97eff67734ffdba35e 100644
--- a/Source/core/svg/SVGParserUtilities.cpp
+++ b/Source/core/svg/SVGParserUtilities.cpp
@@ -25,7 +25,9 @@
#include "core/dom/Document.h"
#include "core/svg/SVGPointList.h"
+#include "core/svg/SVGTransformList.h"
#include "platform/geometry/FloatRect.h"
+#include "platform/transforms/AffineTransform.h"
#include "wtf/ASCIICType.h"
#include <limits>
@@ -559,4 +561,207 @@ bool parseFloatPoint3(const CharType*& current, const CharType* end, FloatPoint&
template bool parseFloatPoint3(const LChar*& current, const LChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3);
template bool parseFloatPoint3(const UChar*& current, const UChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3);
+template<typename CharType>
+static int parseTransformParamList(const CharType*& ptr, const CharType* end, float* values, int required, int optional)
+{
+ int optionalParams = 0, requiredParams = 0;
+
+ if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(')
+ return -1;
+
+ ptr++;
+
+ skipOptionalSVGSpaces(ptr, end);
+
+ while (requiredParams < required) {
+ if (ptr >= end || !parseNumber(ptr, end, values[requiredParams], false))
+ return -1;
+ requiredParams++;
+ if (requiredParams < required)
+ skipOptionalSVGSpacesOrDelimiter(ptr, end);
+ }
+ if (!skipOptionalSVGSpaces(ptr, end))
+ return -1;
+
+ bool delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end);
+
+ if (ptr >= end)
+ return -1;
+
+ if (*ptr == ')') { // skip optionals
+ ptr++;
+ if (delimParsed)
+ return -1;
+ } else {
+ while (optionalParams < optional) {
+ if (ptr >= end || !parseNumber(ptr, end, values[requiredParams + optionalParams], false))
+ return -1;
+ optionalParams++;
+ if (optionalParams < optional)
+ skipOptionalSVGSpacesOrDelimiter(ptr, end);
+ }
+
+ if (!skipOptionalSVGSpaces(ptr, end))
+ return -1;
+
+ delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end);
+
+ if (ptr >= end || *ptr != ')' || delimParsed)
+ return -1;
+ ptr++;
+ }
+
+ return requiredParams + optionalParams;
+}
+
+// These should be kept in sync with enum SVGTransformType
+static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1};
+static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0};
+
+template<typename CharType>
+static bool parseTransformValueInternal(unsigned type, const CharType*& ptr, const CharType* end, SVGTransform& transform)
+{
+ if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
+ return false;
+
+ int valueCount = 0;
+ float values[] = {0, 0, 0, 0, 0, 0};
+ if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0)
+ return false;
+
+ switch (type) {
+ case SVGTransform::SVG_TRANSFORM_SKEWX:
+ transform.setSkewX(values[0]);
+ break;
+ case SVGTransform::SVG_TRANSFORM_SKEWY:
+ transform.setSkewY(values[0]);
+ break;
+ case SVGTransform::SVG_TRANSFORM_SCALE:
+ if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
+ transform.setScale(values[0], values[0]);
+ else
+ transform.setScale(values[0], values[1]);
+ break;
+ case SVGTransform::SVG_TRANSFORM_TRANSLATE:
+ if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
+ transform.setTranslate(values[0], 0);
+ else
+ transform.setTranslate(values[0], values[1]);
+ break;
+ case SVGTransform::SVG_TRANSFORM_ROTATE:
+ if (valueCount == 1)
+ transform.setRotate(values[0], 0, 0);
+ else
+ transform.setRotate(values[0], values[1], values[2]);
+ break;
+ case SVGTransform::SVG_TRANSFORM_MATRIX:
+ transform.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
+ break;
+ }
+
+ return true;
+}
+
+bool parseTransformValue(unsigned type, const LChar*& ptr, const LChar* end, SVGTransform& transform)
+{
+ return parseTransformValueInternal(type, ptr, end, transform);
+}
+
+bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform)
+{
+ return parseTransformValueInternal(type, ptr, end, transform);
+}
+
+static const LChar skewXDesc[] = {'s', 'k', 'e', 'w', 'X'};
+static const LChar skewYDesc[] = {'s', 'k', 'e', 'w', 'Y'};
+static const LChar scaleDesc[] = {'s', 'c', 'a', 'l', 'e'};
+static const LChar translateDesc[] = {'t', 'r', 'a', 'n', 's', 'l', 'a', 't', 'e'};
+static const LChar rotateDesc[] = {'r', 'o', 't', 'a', 't', 'e'};
+static const LChar matrixDesc[] = {'m', 'a', 't', 'r', 'i', 'x'};
+
+template<typename CharType>
+static inline bool parseAndSkipType(const CharType*& ptr, const CharType* end, unsigned short& type)
+{
+ if (ptr >= end)
+ return false;
+
+ if (*ptr == 's') {
+ if (skipString(ptr, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc)))
+ type = SVGTransform::SVG_TRANSFORM_SKEWX;
+ else if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc)))
+ type = SVGTransform::SVG_TRANSFORM_SKEWY;
+ else if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc)))
+ type = SVGTransform::SVG_TRANSFORM_SCALE;
+ else
+ return false;
+ } else if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDesc)))
+ type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
+ else if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc)))
+ type = SVGTransform::SVG_TRANSFORM_ROTATE;
+ else if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc)))
+ type = SVGTransform::SVG_TRANSFORM_MATRIX;
+ else
+ return false;
+
+ return true;
+}
+
+SVGTransform::SVGTransformType parseTransformType(const String& string)
+{
+ if (string.isEmpty())
+ return SVGTransform::SVG_TRANSFORM_UNKNOWN;
+ unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+ if (string.is8Bit()) {
+ const LChar* ptr = string.characters8();
+ const LChar* end = ptr + string.length();
+ parseAndSkipType(ptr, end, type);
+ } else {
+ const UChar* ptr = string.characters16();
+ const UChar* end = ptr + string.length();
+ parseAndSkipType(ptr, end, type);
+ }
+ return static_cast<SVGTransform::SVGTransformType>(type);
+}
+
+template<typename CharType>
+bool parseTransformAttributeInternal(SVGTransformList& list, const CharType*& ptr, const CharType* end, TransformParsingMode mode)
+{
+ if (mode == ClearList)
+ list.clear();
+
+ bool delimParsed = false;
+ while (ptr < end) {
+ delimParsed = false;
+ unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+ skipOptionalSVGSpaces(ptr, end);
+
+ if (!parseAndSkipType(ptr, end, type))
+ return false;
+
+ SVGTransform transform;
+ if (!parseTransformValue(type, ptr, end, transform))
+ return false;
+
+ list.append(transform);
+ skipOptionalSVGSpaces(ptr, end);
+ if (ptr < end && *ptr == ',') {
+ delimParsed = true;
+ ++ptr;
+ }
+ skipOptionalSVGSpaces(ptr, end);
+ }
+
+ return !delimParsed;
+}
+
+bool parseTransformAttribute(SVGTransformList& list, const LChar*& ptr, const LChar* end, TransformParsingMode mode)
+{
+ return parseTransformAttributeInternal(list, ptr, end, mode);
+}
+
+bool parseTransformAttribute(SVGTransformList& list, const UChar*& ptr, const UChar* end, TransformParsingMode mode)
+{
+ return parseTransformAttributeInternal(list, ptr, end, mode);
+}
+
}

Powered by Google App Engine
This is Rietveld 408576698