1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DOM_SVG_DOMSVGPOINT_H_
8 #define DOM_SVG_DOMSVGPOINT_H_
10 #include "DOMSVGPointList.h"
11 #include "nsCycleCollectionParticipant.h"
14 #include "nsWrapperCache.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/FloatingPoint.h"
17 #include "mozilla/dom/SVGSVGElement.h"
18 #include "mozilla/gfx/2D.h"
20 #define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
22 namespace mozilla::dom
{
23 struct DOMMatrix2DInit
;
28 * This class creates the DOM objects that wrap internal SVGPoint objects that
29 * are in an SVGPointList. It is also used to create the objects returned by
30 * SVGSVGElement.createSVGPoint() and other functions that return DOM SVGPoint
33 * See the architecture comment in DOMSVGPointList.h for an overview of the
34 * important points regarding these DOM wrapper structures.
36 * See the architecture comment in DOMSVGLength.h (yes, LENGTH) for an overview
37 * of the important points regarding how this specific class works.
39 class DOMSVGPoint final
: public nsWrapperCache
{
41 friend class AutoChangePointListNotifier
;
43 using Point
= gfx::Point
;
47 * Generic ctor for DOMSVGPoint objects that are created for an attribute.
49 DOMSVGPoint(DOMSVGPointList
* aList
, uint32_t aListIndex
, bool aIsAnimValItem
)
52 mListIndex(aListIndex
),
53 mIsAnimValItem(aIsAnimValItem
),
54 mIsTranslatePoint(false) {
55 // These shifts are in sync with the members.
56 MOZ_ASSERT(aList
&& aListIndex
<= MaxListIndex(), "bad arg");
58 MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGPoint!");
61 // Constructor for unowned points and SVGSVGElement.createSVGPoint
62 explicit DOMSVGPoint(const Point
& aPt
)
63 : mListIndex(0), mIsAnimValItem(false), mIsTranslatePoint(false) {
64 // In this case we own mVal
65 mVal
= new SVGPoint(aPt
.x
, aPt
.y
);
69 // The translate of an SVGSVGElement
70 DOMSVGPoint(SVGPoint
* aPt
, SVGSVGElement
* aSVGSVGElement
)
72 mOwner(ToSupports(aSVGSVGElement
)),
74 mIsAnimValItem(false),
75 mIsTranslatePoint(true) {}
77 virtual ~DOMSVGPoint() { CleanupWeakRefs(); }
80 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMSVGPoint
)
81 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMSVGPoint
)
83 static already_AddRefed
<DOMSVGPoint
> GetTranslateTearOff(
84 SVGPoint
* aVal
, SVGSVGElement
* aSVGSVGElement
);
86 bool IsInList() const { return HasOwner() && !IsTranslatePoint(); }
89 * "Owner" here means that the instance has an
90 * internal counterpart from which it gets its values. (A better name may
93 bool HasOwner() const { return !!mOwner
; }
95 bool IsTranslatePoint() const { return mIsTranslatePoint
; }
97 void DidChangeTranslate();
100 * This method is called to notify this DOM object that it is being inserted
101 * into a list, and give it the information it needs as a result.
103 * This object MUST NOT already belong to a list when this method is called.
104 * That's not to say that script can't move these DOM objects between
105 * lists - it can - it's just that the logic to handle that (and send out
106 * the necessary notifications) is located elsewhere (in DOMSVGPointList).)
108 void InsertingIntoList(DOMSVGPointList
* aList
, uint32_t aListIndex
,
109 bool aIsAnimValItem
);
111 static uint32_t MaxListIndex() {
112 return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT
) - 1;
115 /// This method is called to notify this object that its list index changed.
116 void UpdateListIndex(uint32_t aListIndex
) { mListIndex
= aListIndex
; }
119 * This method is called to notify this DOM object that it is about to be
120 * removed from its current DOM list so that it can first make a copy of its
121 * internal counterpart's values. (If it didn't do this, then it would
122 * "lose" its value on being removed.)
124 void RemovingFromList();
126 SVGPoint
ToSVGPoint() { return InternalItem(); }
130 void SetX(float aX
, ErrorResult
& rv
);
132 void SetY(float aY
, ErrorResult
& rv
);
133 already_AddRefed
<DOMSVGPoint
> MatrixTransform(const DOMMatrix2DInit
& aMatrix
,
136 nsISupports
* GetParentObject() { return Element(); }
139 * Returns true if our attribute is animating (in which case our animVal is
140 * not simply a mirror of our baseVal).
142 bool AttrIsAnimating() const;
144 JSObject
* WrapObject(JSContext
* cx
,
145 JS::Handle
<JSObject
*> aGivenProto
) override
;
147 DOMSVGPoint
* Copy() { return new DOMSVGPoint(InternalItem()); }
154 SVGElement
* Element();
157 * Clears soon-to-be-invalid weak references in external objects that were
158 * set up during the creation of this object. This should be called during
159 * destruction and during cycle collection.
161 void CleanupWeakRefs();
164 * Get a reference to the internal SVGPoint list item that this DOM wrapper
165 * object currently wraps.
167 SVGPoint
& InternalItem();
169 SVGPoint
* mVal
; // If mIsTranslatePoint is true, the element owns
170 // the value. Otherwise we do.
171 RefPtr
<nsISupports
> mOwner
; // If mIsTranslatePoint is true, this is an
172 // SVGSVGElement, if we're unowned it's null, or
173 // we're in a list and it's a DOMSVGPointList
175 // Bounds for the following are checked in the ctor, so be sure to update
176 // that if you change the capacity of any of the following.
178 uint32_t mListIndex
: MOZ_SVG_LIST_INDEX_BIT_COUNT
;
179 uint32_t mIsAnimValItem
: 1; // True if We're the animated value of a list
180 uint32_t mIsTranslatePoint
: 1; // true iff our owner is a SVGSVGElement
183 } // namespace mozilla::dom
185 #undef MOZ_SVG_LIST_INDEX_BIT_COUNT
187 #endif // DOM_SVG_DOMSVGPOINT_H_