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_SVGPOINTLIST_H__
38 : #define MOZILLA_SVGPOINTLIST_H__
39 :
40 : #include "nsCOMPtr.h"
41 : #include "nsDebug.h"
42 : #include "nsIContent.h"
43 : #include "nsINode.h"
44 : #include "nsIWeakReferenceUtils.h"
45 : #include "nsSVGElement.h"
46 : #include "nsTArray.h"
47 : #include "SVGPoint.h"
48 :
49 : #include <string.h>
50 :
51 : namespace mozilla {
52 :
53 : /**
54 : * ATTENTION! WARNING! WATCH OUT!!
55 : *
56 : * Consumers that modify objects of this type absolutely MUST keep the DOM
57 : * wrappers for those lists (if any) in sync!! That's why this class is so
58 : * locked down.
59 : *
60 : * The DOM wrapper class for this class is DOMSVGPointList.
61 : */
62 : class SVGPointList
63 : {
64 : friend class SVGAnimatedPointList;
65 : friend class DOMSVGPointList;
66 : friend class DOMSVGPoint;
67 :
68 : public:
69 :
70 0 : SVGPointList(){}
71 0 : ~SVGPointList(){}
72 :
73 : // Only methods that don't make/permit modification to this list are public.
74 : // Only our friend classes can access methods that may change us.
75 :
76 : /// This may return an incomplete string on OOM, but that's acceptable.
77 : void GetValueAsString(nsAString& aValue) const;
78 :
79 : bool IsEmpty() const {
80 : return mItems.IsEmpty();
81 : }
82 :
83 0 : PRUint32 Length() const {
84 0 : return mItems.Length();
85 : }
86 :
87 0 : const SVGPoint& operator[](PRUint32 aIndex) const {
88 0 : return mItems[aIndex];
89 : }
90 :
91 0 : bool operator==(const SVGPointList& rhs) const {
92 : // memcmp can be faster than |mItems == rhs.mItems|
93 0 : return mItems.Length() == rhs.mItems.Length() &&
94 0 : memcmp(mItems.Elements(), rhs.mItems.Elements(),
95 0 : mItems.Length() * sizeof(SVGPoint)) == 0;
96 : }
97 :
98 0 : bool SetCapacity(PRUint32 aSize) {
99 0 : return mItems.SetCapacity(aSize);
100 : }
101 :
102 : void Compact() {
103 : mItems.Compact();
104 : }
105 :
106 : // Access to methods that can modify objects of this type is deliberately
107 : // limited. This is to reduce the chances of someone modifying objects of
108 : // this type without taking the necessary steps to keep DOM wrappers in sync.
109 : // If you need wider access to these methods, consider adding a method to
110 : // SVGAnimatedPointList and having that class act as an intermediary so it
111 : // can take care of keeping DOM wrappers in sync.
112 :
113 : protected:
114 :
115 : /**
116 : * This may fail on OOM if the internal capacity needs to be increased, in
117 : * which case the list will be left unmodified.
118 : */
119 : nsresult CopyFrom(const SVGPointList& rhs);
120 :
121 0 : SVGPoint& operator[](PRUint32 aIndex) {
122 0 : return mItems[aIndex];
123 : }
124 :
125 : /**
126 : * This may fail (return false) on OOM if the internal capacity is being
127 : * increased, in which case the list will be left unmodified.
128 : */
129 0 : bool SetLength(PRUint32 aNumberOfItems) {
130 0 : return mItems.SetLength(aNumberOfItems);
131 : }
132 :
133 : private:
134 :
135 : // Marking the following private only serves to show which methods are only
136 : // used by our friend classes (as opposed to our subclasses) - it doesn't
137 : // really provide additional safety.
138 :
139 : nsresult SetValueFromString(const nsAString& aValue);
140 :
141 0 : void Clear() {
142 0 : mItems.Clear();
143 0 : }
144 :
145 0 : bool InsertItem(PRUint32 aIndex, const SVGPoint &aPoint) {
146 0 : if (aIndex >= mItems.Length()) {
147 0 : aIndex = mItems.Length();
148 : }
149 0 : return !!mItems.InsertElementAt(aIndex, aPoint);
150 : }
151 :
152 : void ReplaceItem(PRUint32 aIndex, const SVGPoint &aPoint) {
153 : NS_ABORT_IF_FALSE(aIndex < mItems.Length(),
154 : "DOM wrapper caller should have raised INDEX_SIZE_ERR");
155 : mItems[aIndex] = aPoint;
156 : }
157 :
158 0 : void RemoveItem(PRUint32 aIndex) {
159 0 : NS_ABORT_IF_FALSE(aIndex < mItems.Length(),
160 : "DOM wrapper caller should have raised INDEX_SIZE_ERR");
161 0 : mItems.RemoveElementAt(aIndex);
162 0 : }
163 :
164 0 : bool AppendItem(SVGPoint aPoint) {
165 0 : return !!mItems.AppendElement(aPoint);
166 : }
167 :
168 : protected:
169 :
170 : /* See SVGLengthList for the rationale for using nsTArray<SVGPoint> instead
171 : * of nsTArray<SVGPoint, 1>.
172 : */
173 : nsTArray<SVGPoint> mItems;
174 : };
175 :
176 :
177 : /**
178 : * This SVGPointList subclass is for SVGPointListSMILType which needs a
179 : * mutable version of SVGPointList. Instances of this class do not have
180 : * DOM wrappers that need to be kept in sync, so we can safely expose any
181 : * protected base class methods required by the SMIL code.
182 : *
183 : * This class contains a strong reference to the element that instances of
184 : * this class are being used to animate. This is because the SMIL code stores
185 : * instances of this class in nsSMILValue objects, some of which are cached.
186 : * Holding a strong reference to the element here prevents the element from
187 : * disappearing out from under the SMIL code unexpectedly.
188 : */
189 : class SVGPointListAndInfo : public SVGPointList
190 0 : {
191 : public:
192 :
193 0 : SVGPointListAndInfo(nsSVGElement *aElement = nsnull)
194 0 : : mElement(do_GetWeakReference(static_cast<nsINode*>(aElement)))
195 0 : {}
196 :
197 0 : void SetInfo(nsSVGElement *aElement) {
198 0 : mElement = do_GetWeakReference(static_cast<nsINode*>(aElement));
199 0 : }
200 :
201 0 : nsSVGElement* Element() const {
202 0 : nsCOMPtr<nsIContent> e = do_QueryReferent(mElement);
203 0 : return static_cast<nsSVGElement*>(e.get());
204 : }
205 :
206 0 : nsresult CopyFrom(const SVGPointListAndInfo& rhs) {
207 0 : mElement = rhs.mElement;
208 0 : return SVGPointList::CopyFrom(rhs);
209 : }
210 :
211 : /**
212 : * Exposed so that SVGPointList baseVals can be copied to
213 : * SVGPointListAndInfo objects. Note that callers should also call
214 : * SetElement() when using this method!
215 : */
216 0 : nsresult CopyFrom(const SVGPointList& rhs) {
217 0 : return SVGPointList::CopyFrom(rhs);
218 : }
219 0 : const SVGPoint& operator[](PRUint32 aIndex) const {
220 0 : return SVGPointList::operator[](aIndex);
221 : }
222 0 : SVGPoint& operator[](PRUint32 aIndex) {
223 0 : return SVGPointList::operator[](aIndex);
224 : }
225 0 : bool SetLength(PRUint32 aNumberOfItems) {
226 0 : return SVGPointList::SetLength(aNumberOfItems);
227 : }
228 :
229 : private:
230 : // We must keep a weak reference to our element because we may belong to a
231 : // cached baseVal nsSMILValue. See the comments starting at:
232 : // https://bugzilla.mozilla.org/show_bug.cgi?id=515116#c15
233 : // See also https://bugzilla.mozilla.org/show_bug.cgi?id=653497
234 : nsWeakPtr mElement;
235 : };
236 :
237 : } // namespace mozilla
238 :
239 : #endif // MOZILLA_SVGPOINTLIST_H__
|