1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla SVG Project code.
16 : *
17 : * The Initial Developer of the Original Code is the Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2010
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPL"), or
25 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #ifndef MOZILLA_DOMSVGPOINT_H__
38 : #define MOZILLA_DOMSVGPOINT_H__
39 :
40 : #include "DOMSVGPointList.h"
41 : #include "gfxPoint.h"
42 : #include "nsAutoPtr.h"
43 : #include "nsCycleCollectionParticipant.h"
44 : #include "nsDebug.h"
45 : #include "nsIDOMSVGPoint.h"
46 : #include "nsTArray.h"
47 : #include "SVGPoint.h"
48 :
49 : class nsSVGElement;
50 :
51 : // We make DOMSVGPoint a pseudo-interface to allow us to QI to it in order to
52 : // check that the objects that scripts pass to DOMSVGPointList methods are
53 : // our *native* point objects.
54 : //
55 : // {d6b6c440-af8d-40ee-856b-02a317cab275}
56 : #define MOZILLA_DOMSVGPOINT_IID \
57 : { 0xd6b6c440, 0xaf8d, 0x40ee, \
58 : { 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } }
59 :
60 : #define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
61 :
62 : namespace mozilla {
63 :
64 : /**
65 : * Class DOMSVGPoint
66 : *
67 : * This class creates the DOM objects that wrap internal SVGPoint objects that
68 : * are in an SVGPointList. It is also used to create the objects returned by
69 : * SVGSVGElement.createSVGPoint() and other functions that return DOM SVGPoint
70 : * objects.
71 : *
72 : * See the architecture comment in DOMSVGPointList.h for an overview of the
73 : * important points regarding these DOM wrapper structures.
74 : *
75 : * See the architecture comment in DOMSVGLength.h (yes, LENGTH) for an overview
76 : * of the important points regarding how this specific class works.
77 : */
78 : class DOMSVGPoint : public nsIDOMSVGPoint
79 : {
80 : public:
81 : NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGPOINT_IID)
82 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
83 1464 : NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGPoint)
84 : NS_DECL_NSIDOMSVGPOINT
85 :
86 : /**
87 : * Generic ctor for DOMSVGPoint objects that are created for an attribute.
88 : */
89 0 : DOMSVGPoint(DOMSVGPointList *aList,
90 : PRUint32 aListIndex,
91 : bool aIsAnimValItem)
92 : : mList(aList)
93 : , mListIndex(aListIndex)
94 : , mIsReadonly(false)
95 0 : , mIsAnimValItem(aIsAnimValItem)
96 : {
97 : // These shifts are in sync with the members.
98 0 : NS_ABORT_IF_FALSE(aList &&
99 : aListIndex <= MaxListIndex(), "bad arg");
100 :
101 0 : NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!");
102 0 : }
103 :
104 0 : DOMSVGPoint(const DOMSVGPoint *aPt = nsnull)
105 : : mList(nsnull)
106 : , mListIndex(0)
107 : , mIsReadonly(false)
108 0 : , mIsAnimValItem(false)
109 : {
110 0 : if (aPt) {
111 0 : mPt = aPt->ToSVGPoint();
112 : }
113 0 : }
114 :
115 0 : DOMSVGPoint(float aX, float aY)
116 : : mList(nsnull)
117 : , mListIndex(0)
118 : , mIsReadonly(false)
119 0 : , mIsAnimValItem(false)
120 : {
121 0 : mPt.mX = aX;
122 0 : mPt.mY = aY;
123 0 : }
124 :
125 0 : DOMSVGPoint(const gfxPoint &aPt)
126 : : mList(nsnull)
127 : , mListIndex(0)
128 : , mIsReadonly(false)
129 0 : , mIsAnimValItem(false)
130 : {
131 0 : mPt.mX = float(aPt.x);
132 0 : mPt.mY = float(aPt.y);
133 0 : NS_ASSERTION(NS_finite(mPt.mX) && NS_finite(mPt.mX),
134 : "DOMSVGPoint coords are not finite");
135 0 : }
136 :
137 :
138 0 : ~DOMSVGPoint() {
139 : // Our mList's weak ref to us must be nulled out when we die. If GC has
140 : // unlinked us using the cycle collector code, then that has already
141 : // happened, and mList is null.
142 0 : if (mList) {
143 0 : mList->mItems[mListIndex] = nsnull;
144 : }
145 0 : }
146 :
147 : /**
148 : * Create an unowned copy of this object. The caller is responsible for the
149 : * first AddRef()!
150 : */
151 0 : DOMSVGPoint* Clone() {
152 0 : return new DOMSVGPoint(this);
153 : }
154 :
155 : bool IsInList() const {
156 : return !!mList;
157 : }
158 :
159 : /**
160 : * In future, if this class is used for non-list points, this will be
161 : * different to IsInList(). "Owner" here means that the instance has an
162 : * internal counterpart from which it gets its values. (A better name may
163 : * be HasWrappee().)
164 : */
165 0 : bool HasOwner() const {
166 0 : return !!mList;
167 : }
168 :
169 : /**
170 : * This method is called to notify this DOM object that it is being inserted
171 : * into a list, and give it the information it needs as a result.
172 : *
173 : * This object MUST NOT already belong to a list when this method is called.
174 : * That's not to say that script can't move these DOM objects between
175 : * lists - it can - it's just that the logic to handle that (and send out
176 : * the necessary notifications) is located elsewhere (in DOMSVGPointList).)
177 : */
178 : void InsertingIntoList(DOMSVGPointList *aList,
179 : PRUint32 aListIndex,
180 : bool aIsAnimValItem);
181 :
182 0 : static PRUint32 MaxListIndex() {
183 0 : return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
184 : }
185 :
186 : /// This method is called to notify this object that its list index changed.
187 0 : void UpdateListIndex(PRUint32 aListIndex) {
188 0 : mListIndex = aListIndex;
189 0 : }
190 :
191 : /**
192 : * This method is called to notify this DOM object that it is about to be
193 : * removed from its current DOM list so that it can first make a copy of its
194 : * internal counterpart's values. (If it didn't do this, then it would
195 : * "lose" its value on being removed.)
196 : */
197 : void RemovingFromList();
198 :
199 0 : SVGPoint ToSVGPoint() const {
200 0 : return HasOwner() ? const_cast<DOMSVGPoint*>(this)->InternalItem() : mPt;
201 : }
202 :
203 0 : bool IsReadonly() const {
204 0 : return mIsReadonly;
205 : }
206 0 : void SetReadonly(bool aReadonly) {
207 0 : mIsReadonly = aReadonly;
208 0 : }
209 :
210 : protected:
211 :
212 0 : nsSVGElement* Element() {
213 0 : return mList->Element();
214 : }
215 :
216 : /**
217 : * Get a reference to the internal SVGPoint list item that this DOM wrapper
218 : * object currently wraps.
219 : *
220 : * To simplify the code we just have this one method for obtaining both
221 : * baseVal and animVal internal items. This means that animVal items don't
222 : * get const protection, but then our setter methods guard against changing
223 : * animVal items.
224 : */
225 : SVGPoint& InternalItem();
226 :
227 : #ifdef DEBUG
228 : bool IndexIsValid();
229 : #endif
230 :
231 : nsRefPtr<DOMSVGPointList> mList;
232 :
233 : // Bounds for the following are checked in the ctor, so be sure to update
234 : // that if you change the capacity of any of the following.
235 :
236 : PRUint32 mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
237 : PRUint32 mIsReadonly:1; // PRUint32 because MSVC won't pack otherwise
238 : PRUint32 mIsAnimValItem:1; // PRUint32 because MSVC won't pack otherwise
239 :
240 : // The following member is only used when we're not in a list:
241 : SVGPoint mPt;
242 : };
243 :
244 : NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGPoint, MOZILLA_DOMSVGPOINT_IID)
245 :
246 : } // namespace mozilla
247 :
248 : #undef MOZ_SVG_LIST_INDEX_BIT_COUNT
249 :
250 : #endif // MOZILLA_DOMSVGPOINT_H__
|