mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 821955 r=longsonr
--HG-- rename : content/svg/content/src/DOMSVGPoint.cpp => content/svg/content/nsISVGPoint.cpp rename : content/svg/content/src/DOMSVGPoint.cpp => content/svg/content/src/nsISVGPoint.cpp
This commit is contained in:
parent
b9ec9d66ed
commit
71e0a5342d
164
content/svg/content/nsISVGPoint.cpp
Normal file
164
content/svg/content/nsISVGPoint.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "DOMSVGPoint.h"
|
||||
#include "DOMSVGPointList.h"
|
||||
#include "SVGPoint.h"
|
||||
#include "SVGAnimatedPointList.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsError.h"
|
||||
#include "nsContentUtils.h" // NS_ENSURE_FINITE
|
||||
#include "mozilla/dom/SVGMatrix.h"
|
||||
#include "mozilla/dom/SVGPointBinding.h"
|
||||
|
||||
// See the architecture comment in DOMSVGPointList.h.
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
|
||||
// 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.)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPoint)
|
||||
// We may not belong to a list, so we must null check tmp->mList.
|
||||
if (tmp->mList) {
|
||||
tmp->mList->mItems[tmp->mListIndex] = nullptr;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPoint)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPoint)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(DOMSVGPoint) // pseudo-interface
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGPoint)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
float
|
||||
DOMSVGPoint::X()
|
||||
{
|
||||
if (mIsAnimValItem && HasOwner()) {
|
||||
Element()->FlushAnimations(); // May make HasOwner() == false
|
||||
}
|
||||
return HasOwner() ? InternalItem().mX : mPt.mX;
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGPoint::SetX(float aX, ErrorResult& rv)
|
||||
{
|
||||
if (mIsAnimValItem || mIsReadonly) {
|
||||
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasOwner()) {
|
||||
if (InternalItem().mX == aX) {
|
||||
return;
|
||||
}
|
||||
nsAttrValue emptyOrOldValue = Element()->WillChangePointList();
|
||||
InternalItem().mX = aX;
|
||||
Element()->DidChangePointList(emptyOrOldValue);
|
||||
if (mList->AttrIsAnimating()) {
|
||||
Element()->AnimationNeedsResample();
|
||||
}
|
||||
return;
|
||||
}
|
||||
mPt.mX = aX;
|
||||
}
|
||||
|
||||
float
|
||||
DOMSVGPoint::Y()
|
||||
{
|
||||
if (mIsAnimValItem && HasOwner()) {
|
||||
Element()->FlushAnimations(); // May make HasOwner() == false
|
||||
}
|
||||
return HasOwner() ? InternalItem().mY : mPt.mY;
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGPoint::SetY(float aY, ErrorResult& rv)
|
||||
{
|
||||
if (mIsAnimValItem || mIsReadonly) {
|
||||
rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasOwner()) {
|
||||
if (InternalItem().mY == aY) {
|
||||
return;
|
||||
}
|
||||
nsAttrValue emptyOrOldValue = Element()->WillChangePointList();
|
||||
InternalItem().mY = aY;
|
||||
Element()->DidChangePointList(emptyOrOldValue);
|
||||
if (mList->AttrIsAnimating()) {
|
||||
Element()->AnimationNeedsResample();
|
||||
}
|
||||
return;
|
||||
}
|
||||
mPt.mY = aY;
|
||||
}
|
||||
|
||||
already_AddRefed<nsISVGPoint>
|
||||
DOMSVGPoint::MatrixTransform(dom::SVGMatrix& matrix)
|
||||
{
|
||||
float x = HasOwner() ? InternalItem().mX : mPt.mX;
|
||||
float y = HasOwner() ? InternalItem().mY : mPt.mY;
|
||||
|
||||
gfxPoint pt = matrix.Matrix().Transform(gfxPoint(x, y));
|
||||
nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt);
|
||||
return newPoint.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGPoint::InsertingIntoList(DOMSVGPointList *aList,
|
||||
uint32_t aListIndex,
|
||||
bool aIsAnimValItem)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!HasOwner(), "Inserting item that already has an owner");
|
||||
|
||||
mList = aList;
|
||||
mListIndex = aListIndex;
|
||||
mIsReadonly = false;
|
||||
mIsAnimValItem = aIsAnimValItem;
|
||||
|
||||
NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!");
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGPoint::RemovingFromList()
|
||||
{
|
||||
mPt = InternalItem();
|
||||
mList = nullptr;
|
||||
NS_ABORT_IF_FALSE(!mIsReadonly, "mIsReadonly set for list");
|
||||
mIsAnimValItem = false;
|
||||
}
|
||||
|
||||
SVGPoint&
|
||||
DOMSVGPoint::InternalItem()
|
||||
{
|
||||
return mList->InternalList().mItems[mListIndex];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
DOMSVGPoint::IndexIsValid()
|
||||
{
|
||||
return mListIndex < mList->InternalList().Length();
|
||||
}
|
||||
#endif
|
||||
|
@ -17,38 +17,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
|
||||
// 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.)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPoint)
|
||||
// We may not belong to a list, so we must null check tmp->mList.
|
||||
if (tmp->mList) {
|
||||
tmp->mList->mItems[tmp->mListIndex] = nullptr;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPoint)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPoint)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(DOMSVGPoint) // pseudo-interface
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGPoint)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
float
|
||||
DOMSVGPoint::X()
|
||||
{
|
||||
@ -123,42 +91,3 @@ DOMSVGPoint::MatrixTransform(dom::SVGMatrix& matrix)
|
||||
nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt);
|
||||
return newPoint.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGPoint::InsertingIntoList(DOMSVGPointList *aList,
|
||||
uint32_t aListIndex,
|
||||
bool aIsAnimValItem)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!HasOwner(), "Inserting item that already has an owner");
|
||||
|
||||
mList = aList;
|
||||
mListIndex = aListIndex;
|
||||
mIsReadonly = false;
|
||||
mIsAnimValItem = aIsAnimValItem;
|
||||
|
||||
NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!");
|
||||
}
|
||||
|
||||
void
|
||||
DOMSVGPoint::RemovingFromList()
|
||||
{
|
||||
mPt = InternalItem();
|
||||
mList = nullptr;
|
||||
NS_ABORT_IF_FALSE(!mIsReadonly, "mIsReadonly set for list");
|
||||
mIsAnimValItem = false;
|
||||
}
|
||||
|
||||
SVGPoint&
|
||||
DOMSVGPoint::InternalItem()
|
||||
{
|
||||
return mList->InternalList().mItems[mListIndex];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
DOMSVGPoint::IndexIsValid()
|
||||
{
|
||||
return mListIndex < mList->InternalList().Length();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -19,17 +19,6 @@
|
||||
|
||||
class nsSVGElement;
|
||||
|
||||
// We make DOMSVGPoint a pseudo-interface to allow us to QI to it in order to
|
||||
// check that the objects that scripts pass to DOMSVGPointList methods are
|
||||
// our *native* point objects.
|
||||
//
|
||||
// {d6b6c440-af8d-40ee-856b-02a317cab275}
|
||||
#define MOZILLA_DOMSVGPOINT_IID \
|
||||
{ 0xd6b6c440, 0xaf8d, 0x40ee, \
|
||||
{ 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } }
|
||||
|
||||
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
@ -53,10 +42,6 @@ class SVGMatrix;
|
||||
class DOMSVGPoint MOZ_FINAL : public nsISVGPoint
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGPOINT_IID)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPoint)
|
||||
|
||||
/**
|
||||
* Generic ctor for DOMSVGPoint objects that are created for an attribute.
|
||||
*/
|
||||
@ -64,11 +49,11 @@ public:
|
||||
uint32_t aListIndex,
|
||||
bool aIsAnimValItem)
|
||||
: nsISVGPoint()
|
||||
, mList(aList)
|
||||
, mListIndex(aListIndex)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(aIsAnimValItem)
|
||||
{
|
||||
mList = aList;
|
||||
mListIndex = aListIndex;
|
||||
mIsAnimValItem = aIsAnimValItem;
|
||||
|
||||
// These shifts are in sync with the members.
|
||||
NS_ABORT_IF_FALSE(aList &&
|
||||
aListIndex <= MaxListIndex(), "bad arg");
|
||||
@ -78,10 +63,6 @@ public:
|
||||
|
||||
explicit DOMSVGPoint(const DOMSVGPoint *aPt = nullptr)
|
||||
: nsISVGPoint()
|
||||
, mList(nullptr)
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
{
|
||||
if (aPt) {
|
||||
mPt = aPt->ToSVGPoint();
|
||||
@ -90,10 +71,6 @@ public:
|
||||
|
||||
DOMSVGPoint(float aX, float aY)
|
||||
: nsISVGPoint()
|
||||
, mList(nullptr)
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
{
|
||||
mPt.mX = aX;
|
||||
mPt.mY = aY;
|
||||
@ -101,10 +78,6 @@ public:
|
||||
|
||||
explicit DOMSVGPoint(const gfxPoint &aPt)
|
||||
: nsISVGPoint()
|
||||
, mList(nullptr)
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
{
|
||||
mPt.mX = float(aPt.x);
|
||||
mPt.mY = float(aPt.y);
|
||||
@ -113,15 +86,6 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual ~DOMSVGPoint() {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// WebIDL
|
||||
virtual float X();
|
||||
virtual void SetX(float aX, ErrorResult& rv);
|
||||
@ -132,107 +96,17 @@ public:
|
||||
return mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an unowned copy of this object. The caller is responsible for the
|
||||
* first AddRef()!
|
||||
*/
|
||||
DOMSVGPoint* Clone() {
|
||||
nsISVGPoint* Clone() {
|
||||
return new DOMSVGPoint(this);
|
||||
}
|
||||
|
||||
bool IsInList() const {
|
||||
return !!mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* In future, if this class is used for non-list points, this will be
|
||||
* different to IsInList(). "Owner" here means that the instance has an
|
||||
* internal counterpart from which it gets its values. (A better name may
|
||||
* be HasWrappee().)
|
||||
*/
|
||||
bool HasOwner() const {
|
||||
return !!mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to notify this DOM object that it is being inserted
|
||||
* into a list, and give it the information it needs as a result.
|
||||
*
|
||||
* This object MUST NOT already belong to a list when this method is called.
|
||||
* That's not to say that script can't move these DOM objects between
|
||||
* lists - it can - it's just that the logic to handle that (and send out
|
||||
* the necessary notifications) is located elsewhere (in DOMSVGPointList).)
|
||||
*/
|
||||
void InsertingIntoList(DOMSVGPointList *aList,
|
||||
uint32_t aListIndex,
|
||||
bool aIsAnimValItem);
|
||||
|
||||
static uint32_t MaxListIndex() {
|
||||
return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
|
||||
}
|
||||
|
||||
/// This method is called to notify this object that its list index changed.
|
||||
void UpdateListIndex(uint32_t aListIndex) {
|
||||
mListIndex = aListIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to notify this DOM object that it is about to be
|
||||
* removed from its current DOM list so that it can first make a copy of its
|
||||
* internal counterpart's values. (If it didn't do this, then it would
|
||||
* "lose" its value on being removed.)
|
||||
*/
|
||||
void RemovingFromList();
|
||||
|
||||
SVGPoint ToSVGPoint() const {
|
||||
return HasOwner() ? const_cast<DOMSVGPoint*>(this)->InternalItem() : mPt;
|
||||
}
|
||||
|
||||
bool IsReadonly() const {
|
||||
return mIsReadonly;
|
||||
}
|
||||
void SetReadonly(bool aReadonly) {
|
||||
mIsReadonly = aReadonly;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
nsSVGElement* Element() {
|
||||
return mList->Element();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the internal SVGPoint list item that this DOM wrapper
|
||||
* object currently wraps.
|
||||
*
|
||||
* To simplify the code we just have this one method for obtaining both
|
||||
* baseVal and animVal internal items. This means that animVal items don't
|
||||
* get const protection, but then our setter methods guard against changing
|
||||
* animVal items.
|
||||
*/
|
||||
SVGPoint& InternalItem();
|
||||
|
||||
#ifdef DEBUG
|
||||
bool IndexIsValid();
|
||||
#endif
|
||||
|
||||
nsRefPtr<DOMSVGPointList> mList;
|
||||
|
||||
// Bounds for the following are checked in the ctor, so be sure to update
|
||||
// that if you change the capacity of any of the following.
|
||||
|
||||
uint32_t mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
|
||||
uint32_t mIsReadonly:1; // uint32_t because MSVC won't pack otherwise
|
||||
uint32_t mIsAnimValItem:1; // uint32_t because MSVC won't pack otherwise
|
||||
|
||||
// The following member is only used when we're not in a list:
|
||||
SVGPoint mPt;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGPoint, MOZILLA_DOMSVGPOINT_IID)
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#undef MOZ_SVG_LIST_INDEX_BIT_COUNT
|
||||
|
||||
#endif // MOZILLA_DOMSVGPOINT_H__
|
||||
|
@ -19,10 +19,8 @@
|
||||
// local helper functions
|
||||
namespace {
|
||||
|
||||
using mozilla::DOMSVGPoint;
|
||||
|
||||
void
|
||||
UpdateListIndicesFromIndex(nsTArray<DOMSVGPoint*>& aItemsArray,
|
||||
UpdateListIndicesFromIndex(nsTArray<mozilla::nsISVGPoint*>& aItemsArray,
|
||||
uint32_t aStartingIndex)
|
||||
{
|
||||
uint32_t length = aItemsArray.Length();
|
||||
@ -109,10 +107,10 @@ DOMSVGPointList::InternalListWillChangeTo(const SVGPointList& aNewValue)
|
||||
uint32_t oldLength = mItems.Length();
|
||||
|
||||
uint32_t newLength = aNewValue.Length();
|
||||
if (newLength > DOMSVGPoint::MaxListIndex()) {
|
||||
if (newLength > nsISVGPoint::MaxListIndex()) {
|
||||
// It's safe to get out of sync with our internal list as long as we have
|
||||
// FEWER items than it does.
|
||||
newLength = DOMSVGPoint::MaxListIndex();
|
||||
newLength = nsISVGPoint::MaxListIndex();
|
||||
}
|
||||
|
||||
nsRefPtr<DOMSVGPointList> kungFuDeathGrip;
|
||||
@ -214,11 +212,7 @@ DOMSVGPointList::Initialize(nsISVGPoint& aNewItem, ErrorResult& aError)
|
||||
// clone of aNewItem, it would actually insert aNewItem. To prevent that
|
||||
// from happening we have to do the clone here, if necessary.
|
||||
|
||||
nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem);
|
||||
if (!domItem) {
|
||||
aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsISVGPoint> domItem = &aNewItem;
|
||||
if (domItem->HasOwner() || domItem->IsReadonly()) {
|
||||
domItem = domItem->Clone(); // must do this before changing anything!
|
||||
}
|
||||
@ -254,16 +248,12 @@ DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex,
|
||||
}
|
||||
|
||||
aIndex = std::min(aIndex, LengthNoFlush());
|
||||
if (aIndex >= DOMSVGPoint::MaxListIndex()) {
|
||||
if (aIndex >= nsISVGPoint::MaxListIndex()) {
|
||||
aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem);
|
||||
if (!domItem) {
|
||||
aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsISVGPoint> domItem = &aNewItem;
|
||||
if (domItem->HasOwner() || domItem->IsReadonly()) {
|
||||
domItem = domItem->Clone(); // must do this before changing anything!
|
||||
}
|
||||
@ -310,11 +300,7 @@ DOMSVGPointList::ReplaceItem(nsISVGPoint& aNewItem, uint32_t aIndex,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem);
|
||||
if (!domItem) {
|
||||
aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsISVGPoint> domItem = &aNewItem;
|
||||
if (domItem->HasOwner() || domItem->IsReadonly()) {
|
||||
domItem = domItem->Clone(); // must do this before changing anything!
|
||||
}
|
||||
@ -365,7 +351,7 @@ DOMSVGPointList::RemoveItem(uint32_t aIndex, ErrorResult& aError)
|
||||
// Notify the DOM item of removal *before* modifying the lists so that the
|
||||
// DOM item can copy its *old* value:
|
||||
mItems[aIndex]->RemovingFromList();
|
||||
nsRefPtr<DOMSVGPoint> result = mItems[aIndex];
|
||||
nsCOMPtr<nsISVGPoint> result = mItems[aIndex];
|
||||
|
||||
InternalList().RemoveItem(aIndex);
|
||||
mItems.RemoveElementAt(aIndex);
|
||||
@ -408,7 +394,7 @@ DOMSVGPointList::MaybeInsertNullInAnimValListAt(uint32_t aIndex)
|
||||
NS_ABORT_IF_FALSE(animVal->mItems.Length() == mItems.Length(),
|
||||
"animVal list not in sync!");
|
||||
|
||||
animVal->mItems.InsertElementAt(aIndex, static_cast<DOMSVGPoint*>(nullptr));
|
||||
animVal->mItems.InsertElementAt(aIndex, static_cast<nsISVGPoint*>(nullptr));
|
||||
|
||||
UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1);
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
class nsIDOMSVGPoint;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class DOMSVGPoint;
|
||||
@ -52,7 +50,8 @@ class SVGAnimatedPointList;
|
||||
class DOMSVGPointList MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
friend class DOMSVGPoint;
|
||||
friend class nsISVGPoint;
|
||||
friend class mozilla::DOMSVGPoint;
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
@ -208,18 +207,18 @@ private:
|
||||
|
||||
SVGAnimatedPointList& InternalAList() const;
|
||||
|
||||
/// Creates a DOMSVGPoint for aIndex, if it doesn't already exist.
|
||||
/// Creates an nsISVGPoint for aIndex, if it doesn't already exist.
|
||||
void EnsureItemAt(uint32_t aIndex);
|
||||
|
||||
void MaybeInsertNullInAnimValListAt(uint32_t aIndex);
|
||||
void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex);
|
||||
|
||||
// Weak refs to our DOMSVGPoint items. The items are friends and take care
|
||||
// Weak refs to our nsISVGPoint items. The items are friends and take care
|
||||
// of clearing our pointer to them when they die.
|
||||
nsTArray<DOMSVGPoint*> mItems;
|
||||
nsTArray<nsISVGPoint*> mItems;
|
||||
|
||||
// Strong ref to our element to keep it alive. We hold this not only for
|
||||
// ourself, but also for our DOMSVGPoint items too.
|
||||
// ourself, but also for our nsISVGPoint items too.
|
||||
nsRefPtr<nsSVGElement> mElement;
|
||||
|
||||
bool mIsAnimValList;
|
||||
|
@ -35,6 +35,7 @@ CPPSRCS = \
|
||||
DOMSVGTransformList.cpp \
|
||||
nsDOMSVGZoomEvent.cpp \
|
||||
nsDOMSVGEvent.cpp \
|
||||
nsISVGPoint.cpp \
|
||||
nsSVGAngle.cpp \
|
||||
nsSVGBoolean.cpp \
|
||||
nsSVGClass.cpp \
|
||||
|
@ -21,10 +21,8 @@ class SVGPoint
|
||||
public:
|
||||
|
||||
SVGPoint()
|
||||
#ifdef DEBUG
|
||||
: mX(0.0f)
|
||||
, mY(0.0f)
|
||||
#endif
|
||||
{}
|
||||
|
||||
SVGPoint(float aX, float aY)
|
||||
@ -65,6 +63,19 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetX(float aX)
|
||||
{ mX = aX; }
|
||||
void SetY(float aY)
|
||||
{ mY = aY; }
|
||||
float GetX() const
|
||||
{ return mX; }
|
||||
float GetY() const
|
||||
{ return mY; }
|
||||
|
||||
bool operator!=(const SVGPoint &rhs) const {
|
||||
return mX != rhs.mX || mY != rhs.mY;
|
||||
}
|
||||
|
||||
float mX;
|
||||
float mY;
|
||||
};
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <string.h>
|
||||
|
||||
namespace mozilla {
|
||||
class nsISVGPoint;
|
||||
|
||||
/**
|
||||
* ATTENTION! WARNING! WATCH OUT!!
|
||||
@ -30,6 +31,7 @@ namespace mozilla {
|
||||
*/
|
||||
class SVGPointList
|
||||
{
|
||||
friend class mozilla::nsISVGPoint;
|
||||
friend class SVGAnimatedPointList;
|
||||
friend class DOMSVGPointList;
|
||||
friend class DOMSVGPoint;
|
||||
|
@ -54,12 +54,12 @@ SVGSVGElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
|
||||
return SVGSVGElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
}
|
||||
|
||||
NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(nsSVGTranslatePoint::DOMVal, mElement)
|
||||
NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGTranslatePoint, mElement)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGTranslatePoint::DOMVal)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGTranslatePoint::DOMVal)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGTranslatePoint)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGTranslatePoint)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGTranslatePoint)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
// We have to qualify nsISVGPoint because NS_GET_IID looks for a class in the
|
||||
// global namespace
|
||||
@ -67,39 +67,37 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsresult
|
||||
nsSVGTranslatePoint::ToDOMVal(SVGSVGElement *aElement,
|
||||
nsISupports **aResult)
|
||||
nsISVGPoint*
|
||||
DOMSVGTranslatePoint::Clone()
|
||||
{
|
||||
NS_ADDREF(*aResult = new DOMVal(this, aElement));
|
||||
return NS_OK;
|
||||
return new DOMSVGTranslatePoint(this);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsSVGTranslatePoint::DOMVal::GetParentObject()
|
||||
DOMSVGTranslatePoint::GetParentObject()
|
||||
{
|
||||
return static_cast<nsIDOMSVGSVGElement*>(mElement);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGTranslatePoint::DOMVal::SetX(float aValue, ErrorResult& rv)
|
||||
DOMSVGTranslatePoint::SetX(float aValue, ErrorResult& rv)
|
||||
{
|
||||
rv = mElement->SetCurrentTranslate(aValue, mVal->GetY());
|
||||
rv = mElement->SetCurrentTranslate(aValue, mPt.GetY());
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGTranslatePoint::DOMVal::SetY(float aValue, ErrorResult& rv)
|
||||
DOMSVGTranslatePoint::SetY(float aValue, ErrorResult& rv)
|
||||
{
|
||||
rv = mElement->SetCurrentTranslate(mVal->GetX(), aValue);
|
||||
rv = mElement->SetCurrentTranslate(mPt.GetX(), aValue);
|
||||
}
|
||||
|
||||
already_AddRefed<nsISVGPoint>
|
||||
nsSVGTranslatePoint::DOMVal::MatrixTransform(SVGMatrix& matrix)
|
||||
DOMSVGTranslatePoint::MatrixTransform(SVGMatrix& matrix)
|
||||
{
|
||||
float a = matrix.A(), b = matrix.B(), c = matrix.C();
|
||||
float d = matrix.D(), e = matrix.E(), f = matrix.F();
|
||||
float x = mVal->GetX();
|
||||
float y = mVal->GetY();
|
||||
float x = mPt.GetX();
|
||||
float y = mPt.GetY();
|
||||
|
||||
nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f);
|
||||
return point.forget();
|
||||
@ -361,8 +359,7 @@ SVGSVGElement::GetCurrentTranslate(nsISupports * *aCurrentTranslate)
|
||||
already_AddRefed<nsISVGPoint>
|
||||
SVGSVGElement::CurrentTranslate()
|
||||
{
|
||||
nsCOMPtr<nsISVGPoint> point;
|
||||
mCurrentTranslate.ToDOMVal(this, getter_AddRefs(point));
|
||||
nsCOMPtr<nsISVGPoint> point = new DOMSVGTranslatePoint(&mCurrentTranslate, this);
|
||||
return point.forget();
|
||||
}
|
||||
|
||||
@ -792,7 +789,7 @@ SVGSVGElement::SetCurrentScaleTranslate(float s, float x, float y)
|
||||
mPreviousTranslate = mCurrentTranslate;
|
||||
|
||||
mCurrentScale = s;
|
||||
mCurrentTranslate = nsSVGTranslatePoint(x, y);
|
||||
mCurrentTranslate = SVGPoint(x, y);
|
||||
|
||||
// now dispatch the appropriate event if we are the root element
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
@ -964,7 +961,7 @@ SVGSVGElement::UpdateHasChildrenOnlyTransform()
|
||||
{
|
||||
bool hasChildrenOnlyTransform =
|
||||
HasViewBoxOrSyntheticViewBox() ||
|
||||
(IsRoot() && (mCurrentTranslate != nsSVGTranslatePoint(0.0f, 0.0f) ||
|
||||
(IsRoot() && (mCurrentTranslate != SVGPoint(0.0f, 0.0f) ||
|
||||
mCurrentScale != 1.0f));
|
||||
mHasChildrenOnlyTransform = hasChildrenOnlyTransform;
|
||||
}
|
||||
|
@ -39,57 +39,29 @@ class SVGViewElement;
|
||||
|
||||
class SVGSVGElement;
|
||||
|
||||
class nsSVGTranslatePoint {
|
||||
class DOMSVGTranslatePoint MOZ_FINAL : public nsISVGPoint {
|
||||
public:
|
||||
nsSVGTranslatePoint()
|
||||
: mX(0.0f)
|
||||
, mY(0.0f)
|
||||
{}
|
||||
DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement *aElement)
|
||||
: nsISVGPoint(aPt), mElement(aElement) {}
|
||||
|
||||
nsSVGTranslatePoint(float aX, float aY)
|
||||
: mX(aX)
|
||||
, mY(aY)
|
||||
{}
|
||||
DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt)
|
||||
: nsISVGPoint(&aPt->mPt), mElement(aPt->mElement) {}
|
||||
|
||||
void SetX(float aX)
|
||||
{ mX = aX; }
|
||||
void SetY(float aY)
|
||||
{ mY = aY; }
|
||||
float GetX() const
|
||||
{ return mX; }
|
||||
float GetY() const
|
||||
{ return mY; }
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGTranslatePoint)
|
||||
|
||||
nsresult ToDOMVal(SVGSVGElement *aElement, nsISupports **aResult);
|
||||
virtual nsISVGPoint* Clone();
|
||||
|
||||
bool operator!=(const nsSVGTranslatePoint &rhs) const {
|
||||
return mX != rhs.mX || mY != rhs.mY;
|
||||
}
|
||||
// WebIDL
|
||||
virtual float X() { return mPt.GetX(); }
|
||||
virtual float Y() { return mPt.GetY(); }
|
||||
virtual void SetX(float aValue, ErrorResult& rv);
|
||||
virtual void SetY(float aValue, ErrorResult& rv);
|
||||
virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix);
|
||||
|
||||
private:
|
||||
virtual nsISupports* GetParentObject() MOZ_OVERRIDE;
|
||||
|
||||
struct DOMVal MOZ_FINAL : public nsISVGPoint {
|
||||
DOMVal(nsSVGTranslatePoint* aVal, SVGSVGElement *aElement)
|
||||
: nsISVGPoint(), mVal(aVal), mElement(aElement) {}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMVal)
|
||||
|
||||
// WebIDL
|
||||
virtual float X() { return mVal->GetX(); }
|
||||
virtual float Y() { return mVal->GetY(); }
|
||||
virtual void SetX(float aValue, ErrorResult& rv);
|
||||
virtual void SetY(float aValue, ErrorResult& rv);
|
||||
virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix);
|
||||
|
||||
virtual nsISupports* GetParentObject() MOZ_OVERRIDE;
|
||||
|
||||
nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement
|
||||
nsRefPtr<SVGSVGElement> mElement;
|
||||
};
|
||||
|
||||
float mX;
|
||||
float mY;
|
||||
nsRefPtr<SVGSVGElement> mElement;
|
||||
};
|
||||
|
||||
class svgFloatSize {
|
||||
@ -153,14 +125,14 @@ public:
|
||||
/**
|
||||
* Retrieve the value of currentScale and currentTranslate.
|
||||
*/
|
||||
const nsSVGTranslatePoint& GetCurrentTranslate() { return mCurrentTranslate; }
|
||||
const SVGPoint& GetCurrentTranslate() { return mCurrentTranslate; }
|
||||
float GetCurrentScale() { return mCurrentScale; }
|
||||
|
||||
/**
|
||||
* Retrieve the value of currentScale, currentTranslate.x or
|
||||
* currentTranslate.y prior to the last change made to any one of them.
|
||||
*/
|
||||
const nsSVGTranslatePoint& GetPreviousTranslate() { return mPreviousTranslate; }
|
||||
const SVGPoint& GetPreviousTranslate() { return mPreviousTranslate; }
|
||||
float GetPreviousScale() { return mPreviousScale; }
|
||||
|
||||
nsSMILTimeContainer* GetTimedDocumentRoot();
|
||||
@ -412,20 +384,20 @@ private:
|
||||
// zoom and pan
|
||||
// IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing
|
||||
// code to change any of these!
|
||||
nsSVGTranslatePoint mCurrentTranslate;
|
||||
float mCurrentScale;
|
||||
nsSVGTranslatePoint mPreviousTranslate;
|
||||
float mPreviousScale;
|
||||
SVGPoint mCurrentTranslate;
|
||||
float mCurrentScale;
|
||||
SVGPoint mPreviousTranslate;
|
||||
float mPreviousScale;
|
||||
|
||||
// For outermost <svg> elements created from parsing, animation is started by
|
||||
// the onload event in accordance with the SVG spec, but for <svg> elements
|
||||
// created by script or promoted from inner <svg> to outermost <svg> we need
|
||||
// to manually kick off animation when they are bound to the tree.
|
||||
bool mStartAnimationOnBindToTree;
|
||||
bool mImageNeedsTransformInvalidation;
|
||||
bool mIsPaintingSVGImageElement;
|
||||
bool mHasChildrenOnlyTransform;
|
||||
bool mUseCurrentView;
|
||||
bool mStartAnimationOnBindToTree;
|
||||
bool mImageNeedsTransformInvalidation;
|
||||
bool mIsPaintingSVGImageElement;
|
||||
bool mHasChildrenOnlyTransform;
|
||||
bool mUseCurrentView;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -54,14 +54,12 @@ nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(nsPresContext* aPresContext,
|
||||
mNewScale = SVGSVGElem->GetCurrentScale();
|
||||
mPreviousScale = SVGSVGElem->GetPreviousScale();
|
||||
|
||||
const nsSVGTranslatePoint& translate =
|
||||
SVGSVGElem->GetCurrentTranslate();
|
||||
const SVGPoint& translate = SVGSVGElem->GetCurrentTranslate();
|
||||
mNewTranslate =
|
||||
new DOMSVGPoint(translate.GetX(), translate.GetY());
|
||||
mNewTranslate->SetReadonly(true);
|
||||
|
||||
const nsSVGTranslatePoint& prevTranslate =
|
||||
SVGSVGElem->GetPreviousTranslate();
|
||||
const SVGPoint& prevTranslate = SVGSVGElem->GetPreviousTranslate();
|
||||
mPreviousTranslate =
|
||||
new DOMSVGPoint(prevTranslate.GetX(), prevTranslate.GetY());
|
||||
mPreviousTranslate->SetReadonly(true);
|
||||
|
88
content/svg/content/src/nsISVGPoint.cpp
Normal file
88
content/svg/content/src/nsISVGPoint.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "DOMSVGPoint.h"
|
||||
#include "DOMSVGPointList.h"
|
||||
#include "SVGPoint.h"
|
||||
#include "SVGAnimatedPointList.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsError.h"
|
||||
#include "nsContentUtils.h" // NS_ENSURE_FINITE
|
||||
#include "mozilla/dom/SVGMatrix.h"
|
||||
#include "mozilla/dom/SVGPointBinding.h"
|
||||
|
||||
// See the architecture comment in DOMSVGPointList.h.
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
|
||||
// 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.)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsISVGPoint)
|
||||
// We may not belong to a list, so we must null check tmp->mList.
|
||||
if (tmp->mList) {
|
||||
tmp->mList->mItems[tmp->mListIndex] = nullptr;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsISVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsISVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsISVGPoint)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsISVGPoint)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsISVGPoint)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGPoint)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
void
|
||||
nsISVGPoint::InsertingIntoList(DOMSVGPointList *aList,
|
||||
uint32_t aListIndex,
|
||||
bool aIsAnimValItem)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!HasOwner(), "Inserting item that already has an owner");
|
||||
|
||||
mList = aList;
|
||||
mListIndex = aListIndex;
|
||||
mIsReadonly = false;
|
||||
mIsAnimValItem = aIsAnimValItem;
|
||||
|
||||
NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!");
|
||||
}
|
||||
|
||||
void
|
||||
nsISVGPoint::RemovingFromList()
|
||||
{
|
||||
mPt = InternalItem();
|
||||
mList = nullptr;
|
||||
NS_ABORT_IF_FALSE(!mIsReadonly, "mIsReadonly set for list");
|
||||
mIsAnimValItem = false;
|
||||
}
|
||||
|
||||
SVGPoint&
|
||||
nsISVGPoint::InternalItem()
|
||||
{
|
||||
return mList->InternalList().mItems[mListIndex];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
bool
|
||||
nsISVGPoint::IndexIsValid()
|
||||
{
|
||||
return mListIndex < mList->InternalList().Length();
|
||||
}
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/SVGPointBinding.h"
|
||||
#include "DOMSVGPointList.h"
|
||||
|
||||
class nsSVGElement;
|
||||
|
||||
@ -17,6 +18,8 @@ class nsSVGElement;
|
||||
{ 0xd6b6c440, 0xaf8d, 0x40ee, \
|
||||
{ 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } }
|
||||
|
||||
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
@ -27,22 +30,110 @@ class SVGMatrix;
|
||||
* Class nsISVGPoint
|
||||
*
|
||||
* This class creates the DOM objects that wrap internal SVGPoint objects.
|
||||
* An nsISVGPoint can be either a DOMSVGPoint or a nsSVGTranslatePoint::DOMVal.
|
||||
* An nsISVGPoint can be either a DOMSVGPoint or a DOMSVGTranslatePoint
|
||||
*/
|
||||
class nsISVGPoint : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_NSISVGPOINT_IID)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsISVGPoint)
|
||||
|
||||
/**
|
||||
* Generic ctor for DOMSVGPoint objects that are created for an attribute.
|
||||
*/
|
||||
explicit nsISVGPoint()
|
||||
: mList(nullptr)
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
explicit nsISVGPoint(SVGPoint* aPt)
|
||||
: mList(nullptr)
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mPt.mX = aPt->GetX();
|
||||
mPt.mY = aPt->GetY();
|
||||
}
|
||||
|
||||
virtual ~nsISVGPoint()
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an unowned copy of this object. The caller is responsible for the
|
||||
* first AddRef()!
|
||||
*/
|
||||
virtual nsISVGPoint* Clone() = 0;
|
||||
|
||||
SVGPoint ToSVGPoint() const {
|
||||
return HasOwner() ? const_cast<nsISVGPoint*>(this)->InternalItem() : mPt;
|
||||
}
|
||||
|
||||
bool IsInList() const {
|
||||
return !!mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* In future, if this class is used for non-list points, this will be
|
||||
* different to IsInList(). "Owner" here means that the instance has an
|
||||
* internal counterpart from which it gets its values. (A better name may
|
||||
* be HasWrappee().)
|
||||
*/
|
||||
bool HasOwner() const {
|
||||
return !!mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to notify this DOM object that it is being inserted
|
||||
* into a list, and give it the information it needs as a result.
|
||||
*
|
||||
* This object MUST NOT already belong to a list when this method is called.
|
||||
* That's not to say that script can't move these DOM objects between
|
||||
* lists - it can - it's just that the logic to handle that (and send out
|
||||
* the necessary notifications) is located elsewhere (in DOMSVGPointList).)
|
||||
*/
|
||||
void InsertingIntoList(DOMSVGPointList *aList,
|
||||
uint32_t aListIndex,
|
||||
bool aIsAnimValItem);
|
||||
|
||||
static uint32_t MaxListIndex() {
|
||||
return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
|
||||
}
|
||||
|
||||
/// This method is called to notify this object that its list index changed.
|
||||
void UpdateListIndex(uint32_t aListIndex) {
|
||||
mListIndex = aListIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to notify this DOM object that it is about to be
|
||||
* removed from its current DOM list so that it can first make a copy of its
|
||||
* internal counterpart's values. (If it didn't do this, then it would
|
||||
* "lose" its value on being removed.)
|
||||
*/
|
||||
void RemovingFromList();
|
||||
|
||||
bool IsReadonly() const {
|
||||
return mIsReadonly;
|
||||
}
|
||||
void SetReadonly(bool aReadonly) {
|
||||
mIsReadonly = aReadonly;
|
||||
}
|
||||
|
||||
// WebIDL
|
||||
virtual float X() = 0;
|
||||
virtual void SetX(float aX, ErrorResult& rv) = 0;
|
||||
@ -54,9 +145,40 @@ public:
|
||||
{ return dom::SVGPointBinding::Wrap(cx, scope, this, triedToWrap); }
|
||||
|
||||
virtual nsISupports* GetParentObject() = 0;
|
||||
|
||||
protected:
|
||||
#ifdef DEBUG
|
||||
bool IndexIsValid();
|
||||
#endif
|
||||
|
||||
nsRefPtr<DOMSVGPointList> mList;
|
||||
|
||||
// Bounds for the following are checked in the ctor, so be sure to update
|
||||
// that if you change the capacity of any of the following.
|
||||
|
||||
uint32_t mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
|
||||
uint32_t mIsReadonly:1; // uint32_t because MSVC won't pack otherwise
|
||||
uint32_t mIsAnimValItem:1; // uint32_t because MSVC won't pack otherwise
|
||||
|
||||
/**
|
||||
* Get a reference to the internal SVGPoint list item that this DOM wrapper
|
||||
* object currently wraps.
|
||||
*
|
||||
* To simplify the code we just have this one method for obtaining both
|
||||
* baseVal and animVal internal items. This means that animVal items don't
|
||||
* get const protection, but then our setter methods guard against changing
|
||||
* animVal items.
|
||||
*/
|
||||
SVGPoint& InternalItem();
|
||||
|
||||
// The following member is only used when we're not in a list:
|
||||
SVGPoint mPt;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGPoint, MOZILLA_NSISVGPOINT_IID)
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#undef MOZ_SVG_LIST_INDEX_BIT_COUNT
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user