Bug 1408310 - Part 2: Use CSS parser for DOMMatrix::SetMatrixValue.
Now, we use the CSS parser, instead of SVG parser, so we also need to
update the tests of DOMMatrix, i.e. we don't support unitless tranform
list on CSS parser.
MozReview-Commit-ID: 86F992rIa4J
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -1,25 +1,24 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#include "mozilla/dom/DOMMatrix.h"
+
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMMatrixBinding.h"
+#include "mozilla/dom/DOMPoint.h"
#include "mozilla/dom/DOMPointBinding.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ToJSValue.h"
-
-#include "mozilla/dom/DOMPoint.h"
-#include "mozilla/dom/DOMMatrix.h"
-
-#include "SVGTransformListParser.h"
-#include "SVGTransform.h"
+#include "nsCSSParser.h"
+#include "nsStyleTransformMatrix.h"
#include <math.h>
namespace mozilla {
namespace dom {
static const double radPerDegree = 2.0 * M_PI / 360.0;
@@ -650,35 +649,66 @@ DOMMatrix::InvertSelf()
}
return this;
}
DOMMatrix*
DOMMatrix::SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv)
{
- SVGTransformListParser parser(aTransformList);
- if (!parser.Parse()) {
+ // An empty string is a no-op.
+ if (aTransformList.IsEmpty()) {
+ return this;
+ }
+
+ nsCSSValue value;
+ nsCSSParser parser;
+ bool parseSuccess = parser.ParseTransformProperty(aTransformList,
+ true,
+ value);
+ if (!parseSuccess) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
- } else {
+ return nullptr;
+ }
+
+ // A value of "none" results in a 2D identity matrix.
+ if (value.GetUnit() == eCSSUnit_None) {
mMatrix3D = nullptr;
mMatrix2D = new gfx::Matrix();
- gfxMatrix result;
- const nsTArray<nsSVGTransform>& mItems = parser.GetTransformList();
+ return this;
+ }
- for (uint32_t i = 0; i < mItems.Length(); ++i) {
- result.PreMultiply(mItems[i].GetMatrix());
- }
+ // A value other than a transform-list is a syntax error.
+ if (value.GetUnit() != eCSSUnit_SharedList) {
+ aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+ return nullptr;
+ }
- SetA(result._11);
- SetB(result._12);
- SetC(result._21);
- SetD(result._22);
- SetE(result._31);
- SetF(result._32);
+ RuleNodeCacheConditions dummy;
+ nsStyleTransformMatrix::TransformReferenceBox dummyBox;
+ bool contains3dTransform = false;
+ gfx::Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms(
+ value.GetSharedListValue()->mHead,
+ nullptr, nullptr, dummy, dummyBox,
+ nsPresContext::AppUnitsPerCSSPixel(),
+ &contains3dTransform);
+
+ if (!contains3dTransform) {
+ mMatrix3D = nullptr;
+ mMatrix2D = new gfx::Matrix();
+
+ SetA(transform._11);
+ SetB(transform._12);
+ SetC(transform._21);
+ SetD(transform._22);
+ SetE(transform._41);
+ SetF(transform._42);
+ } else {
+ mMatrix3D = new gfx::Matrix4x4(transform);
+ mMatrix2D = nullptr;
}
return this;
}
JSObject*
DOMMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
--- a/dom/base/WebKitCSSMatrix.cpp
+++ b/dom/base/WebKitCSSMatrix.cpp
@@ -4,19 +4,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/WebKitCSSMatrix.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/WebKitCSSMatrixBinding.h"
#include "mozilla/Preferences.h"
-#include "nsCSSParser.h"
#include "nsPresContext.h"
-#include "nsStyleTransformMatrix.h"
#include "RuleNodeCacheConditions.h"
namespace mozilla {
namespace dom {
static const double sRadPerDegree = 2.0 * M_PI / 360.0;
bool
@@ -56,68 +54,17 @@ WebKitCSSMatrix::WrapObject(JSContext* a
{
return WebKitCSSMatrixBinding::Wrap(aCx, this, aGivenProto);
}
WebKitCSSMatrix*
WebKitCSSMatrix::SetMatrixValue(const nsAString& aTransformList,
ErrorResult& aRv)
{
- // An empty string is a no-op.
- if (aTransformList.IsEmpty()) {
- return this;
- }
-
- nsCSSValue value;
- nsCSSParser parser;
- bool parseSuccess = parser.ParseTransformProperty(aTransformList,
- true,
- value);
- if (!parseSuccess) {
- aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
- return nullptr;
- }
-
- // A value of "none" results in a 2D identity matrix.
- if (value.GetUnit() == eCSSUnit_None) {
- mMatrix3D = nullptr;
- mMatrix2D = new gfx::Matrix();
- return this;
- }
-
- // A value other than a transform-list is a syntax error.
- if (value.GetUnit() != eCSSUnit_SharedList) {
- aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
- return nullptr;
- }
-
- RuleNodeCacheConditions dummy;
- nsStyleTransformMatrix::TransformReferenceBox dummyBox;
- bool contains3dTransform = false;
- gfx::Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms(
- value.GetSharedListValue()->mHead,
- nullptr, nullptr, dummy, dummyBox,
- nsPresContext::AppUnitsPerCSSPixel(),
- &contains3dTransform);
-
- if (!contains3dTransform) {
- mMatrix3D = nullptr;
- mMatrix2D = new gfx::Matrix();
-
- SetA(transform._11);
- SetB(transform._12);
- SetC(transform._21);
- SetD(transform._22);
- SetE(transform._41);
- SetF(transform._42);
- } else {
- mMatrix3D = new gfx::Matrix4x4(transform);
- mMatrix2D = nullptr;
- }
-
+ DOMMatrix::SetMatrixValue(aTransformList, aRv);
return this;
}
already_AddRefed<WebKitCSSMatrix>
WebKitCSSMatrix::Multiply(const WebKitCSSMatrix& other) const
{
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
retval->MultiplySelf(other);
--- a/dom/tests/mochitest/general/test_DOMMatrix.html
+++ b/dom/tests/mochitest/general/test_DOMMatrix.html
@@ -691,23 +691,23 @@ function test3D()
m2 = new Matrix3D();
m2 = m2.multiply(m2.translate(2,3,4)).multiply(m2.scale(1.2, 2.3, 3.4));
m2 = m2.inverse(m2).swap();
ok(CompareMatrix(m2, m), "translate + scale in inverted 3d didn't match, expected: " + formatMatrix(m2.m) + ", got: " + formatMatrix(m));
}
function testParsing()
{
- var m = new DOMMatrix("translate(10, 20) scale(.5, 2) rotate(45)");
+ var m = new DOMMatrix("translate(10px, 20px) scale(.5, 2) rotate(45deg)");
var m2 = new DOMMatrix();
m2.translateSelf(10, 20).scaleNonUniformSelf(.5,2).rotateSelf(45);
ok(CompareDOMMatrix(m2, m), "string parsing didn't match");
m = new DOMMatrix();
- m.setMatrixValue("translate(10, 20) scale(.5, 2) rotate(45)");
+ m.setMatrixValue("translate(10px, 20px) scale(.5, 2) rotate(45deg)");
ok(CompareDOMMatrix(m2, m), "string parsing didn't match");
}
function testStringify() {
var m = new DOMMatrix();
var s = "" + m;
ok(s == "matrix" + formatMatrix(m), "stringifier 1 produced wrong result: " + s);
--- a/testing/web-platform/meta/css/geometry/DOMMatrix-001.html.ini
+++ b/testing/web-platform/meta/css/geometry/DOMMatrix-001.html.ini
@@ -85,19 +85,16 @@
expected: FAIL
[new DOMMatrix(sequence) 6 elements]
expected: FAIL
[new DOMMatrix("scale(2) translateX(5px) translateY(5px)")]
expected: FAIL
- [new DOMMatrix(" ")]
- expected: FAIL
-
[new DOMMatrix(sequence)]
expected: FAIL
[new DOMMatrix(matrix)]
expected: FAIL
[new DOMMatrix(sequence) 17 elements]
expected: FAIL
@@ -250,22 +247,16 @@
expected: FAIL
[new DOMMatrix("scale(2) translateX(calc(2 * 2.5px)) translateY(5px)")]
expected: FAIL
[new DOMMatrix("scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)")]
expected: FAIL
- [new DOMMatrix("rotate(5)")]
- expected: FAIL
-
- [new DOMMatrix("rotate(5, 5, 5)")]
- expected: FAIL
-
[new DOMMatrixReadOnly("scale(2, 2) translateX(5px) translateY(5px)")]
expected: FAIL
[new DOMMatrixReadOnly("scale(2)translateX(5px)translateY(5px)")]
expected: FAIL
[new DOMMatrixReadOnly("scale(2) translateX(calc(2 * 2.5px)) translateY(5px)")]
expected: FAIL