2015-05-03 22:32:37 +03:00
|
|
|
/* -*- 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
|
2012-05-21 15:12:37 +04:00
|
|
|
* 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/. */
|
2011-09-26 01:04:27 +04:00
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
#include "SVGTransform.h"
|
2018-12-28 05:47:10 +03:00
|
|
|
|
|
|
|
#include "nsError.h"
|
2013-08-14 10:56:21 +04:00
|
|
|
#include "nsContentUtils.h" // for NS_ENSURE_FINITE
|
2011-09-26 01:04:27 +04:00
|
|
|
#include "nsTextFormatter.h"
|
|
|
|
|
|
|
|
namespace {
|
2013-12-25 12:33:48 +04:00
|
|
|
const double kRadPerDegree = 2.0 * M_PI / 360.0;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace
|
2011-09-26 01:04:27 +04:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
2018-06-26 00:20:54 +03:00
|
|
|
using namespace dom::SVGTransform_Binding;
|
2018-02-18 18:53:13 +03:00
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
void SVGTransform::GetValueAsString(nsAString& aValue) const {
|
2011-09-26 01:04:27 +04:00
|
|
|
switch (mType) {
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_TRANSLATE:
|
2012-03-18 22:24:35 +04:00
|
|
|
// The spec say that if Y is not provided, it is assumed to be zero.
|
2014-06-17 21:35:51 +04:00
|
|
|
if (mMatrix._32 != 0)
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"translate(%g, %g)", mMatrix._31,
|
2014-06-17 21:35:51 +04:00
|
|
|
mMatrix._32);
|
2011-09-26 01:04:27 +04:00
|
|
|
else
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"translate(%g)", mMatrix._31);
|
2011-09-26 01:04:27 +04:00
|
|
|
break;
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_ROTATE:
|
2011-09-26 01:04:27 +04:00
|
|
|
if (mOriginX != 0.0f || mOriginY != 0.0f)
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"rotate(%g, %g, %g)", mAngle,
|
2011-09-26 01:04:27 +04:00
|
|
|
mOriginX, mOriginY);
|
|
|
|
else
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"rotate(%g)", mAngle);
|
2011-09-26 01:04:27 +04:00
|
|
|
break;
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SCALE:
|
2014-06-17 21:35:51 +04:00
|
|
|
if (mMatrix._11 != mMatrix._22)
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"scale(%g, %g)", mMatrix._11,
|
2016-07-21 08:03:25 +03:00
|
|
|
mMatrix._22);
|
2011-09-26 01:04:27 +04:00
|
|
|
else
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"scale(%g)", mMatrix._11);
|
2011-09-26 01:04:27 +04:00
|
|
|
break;
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SKEWX:
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"skewX(%g)", mAngle);
|
2011-09-26 01:04:27 +04:00
|
|
|
break;
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SKEWY:
|
2017-09-06 17:19:05 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"skewY(%g)", mAngle);
|
2011-09-26 01:04:27 +04:00
|
|
|
break;
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_MATRIX:
|
2016-07-21 08:03:25 +03:00
|
|
|
nsTextFormatter::ssprintf(aValue, u"matrix(%g, %g, %g, %g, %g, %g)",
|
2014-06-17 21:35:51 +04:00
|
|
|
mMatrix._11, mMatrix._12, mMatrix._21,
|
|
|
|
mMatrix._22, mMatrix._31, mMatrix._32);
|
2011-09-26 01:04:27 +04:00
|
|
|
break;
|
|
|
|
default:
|
2017-09-06 17:19:05 +03:00
|
|
|
aValue.Truncate();
|
2011-09-26 01:04:27 +04:00
|
|
|
NS_ERROR("unknown transformation type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
void SVGTransform::SetMatrix(const gfxMatrix& aMatrix) {
|
2012-12-23 08:54:24 +04:00
|
|
|
mType = SVG_TRANSFORM_MATRIX;
|
2011-09-26 01:04:27 +04:00
|
|
|
mMatrix = aMatrix;
|
|
|
|
// We set the other members here too, since operator== requires it and
|
|
|
|
// the DOM requires it for mAngle.
|
|
|
|
mAngle = 0.f;
|
|
|
|
mOriginX = 0.f;
|
|
|
|
mOriginY = 0.f;
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
void SVGTransform::SetTranslate(float aTx, float aTy) {
|
2012-12-23 08:54:24 +04:00
|
|
|
mType = SVG_TRANSFORM_TRANSLATE;
|
2017-07-05 18:18:49 +03:00
|
|
|
mMatrix = gfxMatrix::Translation(aTx, aTy);
|
2011-09-26 01:04:27 +04:00
|
|
|
mAngle = 0.f;
|
|
|
|
mOriginX = 0.f;
|
|
|
|
mOriginY = 0.f;
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
void SVGTransform::SetScale(float aSx, float aSy) {
|
2012-12-23 08:54:24 +04:00
|
|
|
mType = SVG_TRANSFORM_SCALE;
|
2017-07-05 18:18:49 +03:00
|
|
|
mMatrix = gfxMatrix::Scaling(aSx, aSy);
|
2011-09-26 01:04:27 +04:00
|
|
|
mAngle = 0.f;
|
|
|
|
mOriginX = 0.f;
|
|
|
|
mOriginY = 0.f;
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
void SVGTransform::SetRotate(float aAngle, float aCx, float aCy) {
|
2012-12-23 08:54:24 +04:00
|
|
|
mType = SVG_TRANSFORM_ROTATE;
|
2017-07-05 18:18:49 +03:00
|
|
|
mMatrix = gfxMatrix::Translation(aCx, aCy)
|
|
|
|
.PreRotate(aAngle * kRadPerDegree)
|
|
|
|
.PreTranslate(-aCx, -aCy);
|
2011-09-26 01:04:27 +04:00
|
|
|
mAngle = aAngle;
|
|
|
|
mOriginX = aCx;
|
|
|
|
mOriginY = aCy;
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
nsresult SVGTransform::SetSkewX(float aAngle) {
|
2013-12-25 12:33:48 +04:00
|
|
|
double ta = tan(aAngle * kRadPerDegree);
|
2012-06-14 05:12:37 +04:00
|
|
|
NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR);
|
2011-09-26 01:04:27 +04:00
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
mType = SVG_TRANSFORM_SKEWX;
|
2017-07-05 18:18:49 +03:00
|
|
|
mMatrix = gfxMatrix();
|
2014-06-17 21:35:51 +04:00
|
|
|
mMatrix._21 = ta;
|
2011-09-26 01:04:27 +04:00
|
|
|
mAngle = aAngle;
|
|
|
|
mOriginX = 0.f;
|
|
|
|
mOriginY = 0.f;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
nsresult SVGTransform::SetSkewY(float aAngle) {
|
2013-12-25 12:33:48 +04:00
|
|
|
double ta = tan(aAngle * kRadPerDegree);
|
2012-06-14 05:12:37 +04:00
|
|
|
NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR);
|
2011-09-26 01:04:27 +04:00
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
mType = SVG_TRANSFORM_SKEWY;
|
2017-07-05 18:18:49 +03:00
|
|
|
mMatrix = gfxMatrix();
|
2014-06-17 21:35:51 +04:00
|
|
|
mMatrix._12 = ta;
|
2011-09-26 01:04:27 +04:00
|
|
|
mAngle = aAngle;
|
|
|
|
mOriginX = 0.f;
|
|
|
|
mOriginY = 0.f;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
SVGTransformSMILData::SVGTransformSMILData(const SVGTransform& aTransform)
|
2011-09-26 01:04:31 +04:00
|
|
|
: mTransformType(aTransform.Type()) {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(mTransformType >= SVG_TRANSFORM_MATRIX &&
|
|
|
|
mTransformType <= SVG_TRANSFORM_SKEWY,
|
|
|
|
"Unexpected transform type");
|
2011-09-26 01:04:31 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
for (uint32_t i = 0; i < NUM_STORED_PARAMS; ++i) {
|
2011-09-26 01:04:31 +04:00
|
|
|
mParams[i] = 0.f;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (mTransformType) {
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_MATRIX: {
|
2014-03-18 06:41:35 +04:00
|
|
|
const gfxMatrix& mx = aTransform.GetMatrix();
|
2014-06-17 21:35:51 +04:00
|
|
|
mParams[0] = static_cast<float>(mx._11);
|
|
|
|
mParams[1] = static_cast<float>(mx._12);
|
|
|
|
mParams[2] = static_cast<float>(mx._21);
|
|
|
|
mParams[3] = static_cast<float>(mx._22);
|
|
|
|
mParams[4] = static_cast<float>(mx._31);
|
|
|
|
mParams[5] = static_cast<float>(mx._32);
|
2011-09-26 01:04:31 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_TRANSLATE: {
|
2014-03-18 06:41:35 +04:00
|
|
|
const gfxMatrix& mx = aTransform.GetMatrix();
|
2014-06-17 21:35:51 +04:00
|
|
|
mParams[0] = static_cast<float>(mx._31);
|
|
|
|
mParams[1] = static_cast<float>(mx._32);
|
2011-09-26 01:04:31 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SCALE: {
|
2014-03-18 06:41:35 +04:00
|
|
|
const gfxMatrix& mx = aTransform.GetMatrix();
|
2014-06-17 21:35:51 +04:00
|
|
|
mParams[0] = static_cast<float>(mx._11);
|
|
|
|
mParams[1] = static_cast<float>(mx._22);
|
2011-09-26 01:04:31 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_ROTATE:
|
2011-09-26 01:04:31 +04:00
|
|
|
mParams[0] = aTransform.Angle();
|
|
|
|
aTransform.GetRotationOrigin(mParams[1], mParams[2]);
|
|
|
|
break;
|
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SKEWX:
|
|
|
|
case SVG_TRANSFORM_SKEWY:
|
2011-09-26 01:04:31 +04:00
|
|
|
mParams[0] = aTransform.Angle();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected transform type");
|
2011-09-26 01:04:31 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-29 12:15:40 +03:00
|
|
|
SVGTransform SVGTransformSMILData::ToSVGTransform() const {
|
|
|
|
SVGTransform result;
|
2011-09-26 01:04:31 +04:00
|
|
|
|
|
|
|
switch (mTransformType) {
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_MATRIX:
|
2011-09-26 01:04:31 +04:00
|
|
|
result.SetMatrix(gfxMatrix(mParams[0], mParams[1], mParams[2], mParams[3],
|
|
|
|
mParams[4], mParams[5]));
|
|
|
|
break;
|
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_TRANSLATE:
|
2011-09-26 01:04:31 +04:00
|
|
|
result.SetTranslate(mParams[0], mParams[1]);
|
|
|
|
break;
|
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SCALE:
|
2011-09-26 01:04:31 +04:00
|
|
|
result.SetScale(mParams[0], mParams[1]);
|
|
|
|
break;
|
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_ROTATE:
|
2011-09-26 01:04:31 +04:00
|
|
|
result.SetRotate(mParams[0], mParams[1], mParams[2]);
|
|
|
|
break;
|
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SKEWX:
|
2011-09-26 01:04:31 +04:00
|
|
|
result.SetSkewX(mParams[0]);
|
|
|
|
break;
|
|
|
|
|
2012-12-23 08:54:24 +04:00
|
|
|
case SVG_TRANSFORM_SKEWY:
|
2011-09-26 01:04:31 +04:00
|
|
|
result.SetSkewY(mParams[0]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected transform type");
|
2011-09-26 01:04:31 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-09-26 01:04:27 +04:00
|
|
|
} // namespace mozilla
|