123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "nsError.h"
- #include "nsSVGTransform.h"
- #include "nsContentUtils.h" // for NS_ENSURE_FINITE
- #include "nsTextFormatter.h"
- namespace {
- const double kRadPerDegree = 2.0 * M_PI / 360.0;
- } // namespace
- namespace mozilla {
- void
- nsSVGTransform::GetValueAsString(nsAString& aValue) const
- {
- char16_t buf[256];
- switch (mType) {
- case SVG_TRANSFORM_TRANSLATE:
- // The spec say that if Y is not provided, it is assumed to be zero.
- if (mMatrix._32 != 0)
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"translate(%g, %g)",
- mMatrix._31, mMatrix._32);
- else
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"translate(%g)",
- mMatrix._31);
- break;
- case SVG_TRANSFORM_ROTATE:
- if (mOriginX != 0.0f || mOriginY != 0.0f)
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"rotate(%g, %g, %g)",
- mAngle, mOriginX, mOriginY);
- else
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"rotate(%g)", mAngle);
- break;
- case SVG_TRANSFORM_SCALE:
- if (mMatrix._11 != mMatrix._22)
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"scale(%g, %g)", mMatrix._11, mMatrix._22);
- else
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"scale(%g)", mMatrix._11);
- break;
- case SVG_TRANSFORM_SKEWX:
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"skewX(%g)", mAngle);
- break;
- case SVG_TRANSFORM_SKEWY:
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"skewY(%g)", mAngle);
- break;
- case SVG_TRANSFORM_MATRIX:
- nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(char16_t),
- u"matrix(%g, %g, %g, %g, %g, %g)",
- mMatrix._11, mMatrix._12,
- mMatrix._21, mMatrix._22,
- mMatrix._31, mMatrix._32);
- break;
- default:
- buf[0] = '\0';
- NS_ERROR("unknown transformation type");
- break;
- }
- aValue.Assign(buf);
- }
- void
- nsSVGTransform::SetMatrix(const gfxMatrix& aMatrix)
- {
- mType = SVG_TRANSFORM_MATRIX;
- 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;
- }
- void
- nsSVGTransform::SetTranslate(float aTx, float aTy)
- {
- mType = SVG_TRANSFORM_TRANSLATE;
- mMatrix.Reset();
- mMatrix._31 = aTx;
- mMatrix._32 = aTy;
- mAngle = 0.f;
- mOriginX = 0.f;
- mOriginY = 0.f;
- }
- void
- nsSVGTransform::SetScale(float aSx, float aSy)
- {
- mType = SVG_TRANSFORM_SCALE;
- mMatrix.Reset();
- mMatrix._11 = aSx;
- mMatrix._22 = aSy;
- mAngle = 0.f;
- mOriginX = 0.f;
- mOriginY = 0.f;
- }
- void
- nsSVGTransform::SetRotate(float aAngle, float aCx, float aCy)
- {
- mType = SVG_TRANSFORM_ROTATE;
- mMatrix.Reset();
- mMatrix.Translate(aCx, aCy);
- mMatrix.Rotate(aAngle*kRadPerDegree);
- mMatrix.Translate(-aCx, -aCy);
- mAngle = aAngle;
- mOriginX = aCx;
- mOriginY = aCy;
- }
- nsresult
- nsSVGTransform::SetSkewX(float aAngle)
- {
- double ta = tan(aAngle*kRadPerDegree);
- NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR);
- mType = SVG_TRANSFORM_SKEWX;
- mMatrix.Reset();
- mMatrix._21 = ta;
- mAngle = aAngle;
- mOriginX = 0.f;
- mOriginY = 0.f;
- return NS_OK;
- }
- nsresult
- nsSVGTransform::SetSkewY(float aAngle)
- {
- double ta = tan(aAngle*kRadPerDegree);
- NS_ENSURE_FINITE(ta, NS_ERROR_RANGE_ERR);
- mType = SVG_TRANSFORM_SKEWY;
- mMatrix.Reset();
- mMatrix._12 = ta;
- mAngle = aAngle;
- mOriginX = 0.f;
- mOriginY = 0.f;
- return NS_OK;
- }
- SVGTransformSMILData::SVGTransformSMILData(const nsSVGTransform& aTransform)
- : mTransformType(aTransform.Type())
- {
- MOZ_ASSERT(mTransformType >= SVG_TRANSFORM_MATRIX &&
- mTransformType <= SVG_TRANSFORM_SKEWY,
- "Unexpected transform type");
- for (uint32_t i = 0; i < NUM_STORED_PARAMS; ++i) {
- mParams[i] = 0.f;
- }
- switch (mTransformType) {
- case SVG_TRANSFORM_MATRIX: {
- const gfxMatrix& mx = aTransform.GetMatrix();
- 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);
- break;
- }
- case SVG_TRANSFORM_TRANSLATE: {
- const gfxMatrix& mx = aTransform.GetMatrix();
- mParams[0] = static_cast<float>(mx._31);
- mParams[1] = static_cast<float>(mx._32);
- break;
- }
- case SVG_TRANSFORM_SCALE: {
- const gfxMatrix& mx = aTransform.GetMatrix();
- mParams[0] = static_cast<float>(mx._11);
- mParams[1] = static_cast<float>(mx._22);
- break;
- }
- case SVG_TRANSFORM_ROTATE:
- mParams[0] = aTransform.Angle();
- aTransform.GetRotationOrigin(mParams[1], mParams[2]);
- break;
- case SVG_TRANSFORM_SKEWX:
- case SVG_TRANSFORM_SKEWY:
- mParams[0] = aTransform.Angle();
- break;
- default:
- NS_NOTREACHED("Unexpected transform type");
- break;
- }
- }
- nsSVGTransform
- SVGTransformSMILData::ToSVGTransform() const
- {
- nsSVGTransform result;
- switch (mTransformType) {
- case SVG_TRANSFORM_MATRIX:
- result.SetMatrix(gfxMatrix(mParams[0], mParams[1],
- mParams[2], mParams[3],
- mParams[4], mParams[5]));
- break;
- case SVG_TRANSFORM_TRANSLATE:
- result.SetTranslate(mParams[0], mParams[1]);
- break;
- case SVG_TRANSFORM_SCALE:
- result.SetScale(mParams[0], mParams[1]);
- break;
- case SVG_TRANSFORM_ROTATE:
- result.SetRotate(mParams[0], mParams[1], mParams[2]);
- break;
- case SVG_TRANSFORM_SKEWX:
- result.SetSkewX(mParams[0]);
- break;
- case SVG_TRANSFORM_SKEWY:
- result.SetSkewY(mParams[0]);
- break;
- default:
- NS_NOTREACHED("Unexpected transform type");
- break;
- }
- return result;
- }
- } // namespace mozilla
|