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_DOMSVGLENGTH_H__
38 : #define MOZILLA_DOMSVGLENGTH_H__
39 :
40 : #include "DOMSVGLengthList.h"
41 : #include "nsAutoPtr.h"
42 : #include "nsCycleCollectionParticipant.h"
43 : #include "nsDebug.h"
44 : #include "nsIDOMSVGLength.h"
45 : #include "nsTArray.h"
46 : #include "SVGLength.h"
47 :
48 : class nsSVGElement;
49 :
50 : // We make DOMSVGLength a pseudo-interface to allow us to QI to it in order to
51 : // check that the objects that scripts pass to DOMSVGLengthList methods are our
52 : // *native* length objects.
53 : //
54 : // {A8468350-7F7B-4976-9A7E-3765A1DADF9A}
55 : #define MOZILLA_DOMSVGLENGTH_IID \
56 : { 0xA8468350, 0x7F7B, 0x4976, { 0x9A, 0x7E, 0x37, 0x65, 0xA1, 0xDA, 0xDF, 0x9A } }
57 :
58 : #define MOZ_SVG_LIST_INDEX_BIT_COUNT 22 // supports > 4 million list items
59 :
60 : namespace mozilla {
61 :
62 : /**
63 : * Class DOMSVGLength
64 : *
65 : * This class creates the DOM objects that wrap internal SVGLength objects that
66 : * are in an SVGLengthList. It is also used to create the objects returned by
67 : * SVGSVGElement.createSVGLength().
68 : *
69 : * For the DOM wrapper classes for non-list SVGLength, see nsSVGLength2.h.
70 : *
71 : * See the architecture comment in DOMSVGAnimatedLengthList.h.
72 : *
73 : * This class is strongly intertwined with DOMSVGAnimatedLengthList and
74 : * DOMSVGLengthList. We are a friend of DOMSVGLengthList, and are responsible
75 : * for nulling out our DOMSVGLengthList's pointer to us when we die, making it
76 : * a real weak pointer.
77 : *
78 : * When objects of this type are in a DOMSVGLengthList they belong to an
79 : * attribute. While they belong to an attribute, the objects' values come from
80 : * their corresponding internal SVGLength objects in the internal SVGLengthList
81 : * objects for the attribute. Getting and setting values of a DOMSVGLength
82 : * requires reading and writing to its internal SVGLength. However, if the
83 : * DOMSVGLength is detached from its DOMSVGLengthList then it first makes a
84 : * copy of its internal SVGLength's value and unit so that it doesn't appear to
85 : * "lose" its value from script's perspective on being removed from the list.
86 : * This means that these DOM tearoffs have space to store these values, even
87 : * though they're not used in the common case.
88 : *
89 : * This class also stores its current list index, attribute enum, and whether
90 : * it belongs to a baseVal or animVal list. This is so that objects of this
91 : * type can find their corresponding internal SVGLength.
92 : *
93 : * To use these classes for <length> attributes as well as <list-of-length>
94 : * attributes, we would need to take a bit from mListIndex and use that to
95 : * indicate whether the object belongs to a list or non-list attribute, then
96 : * if-else as appropriate. The bug for doing that work is:
97 : * https://bugzilla.mozilla.org/show_bug.cgi?id=571734
98 : */
99 : class DOMSVGLength : public nsIDOMSVGLength
100 : {
101 : public:
102 : NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGLENGTH_IID)
103 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
104 1464 : NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGLength)
105 : NS_DECL_NSIDOMSVGLENGTH
106 :
107 : /**
108 : * Generic ctor for DOMSVGLength objects that are created for an attribute.
109 : */
110 : DOMSVGLength(DOMSVGLengthList *aList,
111 : PRUint8 aAttrEnum,
112 : PRUint32 aListIndex,
113 : PRUint8 aIsAnimValItem);
114 :
115 : /**
116 : * Ctor for creating the objects returned by SVGSVGElement.createSVGLength(),
117 : * which do not initially belong to an attribute.
118 : */
119 : DOMSVGLength();
120 :
121 0 : ~DOMSVGLength() {
122 : // Our mList's weak ref to us must be nulled out when we die. If GC has
123 : // unlinked us using the cycle collector code, then that has already
124 : // happened, and mList is null.
125 0 : if (mList) {
126 0 : mList->mItems[mListIndex] = nsnull;
127 : }
128 0 : };
129 :
130 : /**
131 : * Create an unowned copy of an owned length. The caller is responsible for
132 : * the first AddRef().
133 : */
134 0 : DOMSVGLength* Copy() {
135 0 : NS_ASSERTION(mList, "unexpected caller");
136 0 : DOMSVGLength *copy = new DOMSVGLength();
137 0 : SVGLength &length = InternalItem();
138 0 : copy->NewValueSpecifiedUnits(length.GetUnit(), length.GetValueInCurrentUnits());
139 0 : return copy;
140 : }
141 :
142 : bool IsInList() const {
143 : return !!mList;
144 : }
145 :
146 : /**
147 : * In future, if this class is used for non-list lengths, this will be
148 : * different to IsInList().
149 : */
150 0 : bool HasOwner() const {
151 0 : return !!mList;
152 : }
153 :
154 : /**
155 : * This method is called to notify this DOM object that it is being inserted
156 : * into a list, and give it the information it needs as a result.
157 : *
158 : * This object MUST NOT already belong to a list when this method is called.
159 : * That's not to say that script can't move these DOM objects between
160 : * lists - it can - it's just that the logic to handle that (and send out
161 : * the necessary notifications) is located elsewhere (in DOMSVGLengthList).)
162 : */
163 : void InsertingIntoList(DOMSVGLengthList *aList,
164 : PRUint8 aAttrEnum,
165 : PRUint32 aListIndex,
166 : PRUint8 aIsAnimValItem);
167 :
168 0 : static PRUint32 MaxListIndex() {
169 0 : return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
170 : }
171 :
172 : /// This method is called to notify this object that its list index changed.
173 0 : void UpdateListIndex(PRUint32 aListIndex) {
174 0 : mListIndex = aListIndex;
175 0 : }
176 :
177 : /**
178 : * This method is called to notify this DOM object that it is about to be
179 : * removed from its current DOM list so that it can first make a copy of its
180 : * internal counterpart's values. (If it didn't do this, then it would
181 : * "lose" its value on being removed.)
182 : */
183 : void RemovingFromList();
184 :
185 : SVGLength ToSVGLength();
186 :
187 : private:
188 :
189 0 : nsSVGElement* Element() {
190 0 : return mList->Element();
191 : }
192 :
193 : PRUint8 AttrEnum() const {
194 : return mAttrEnum;
195 : }
196 :
197 : /**
198 : * Get the axis that this length lies along. This method must only be called
199 : * when this object is associated with an element (HasOwner() returns true).
200 : */
201 0 : PRUint8 Axis() const {
202 0 : return mList->Axis();
203 : }
204 :
205 : /**
206 : * Get a reference to the internal SVGLength list item that this DOM wrapper
207 : * object currently wraps.
208 : *
209 : * To simplify the code we just have this one method for obtaining both
210 : * baseVal and animVal internal items. This means that animVal items don't
211 : * get const protection, but then our setter methods guard against changing
212 : * animVal items.
213 : */
214 : SVGLength& InternalItem();
215 :
216 : #ifdef DEBUG
217 : bool IndexIsValid();
218 : #endif
219 :
220 : nsRefPtr<DOMSVGLengthList> mList;
221 :
222 : // Bounds for the following are checked in the ctor, so be sure to update
223 : // that if you change the capacity of any of the following.
224 :
225 : PRUint32 mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
226 : PRUint32 mAttrEnum:4; // supports up to 16 attributes
227 : PRUint32 mIsAnimValItem:1;
228 :
229 : // The following members are only used when we're not in a list:
230 : PRUint32 mUnit:5; // can handle 31 units (the 10 SVG 1.1 units + rem, vw, vh, wm, calc + future additions)
231 : float mValue;
232 : };
233 :
234 : NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGLength, MOZILLA_DOMSVGLENGTH_IID)
235 :
236 : } // namespace mozilla
237 :
238 : #undef MOZ_SVG_LIST_INDEX_BIT_COUNT
239 :
240 : #endif // MOZILLA_DOMSVGLENGTH_H__
|