2015-05-03 19:32:37 +00: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 11:12:37 +00: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-25 21:04:27 +00:00
|
|
|
|
2013-12-24 22:09:22 +00:00
|
|
|
#include "SVGTransform.h"
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
#include "mozilla/dom/SVGTransform.h"
|
2013-01-11 20:30:21 +00:00
|
|
|
#include "mozilla/dom/SVGMatrix.h"
|
2013-09-17 12:52:39 +00:00
|
|
|
#include "mozilla/dom/SVGTransformBinding.h"
|
2012-07-27 14:03:27 +00:00
|
|
|
#include "nsError.h"
|
2013-04-14 22:56:34 +00:00
|
|
|
#include "nsSVGAnimatedTransformList.h"
|
2013-01-11 07:15:06 +00:00
|
|
|
#include "nsSVGAttrTearoffTable.h"
|
2014-03-04 23:39:42 +00:00
|
|
|
#include "mozilla/DebugOnly.h"
|
2014-10-01 09:26:00 +00:00
|
|
|
#include "mozilla/FloatingPoint.h"
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2013-12-24 22:09:22 +00:00
|
|
|
namespace {
|
2013-12-25 08:33:48 +00:00
|
|
|
const double kRadPerDegree = 2.0 * M_PI / 360.0;
|
2013-12-24 22:09:22 +00:00
|
|
|
}
|
|
|
|
|
2011-09-25 21:04:27 +00:00
|
|
|
namespace mozilla {
|
2013-04-02 19:17:41 +00:00
|
|
|
namespace dom {
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2013-05-30 22:34:53 +00:00
|
|
|
static nsSVGAttrTearoffTable<SVGTransform, SVGMatrix>&
|
|
|
|
SVGMatrixTearoffTable()
|
|
|
|
{
|
|
|
|
static nsSVGAttrTearoffTable<SVGTransform, SVGMatrix> sSVGMatrixTearoffTable;
|
|
|
|
return sSVGMatrixTearoffTable;
|
|
|
|
}
|
2013-01-11 07:15:06 +00:00
|
|
|
|
2011-09-25 21:04:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2014-04-25 16:49:00 +00:00
|
|
|
// We could use NS_IMPL_CYCLE_COLLECTION(, except that in Unlink() we need to
|
2011-09-25 21:04:27 +00:00
|
|
|
// clear our list's weak ref to us to be safe. (The other option would be to
|
|
|
|
// not unlink and rely on the breaking of the other edges in the cycle, as
|
|
|
|
// NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
|
2013-08-02 01:29:05 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(SVGTransform)
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SVGTransform)
|
2011-09-25 21:04:27 +00:00
|
|
|
// We may not belong to a list, so we must null check tmp->mList.
|
|
|
|
if (tmp->mList) {
|
2012-07-30 14:20:58 +00:00
|
|
|
tmp->mList->mItems[tmp->mListIndex] = nullptr;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
2012-11-15 07:32:40 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
|
2012-12-23 04:54:20 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
2011-09-25 21:04:27 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
2012-12-23 04:54:20 +00:00
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SVGTransform)
|
2012-11-15 07:32:40 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
|
2013-01-19 20:56:31 +00:00
|
|
|
SVGMatrix* matrix =
|
2013-05-30 22:34:53 +00:00
|
|
|
SVGMatrixTearoffTable().GetTearoff(tmp);
|
2013-01-19 20:56:31 +00:00
|
|
|
CycleCollectionNoteChild(cb, matrix, "matrix");
|
2012-12-23 04:54:20 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
2011-09-25 21:04:27 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(SVGTransform)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(SVGTransform, AddRef)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(SVGTransform, Release)
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
JSObject*
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 14:13:33 +00:00
|
|
|
SVGTransform::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
2012-12-23 04:54:20 +00:00
|
|
|
{
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 14:13:33 +00:00
|
|
|
return SVGTransformBinding::Wrap(aCx, this, aGivenProto);
|
2012-12-23 04:54:20 +00:00
|
|
|
}
|
|
|
|
|
2013-12-24 22:09:22 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Helper class: AutoChangeTransformNotifier
|
|
|
|
// Stack-based helper class to pair calls to WillChangeTransformList
|
|
|
|
// and DidChangeTransformList.
|
|
|
|
class MOZ_STACK_CLASS AutoChangeTransformNotifier
|
|
|
|
{
|
|
|
|
public:
|
2014-09-01 01:08:04 +00:00
|
|
|
explicit AutoChangeTransformNotifier(SVGTransform* aTransform MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
2013-12-24 22:09:22 +00:00
|
|
|
: mTransform(aTransform)
|
|
|
|
{
|
|
|
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
2013-12-25 08:33:48 +00:00
|
|
|
MOZ_ASSERT(mTransform, "Expecting non-null transform");
|
2013-12-24 22:09:22 +00:00
|
|
|
if (mTransform->HasOwner()) {
|
|
|
|
mEmptyOrOldValue =
|
|
|
|
mTransform->Element()->WillChangeTransformList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~AutoChangeTransformNotifier()
|
|
|
|
{
|
|
|
|
if (mTransform->HasOwner()) {
|
|
|
|
mTransform->Element()->DidChangeTransformList(mEmptyOrOldValue);
|
|
|
|
if (mTransform->mList->IsAnimating()) {
|
|
|
|
mTransform->Element()->AnimationNeedsResample();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2013-12-25 08:33:48 +00:00
|
|
|
SVGTransform* const mTransform;
|
2013-12-24 22:09:22 +00:00
|
|
|
nsAttrValue mEmptyOrOldValue;
|
|
|
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
|
|
|
};
|
|
|
|
|
2011-09-25 21:04:27 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Ctors:
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SVGTransform(DOMSVGTransformList *aList,
|
|
|
|
uint32_t aListIndex,
|
|
|
|
bool aIsAnimValItem)
|
2011-09-25 21:04:27 +00:00
|
|
|
: mList(aList)
|
|
|
|
, mListIndex(aListIndex)
|
|
|
|
, mIsAnimValItem(aIsAnimValItem)
|
2012-07-30 14:20:58 +00:00
|
|
|
, mTransform(nullptr)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
// These shifts are in sync with the members in the header.
|
2015-02-09 22:34:50 +00:00
|
|
|
MOZ_ASSERT(aList && aListIndex <= MaxListIndex(), "bad arg");
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2015-02-09 22:34:50 +00:00
|
|
|
MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGNumber!");
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SVGTransform()
|
2012-07-30 14:20:58 +00:00
|
|
|
: mList(nullptr)
|
2011-09-25 21:04:27 +00:00
|
|
|
, mListIndex(0)
|
2011-10-17 14:59:28 +00:00
|
|
|
, mIsAnimValItem(false)
|
2013-04-02 19:17:41 +00:00
|
|
|
, mTransform(new nsSVGTransform()) // Default ctor for objects not in a list
|
|
|
|
// initialises to matrix type with identity
|
|
|
|
// matrix
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SVGTransform(const gfxMatrix &aMatrix)
|
2012-07-30 14:20:58 +00:00
|
|
|
: mList(nullptr)
|
2011-09-25 21:04:27 +00:00
|
|
|
, mListIndex(0)
|
2011-10-17 14:59:28 +00:00
|
|
|
, mIsAnimValItem(false)
|
2013-04-02 19:17:41 +00:00
|
|
|
, mTransform(new nsSVGTransform(aMatrix))
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SVGTransform(const nsSVGTransform &aTransform)
|
2012-07-30 14:20:58 +00:00
|
|
|
: mList(nullptr)
|
2011-09-25 21:04:27 +00:00
|
|
|
, mListIndex(0)
|
2011-10-17 14:59:28 +00:00
|
|
|
, mIsAnimValItem(false)
|
2013-04-02 19:17:41 +00:00
|
|
|
, mTransform(new nsSVGTransform(aTransform))
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::~SVGTransform()
|
2013-01-11 07:15:06 +00:00
|
|
|
{
|
2013-05-30 22:34:53 +00:00
|
|
|
SVGMatrix* matrix = SVGMatrixTearoffTable().GetTearoff(this);
|
2013-01-19 20:56:31 +00:00
|
|
|
if (matrix) {
|
2013-05-30 22:34:53 +00:00
|
|
|
SVGMatrixTearoffTable().RemoveTearoff(this);
|
2013-01-19 20:56:31 +00:00
|
|
|
NS_RELEASE(matrix);
|
|
|
|
}
|
2013-01-11 07:15:06 +00:00
|
|
|
// Our mList's weak ref to us must be nulled out when we die. If GC has
|
|
|
|
// unlinked us using the cycle collector code, then that has already
|
|
|
|
// happened, and mList is null.
|
|
|
|
if (mList) {
|
|
|
|
mList->mItems[mListIndex] = nullptr;
|
|
|
|
}
|
|
|
|
}
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
uint16_t
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::Type() const
|
2012-12-23 04:54:20 +00:00
|
|
|
{
|
|
|
|
return Transform().Type();
|
|
|
|
}
|
|
|
|
|
2013-01-19 20:56:31 +00:00
|
|
|
SVGMatrix*
|
2014-03-18 02:41:35 +00:00
|
|
|
SVGTransform::GetMatrix()
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2013-01-19 20:56:31 +00:00
|
|
|
SVGMatrix* wrapper =
|
2013-05-30 22:34:53 +00:00
|
|
|
SVGMatrixTearoffTable().GetTearoff(this);
|
2013-01-11 07:15:06 +00:00
|
|
|
if (!wrapper) {
|
2013-01-19 20:56:31 +00:00
|
|
|
NS_ADDREF(wrapper = new SVGMatrix(*this));
|
2013-05-30 22:34:53 +00:00
|
|
|
SVGMatrixTearoffTable().AddTearoff(this, wrapper);
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
2013-01-19 20:56:31 +00:00
|
|
|
return wrapper;
|
2012-12-23 04:54:20 +00:00
|
|
|
}
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
float
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::Angle() const
|
2012-12-23 04:54:20 +00:00
|
|
|
{
|
|
|
|
return Transform().Angle();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetMatrix(SVGMatrix& aMatrix, ErrorResult& rv)
|
2012-12-23 04:54:20 +00:00
|
|
|
{
|
|
|
|
if (mIsAnimValItem) {
|
|
|
|
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
|
|
|
return;
|
|
|
|
}
|
2014-03-18 02:41:35 +00:00
|
|
|
SetMatrix(aMatrix.GetMatrix());
|
2012-12-23 04:54:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetTranslate(float tx, float ty, ErrorResult& rv)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
if (mIsAnimValItem) {
|
2012-12-23 04:54:20 +00:00
|
|
|
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
|
|
|
return;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:24 +00:00
|
|
|
if (Transform().Type() == SVG_TRANSFORM_TRANSLATE &&
|
2014-06-17 17:35:51 +00:00
|
|
|
Matrixgfx()._31 == tx && Matrixgfx()._32 == ty) {
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
2012-02-15 23:40:46 +00:00
|
|
|
}
|
|
|
|
|
2013-12-24 22:09:22 +00:00
|
|
|
AutoChangeTransformNotifier notifier(this);
|
2011-09-25 21:04:27 +00:00
|
|
|
Transform().SetTranslate(tx, ty);
|
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetScale(float sx, float sy, ErrorResult& rv)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
if (mIsAnimValItem) {
|
2012-12-23 04:54:20 +00:00
|
|
|
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
|
|
|
return;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:24 +00:00
|
|
|
if (Transform().Type() == SVG_TRANSFORM_SCALE &&
|
2014-06-17 17:35:51 +00:00
|
|
|
Matrixgfx()._11 == sx && Matrixgfx()._22 == sy) {
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
2012-02-15 23:40:46 +00:00
|
|
|
}
|
2013-12-24 22:09:22 +00:00
|
|
|
AutoChangeTransformNotifier notifier(this);
|
2011-09-25 21:04:27 +00:00
|
|
|
Transform().SetScale(sx, sy);
|
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetRotate(float angle, float cx, float cy, ErrorResult& rv)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
if (mIsAnimValItem) {
|
2012-12-23 04:54:20 +00:00
|
|
|
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
|
|
|
return;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:24 +00:00
|
|
|
if (Transform().Type() == SVG_TRANSFORM_ROTATE) {
|
2012-02-15 23:40:46 +00:00
|
|
|
float currentCx, currentCy;
|
|
|
|
Transform().GetRotationOrigin(currentCx, currentCy);
|
|
|
|
if (Transform().Angle() == angle && currentCx == cx && currentCy == cy) {
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
2012-02-15 23:40:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-24 22:09:22 +00:00
|
|
|
AutoChangeTransformNotifier notifier(this);
|
2011-09-25 21:04:27 +00:00
|
|
|
Transform().SetRotate(angle, cx, cy);
|
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetSkewX(float angle, ErrorResult& rv)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
if (mIsAnimValItem) {
|
2012-12-23 04:54:20 +00:00
|
|
|
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
|
|
|
return;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:24 +00:00
|
|
|
if (Transform().Type() == SVG_TRANSFORM_SKEWX &&
|
2012-02-15 23:40:46 +00:00
|
|
|
Transform().Angle() == angle) {
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
2012-02-15 23:40:46 +00:00
|
|
|
}
|
|
|
|
|
2014-10-01 09:26:00 +00:00
|
|
|
if (!IsFinite(tan(angle * kRadPerDegree))) {
|
2015-02-04 11:46:26 +00:00
|
|
|
rv.ThrowRangeError(MSG_INVALID_TRANSFORM_ANGLE_ERROR);
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-12-24 22:09:22 +00:00
|
|
|
|
|
|
|
AutoChangeTransformNotifier notifier(this);
|
2013-12-25 08:33:48 +00:00
|
|
|
DebugOnly<nsresult> result = Transform().SetSkewX(angle);
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(result), "SetSkewX unexpectedly failed");
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:20 +00:00
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetSkewY(float angle, ErrorResult& rv)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
|
|
|
if (mIsAnimValItem) {
|
2012-12-23 04:54:20 +00:00
|
|
|
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
|
|
|
return;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:54:24 +00:00
|
|
|
if (Transform().Type() == SVG_TRANSFORM_SKEWY &&
|
2012-02-15 23:40:46 +00:00
|
|
|
Transform().Angle() == angle) {
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
2012-02-15 23:40:46 +00:00
|
|
|
}
|
|
|
|
|
2014-10-01 09:26:00 +00:00
|
|
|
if (!IsFinite(tan(angle * kRadPerDegree))) {
|
2015-02-04 11:46:26 +00:00
|
|
|
rv.ThrowRangeError(MSG_INVALID_TRANSFORM_ANGLE_ERROR);
|
2012-12-23 04:54:20 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-12-24 22:09:22 +00:00
|
|
|
|
|
|
|
AutoChangeTransformNotifier notifier(this);
|
2013-12-25 08:33:48 +00:00
|
|
|
DebugOnly<nsresult> result = Transform().SetSkewY(angle);
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(result), "SetSkewY unexpectedly failed");
|
2012-12-23 04:54:20 +00:00
|
|
|
}
|
2011-09-25 21:04:27 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// List management methods:
|
|
|
|
|
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::InsertingIntoList(DOMSVGTransformList *aList,
|
|
|
|
uint32_t aListIndex,
|
|
|
|
bool aIsAnimValItem)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2015-02-09 22:34:50 +00:00
|
|
|
MOZ_ASSERT(!HasOwner(), "Inserting item that is already in a list");
|
2011-09-25 21:04:27 +00:00
|
|
|
|
|
|
|
mList = aList;
|
|
|
|
mListIndex = aListIndex;
|
|
|
|
mIsAnimValItem = aIsAnimValItem;
|
2012-07-30 14:20:58 +00:00
|
|
|
mTransform = nullptr;
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2015-02-09 22:34:50 +00:00
|
|
|
MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGLength!");
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::RemovingFromList()
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2015-02-09 22:34:50 +00:00
|
|
|
MOZ_ASSERT(!mTransform,
|
|
|
|
"Item in list also has another non-list value associated with it");
|
2011-09-25 21:04:27 +00:00
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
mTransform = new nsSVGTransform(InternalItem());
|
2012-07-30 14:20:58 +00:00
|
|
|
mList = nullptr;
|
2011-10-17 14:59:28 +00:00
|
|
|
mIsAnimValItem = false;
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
nsSVGTransform&
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::InternalItem()
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2013-04-14 22:56:34 +00:00
|
|
|
nsSVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList();
|
2011-09-25 21:04:27 +00:00
|
|
|
return mIsAnimValItem && alist->mAnimVal ?
|
|
|
|
(*alist->mAnimVal)[mListIndex] :
|
|
|
|
alist->mBaseVal[mListIndex];
|
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
const nsSVGTransform&
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::InternalItem() const
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2013-04-02 19:17:41 +00:00
|
|
|
return const_cast<SVGTransform*>(this)->InternalItem();
|
2011-09-25 21:04:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::IndexIsValid()
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2013-04-14 22:56:34 +00:00
|
|
|
nsSVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList();
|
2011-09-25 21:04:27 +00:00
|
|
|
return (mIsAnimValItem &&
|
|
|
|
mListIndex < alist->GetAnimValue().Length()) ||
|
|
|
|
(!mIsAnimValItem &&
|
|
|
|
mListIndex < alist->GetBaseValue().Length());
|
|
|
|
}
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2013-01-11 20:30:21 +00:00
|
|
|
// Interface for SVGMatrix's use
|
2011-09-25 21:04:27 +00:00
|
|
|
|
|
|
|
void
|
2013-04-02 19:17:41 +00:00
|
|
|
SVGTransform::SetMatrix(const gfxMatrix& aMatrix)
|
2011-09-25 21:04:27 +00:00
|
|
|
{
|
2015-02-09 22:34:50 +00:00
|
|
|
MOZ_ASSERT(!mIsAnimValItem,
|
|
|
|
"Attempting to modify read-only transform");
|
2012-02-15 23:40:46 +00:00
|
|
|
|
2012-12-23 04:54:24 +00:00
|
|
|
if (Transform().Type() == SVG_TRANSFORM_MATRIX &&
|
2013-04-02 19:17:41 +00:00
|
|
|
nsSVGTransform::MatricesEqual(Matrixgfx(), aMatrix)) {
|
2012-02-15 23:40:46 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-24 22:09:22 +00:00
|
|
|
AutoChangeTransformNotifier notifier(this);
|
2011-09-25 21:04:27 +00:00
|
|
|
Transform().SetMatrix(aMatrix);
|
|
|
|
}
|
|
|
|
|
2013-04-02 19:17:41 +00:00
|
|
|
} // namespace dom
|
2011-09-25 21:04:27 +00:00
|
|
|
} // namespace mozilla
|