Bug 1700051: part 46) Const-qualify `mozInlineSpellStatus::mAnchorRange`. r=smaug
[gecko.git] / dom / svg / DOMSVGPathSeg.cpp
blob80b72730dc1cbb4594bbfdcd23a556e600fb0ff5
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 #include "DOMSVGPathSeg.h"
8 #include "DOMSVGPathSegList.h"
9 #include "SVGAnimatedPathSegList.h"
10 #include "SVGElement.h"
11 #include "mozAutoDocUpdate.h"
12 #include "nsError.h"
14 // See the architecture comment in DOMSVGPathSegList.h.
16 namespace mozilla {
17 namespace dom {
19 using namespace dom::SVGPathSeg_Binding;
21 // We could use NS_IMPL_CYCLE_COLLECTION(, except that in Unlink() we need to
22 // clear our list's weak ref to us to be safe. (The other option would be to
23 // not unlink and rely on the breaking of the other edges in the cycle, as
24 // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
25 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPathSeg)
27 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPathSeg)
28 // We may not belong to a list, so we must null check tmp->mList.
29 if (tmp->mList) {
30 tmp->mList->ItemAt(tmp->mListIndex) = nullptr;
32 NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
33 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
34 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPathSeg)
37 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
38 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
40 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPathSeg)
41 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
42 NS_IMPL_CYCLE_COLLECTION_TRACE_END
44 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMSVGPathSeg, AddRef)
45 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMSVGPathSeg, Release)
47 DOMSVGPathSeg::DOMSVGPathSeg(DOMSVGPathSegList* aList, uint32_t aListIndex,
48 bool aIsAnimValItem)
49 : mList(aList), mListIndex(aListIndex), mIsAnimValItem(aIsAnimValItem) {
50 // These shifts are in sync with the members in the header.
51 MOZ_ASSERT(aList && aListIndex <= MaxListIndex(), "bad arg");
53 MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGPathSeg!");
56 DOMSVGPathSeg::DOMSVGPathSeg()
57 : mList(nullptr), mListIndex(0), mIsAnimValItem(false) {}
59 void DOMSVGPathSeg::InsertingIntoList(DOMSVGPathSegList* aList,
60 uint32_t aListIndex,
61 bool aIsAnimValItem) {
62 MOZ_ASSERT(!HasOwner(), "Inserting item that is already in a list");
64 mList = aList;
65 mListIndex = aListIndex;
66 mIsAnimValItem = aIsAnimValItem;
68 MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGPathSeg!");
71 void DOMSVGPathSeg::RemovingFromList() {
72 uint32_t argCount = SVGPathSegUtils::ArgCountForType(Type());
73 // InternalItem() + 1, because the args come after the encoded seg type
74 memcpy(PtrToMemberArgs(), InternalItem() + 1, argCount * sizeof(float));
75 mList = nullptr;
76 mIsAnimValItem = false;
79 void DOMSVGPathSeg::ToSVGPathSegEncodedData(float* aRaw) {
80 MOZ_ASSERT(aRaw, "null pointer");
81 uint32_t argCount = SVGPathSegUtils::ArgCountForType(Type());
82 if (IsInList()) {
83 // 1 + argCount, because we're copying the encoded seg type and args
84 memcpy(aRaw, InternalItem(), (1 + argCount) * sizeof(float));
85 } else {
86 aRaw[0] = SVGPathSegUtils::EncodeType(Type());
87 // aRaw + 1, because the args go after the encoded seg type
88 memcpy(aRaw + 1, PtrToMemberArgs(), argCount * sizeof(float));
92 float* DOMSVGPathSeg::InternalItem() {
93 uint32_t dataIndex = mList->mItems[mListIndex].mInternalDataIndex;
94 return &(mList->InternalList().mData[dataIndex]);
97 #ifdef DEBUG
98 bool DOMSVGPathSeg::IndexIsValid() {
99 SVGAnimatedPathSegList* alist = Element()->GetAnimPathSegList();
100 return (mIsAnimValItem && mListIndex < alist->GetAnimValue().CountItems()) ||
101 (!mIsAnimValItem && mListIndex < alist->GetBaseValue().CountItems());
103 #endif
105 ////////////////////////////////////////////////////////////////////////
106 // Implementation of DOMSVGPathSeg sub-classes below this point
108 #define IMPL_PROP_WITH_TYPE(segName, propName, index, type) \
109 type DOMSVGPathSeg##segName::propName() { \
110 if (mIsAnimValItem && HasOwner()) { \
111 Element()->FlushAnimations(); /* May make HasOwner() == false */ \
113 return type(HasOwner() ? InternalItem()[1 + index] : mArgs[index]); \
115 void DOMSVGPathSeg##segName::Set##propName(type a##propName, \
116 ErrorResult& rv) { \
117 if (mIsAnimValItem) { \
118 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); \
119 return; \
121 if (HasOwner()) { \
122 if (InternalItem()[1 + index] == float(a##propName)) { \
123 return; \
125 AutoChangePathSegListNotifier notifier(this); \
126 InternalItem()[1 + index] = float(a##propName); \
127 } else { \
128 mArgs[index] = float(a##propName); \
132 // For float, the normal type of arguments
133 #define IMPL_FLOAT_PROP(segName, propName, index) \
134 IMPL_PROP_WITH_TYPE(segName, propName, index, float)
136 // For the boolean flags in arc commands
137 #define IMPL_BOOL_PROP(segName, propName, index) \
138 IMPL_PROP_WITH_TYPE(segName, propName, index, bool)
140 ///////////////////////////////////////////////////////////////////////
142 IMPL_FLOAT_PROP(MovetoAbs, X, 0)
143 IMPL_FLOAT_PROP(MovetoAbs, Y, 1)
145 ////////////////////////////////////////////////////////////////////////
147 IMPL_FLOAT_PROP(MovetoRel, X, 0)
148 IMPL_FLOAT_PROP(MovetoRel, Y, 1)
150 ////////////////////////////////////////////////////////////////////////
152 IMPL_FLOAT_PROP(LinetoAbs, X, 0)
153 IMPL_FLOAT_PROP(LinetoAbs, Y, 1)
155 ////////////////////////////////////////////////////////////////////////
157 IMPL_FLOAT_PROP(LinetoRel, X, 0)
158 IMPL_FLOAT_PROP(LinetoRel, Y, 1)
160 ////////////////////////////////////////////////////////////////////////
162 IMPL_FLOAT_PROP(CurvetoCubicAbs, X1, 0)
163 IMPL_FLOAT_PROP(CurvetoCubicAbs, Y1, 1)
164 IMPL_FLOAT_PROP(CurvetoCubicAbs, X2, 2)
165 IMPL_FLOAT_PROP(CurvetoCubicAbs, Y2, 3)
166 IMPL_FLOAT_PROP(CurvetoCubicAbs, X, 4)
167 IMPL_FLOAT_PROP(CurvetoCubicAbs, Y, 5)
169 ////////////////////////////////////////////////////////////////////////
171 IMPL_FLOAT_PROP(CurvetoCubicRel, X1, 0)
172 IMPL_FLOAT_PROP(CurvetoCubicRel, Y1, 1)
173 IMPL_FLOAT_PROP(CurvetoCubicRel, X2, 2)
174 IMPL_FLOAT_PROP(CurvetoCubicRel, Y2, 3)
175 IMPL_FLOAT_PROP(CurvetoCubicRel, X, 4)
176 IMPL_FLOAT_PROP(CurvetoCubicRel, Y, 5)
178 ////////////////////////////////////////////////////////////////////////
180 IMPL_FLOAT_PROP(CurvetoQuadraticAbs, X1, 0)
181 IMPL_FLOAT_PROP(CurvetoQuadraticAbs, Y1, 1)
182 IMPL_FLOAT_PROP(CurvetoQuadraticAbs, X, 2)
183 IMPL_FLOAT_PROP(CurvetoQuadraticAbs, Y, 3)
185 ////////////////////////////////////////////////////////////////////////
187 IMPL_FLOAT_PROP(CurvetoQuadraticRel, X1, 0)
188 IMPL_FLOAT_PROP(CurvetoQuadraticRel, Y1, 1)
189 IMPL_FLOAT_PROP(CurvetoQuadraticRel, X, 2)
190 IMPL_FLOAT_PROP(CurvetoQuadraticRel, Y, 3)
192 ////////////////////////////////////////////////////////////////////////
194 IMPL_FLOAT_PROP(ArcAbs, R1, 0)
195 IMPL_FLOAT_PROP(ArcAbs, R2, 1)
196 IMPL_FLOAT_PROP(ArcAbs, Angle, 2)
197 IMPL_BOOL_PROP(ArcAbs, LargeArcFlag, 3)
198 IMPL_BOOL_PROP(ArcAbs, SweepFlag, 4)
199 IMPL_FLOAT_PROP(ArcAbs, X, 5)
200 IMPL_FLOAT_PROP(ArcAbs, Y, 6)
202 ////////////////////////////////////////////////////////////////////////
204 IMPL_FLOAT_PROP(ArcRel, R1, 0)
205 IMPL_FLOAT_PROP(ArcRel, R2, 1)
206 IMPL_FLOAT_PROP(ArcRel, Angle, 2)
207 IMPL_BOOL_PROP(ArcRel, LargeArcFlag, 3)
208 IMPL_BOOL_PROP(ArcRel, SweepFlag, 4)
209 IMPL_FLOAT_PROP(ArcRel, X, 5)
210 IMPL_FLOAT_PROP(ArcRel, Y, 6)
212 ////////////////////////////////////////////////////////////////////////
214 IMPL_FLOAT_PROP(LinetoHorizontalAbs, X, 0)
216 ////////////////////////////////////////////////////////////////////////
218 IMPL_FLOAT_PROP(LinetoHorizontalRel, X, 0)
220 ////////////////////////////////////////////////////////////////////////
222 IMPL_FLOAT_PROP(LinetoVerticalAbs, Y, 0)
224 ////////////////////////////////////////////////////////////////////////
226 IMPL_FLOAT_PROP(LinetoVerticalRel, Y, 0)
228 ////////////////////////////////////////////////////////////////////////
230 IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, X2, 0)
231 IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, Y2, 1)
232 IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, X, 2)
233 IMPL_FLOAT_PROP(CurvetoCubicSmoothAbs, Y, 3)
235 ////////////////////////////////////////////////////////////////////////
237 IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, X2, 0)
238 IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, Y2, 1)
239 IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, X, 2)
240 IMPL_FLOAT_PROP(CurvetoCubicSmoothRel, Y, 3)
242 ////////////////////////////////////////////////////////////////////////
244 IMPL_FLOAT_PROP(CurvetoQuadraticSmoothAbs, X, 0)
245 IMPL_FLOAT_PROP(CurvetoQuadraticSmoothAbs, Y, 1)
247 ////////////////////////////////////////////////////////////////////////
249 IMPL_FLOAT_PROP(CurvetoQuadraticSmoothRel, X, 0)
250 IMPL_FLOAT_PROP(CurvetoQuadraticSmoothRel, Y, 1)
252 // This must come after DOMSVGPathSegClosePath et. al. have been declared.
253 /* static */
254 DOMSVGPathSeg* DOMSVGPathSeg::CreateFor(DOMSVGPathSegList* aList,
255 uint32_t aListIndex,
256 bool aIsAnimValItem) {
257 uint32_t dataIndex = aList->mItems[aListIndex].mInternalDataIndex;
258 float* data = &aList->InternalList().mData[dataIndex];
259 uint32_t type = SVGPathSegUtils::DecodeType(data[0]);
261 switch (type) {
262 case PATHSEG_CLOSEPATH:
263 return new DOMSVGPathSegClosePath(aList, aListIndex, aIsAnimValItem);
264 case PATHSEG_MOVETO_ABS:
265 return new DOMSVGPathSegMovetoAbs(aList, aListIndex, aIsAnimValItem);
266 case PATHSEG_MOVETO_REL:
267 return new DOMSVGPathSegMovetoRel(aList, aListIndex, aIsAnimValItem);
268 case PATHSEG_LINETO_ABS:
269 return new DOMSVGPathSegLinetoAbs(aList, aListIndex, aIsAnimValItem);
270 case PATHSEG_LINETO_REL:
271 return new DOMSVGPathSegLinetoRel(aList, aListIndex, aIsAnimValItem);
272 case PATHSEG_CURVETO_CUBIC_ABS:
273 return new DOMSVGPathSegCurvetoCubicAbs(aList, aListIndex,
274 aIsAnimValItem);
275 case PATHSEG_CURVETO_CUBIC_REL:
276 return new DOMSVGPathSegCurvetoCubicRel(aList, aListIndex,
277 aIsAnimValItem);
278 case PATHSEG_CURVETO_QUADRATIC_ABS:
279 return new DOMSVGPathSegCurvetoQuadraticAbs(aList, aListIndex,
280 aIsAnimValItem);
281 case PATHSEG_CURVETO_QUADRATIC_REL:
282 return new DOMSVGPathSegCurvetoQuadraticRel(aList, aListIndex,
283 aIsAnimValItem);
284 case PATHSEG_ARC_ABS:
285 return new DOMSVGPathSegArcAbs(aList, aListIndex, aIsAnimValItem);
286 case PATHSEG_ARC_REL:
287 return new DOMSVGPathSegArcRel(aList, aListIndex, aIsAnimValItem);
288 case PATHSEG_LINETO_HORIZONTAL_ABS:
289 return new DOMSVGPathSegLinetoHorizontalAbs(aList, aListIndex,
290 aIsAnimValItem);
291 case PATHSEG_LINETO_HORIZONTAL_REL:
292 return new DOMSVGPathSegLinetoHorizontalRel(aList, aListIndex,
293 aIsAnimValItem);
294 case PATHSEG_LINETO_VERTICAL_ABS:
295 return new DOMSVGPathSegLinetoVerticalAbs(aList, aListIndex,
296 aIsAnimValItem);
297 case PATHSEG_LINETO_VERTICAL_REL:
298 return new DOMSVGPathSegLinetoVerticalRel(aList, aListIndex,
299 aIsAnimValItem);
300 case PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
301 return new DOMSVGPathSegCurvetoCubicSmoothAbs(aList, aListIndex,
302 aIsAnimValItem);
303 case PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
304 return new DOMSVGPathSegCurvetoCubicSmoothRel(aList, aListIndex,
305 aIsAnimValItem);
306 case PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
307 return new DOMSVGPathSegCurvetoQuadraticSmoothAbs(aList, aListIndex,
308 aIsAnimValItem);
309 case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
310 return new DOMSVGPathSegCurvetoQuadraticSmoothRel(aList, aListIndex,
311 aIsAnimValItem);
312 default:
313 MOZ_ASSERT_UNREACHABLE("Invalid path segment type");
314 return nullptr;
318 } // namespace dom
319 } // namespace mozilla