Bug 1635304 [wpt PR 23392] - Remove erroneous named properties object test, a=testonly
[gecko.git] / dom / svg / DOMSVGPathSeg.h
blobaa776936df17faf4f6f0d45e0870e66edace9ae9
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 MOZILLA_DOMSVGPATHSEG_H__
8 #define MOZILLA_DOMSVGPATHSEG_H__
10 #include "DOMSVGPathSegList.h"
11 #include "nsCycleCollectionParticipant.h"
12 #include "nsWrapperCache.h"
13 #include "SVGPathSegUtils.h"
14 #include "mozilla/dom/SVGPathSegBinding.h"
16 #define MOZ_SVG_LIST_INDEX_BIT_COUNT 31
18 namespace mozilla {
19 namespace dom {
21 class SVGElement;
23 #define CHECK_ARG_COUNT_IN_SYNC(segType) \
24 MOZ_ASSERT( \
25 ArrayLength(mArgs) == \
26 SVGPathSegUtils::ArgCountForType(uint32_t(segType)) || \
27 uint32_t(segType) == dom::SVGPathSeg_Binding::PATHSEG_CLOSEPATH, \
28 "Arg count/array size out of sync")
30 #define IMPL_SVGPATHSEG_SUBCLASS_COMMON(segName, segType) \
31 explicit DOMSVGPathSeg##segName(const float* aArgs) : DOMSVGPathSeg() { \
32 CHECK_ARG_COUNT_IN_SYNC(segType); \
33 memcpy( \
34 mArgs, aArgs, \
35 SVGPathSegUtils::ArgCountForType(uint32_t(segType)) * sizeof(float)); \
36 } \
37 DOMSVGPathSeg##segName(DOMSVGPathSegList* aList, uint32_t aListIndex, \
38 bool aIsAnimValItem) \
39 : DOMSVGPathSeg(aList, aListIndex, aIsAnimValItem) { \
40 CHECK_ARG_COUNT_IN_SYNC(segType); \
41 } \
42 /* From DOMSVGPathSeg: */ \
43 virtual uint32_t Type() const override { return segType; } \
44 virtual DOMSVGPathSeg* Clone() override { \
45 /* InternalItem() + 1, because we're skipping the encoded seg type */ \
46 float* args = IsInList() ? InternalItem() + 1 : mArgs; \
47 return new DOMSVGPathSeg##segName(args); \
48 } \
49 virtual float* PtrToMemberArgs() override { return mArgs; } \
51 virtual JSObject* WrapObject(JSContext* aCx, \
52 JS::Handle<JSObject*> aGivenProto) override { \
53 return dom::SVGPathSeg##segName##_Binding::Wrap(aCx, this, aGivenProto); \
56 /**
57 * Class DOMSVGPathSeg
59 * This class is the base class of the classes that create the DOM objects that
60 * wrap the internal path segments that are encoded in an SVGPathData. Its
61 * sub-classes are also used to create the objects returned by
62 * SVGPathElement.createSVGPathSegXxx().
64 * See the architecture comment in DOMSVGPathSegList.h for an overview of the
65 * important points regarding these DOM wrapper structures.
67 * See the architecture comment in DOMSVGLength.h (yes, LENGTH) for an overview
68 * of the important points regarding how this specific class works.
70 * The main differences between this class and DOMSVGLength is that we have
71 * sub-classes (it does not), and the "internal counterpart" that we provide a
72 * DOM wrapper for is a list of floats, not an instance of an internal class.
74 class DOMSVGPathSeg : public nsWrapperCache {
75 friend class AutoChangePathSegNotifier;
77 public:
78 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMSVGPathSeg)
79 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMSVGPathSeg)
81 /**
82 * Unlike the other list classes, we hide our ctor (because no one should be
83 * creating instances of this class directly). This factory method in exposed
84 * instead to take care of creating instances of the correct sub-class.
86 static DOMSVGPathSeg* CreateFor(DOMSVGPathSegList* aList, uint32_t aListIndex,
87 bool aIsAnimValItem);
89 /**
90 * Create an unowned copy of this object. The caller is responsible for the
91 * first AddRef()!
93 virtual DOMSVGPathSeg* Clone() = 0;
95 bool IsInList() const { return !!mList; }
97 /**
98 * In future, if this class is used for non-list segments, this will be
99 * different to IsInList().
101 bool HasOwner() const { return !!mList; }
104 * This method is called to notify this DOM object that it is being inserted
105 * into a list, and give it the information it needs as a result.
107 * This object MUST NOT already belong to a list when this method is called.
108 * That's not to say that script can't move these DOM objects between
109 * lists - it can - it's just that the logic to handle that (and send out
110 * the necessary notifications) is located elsewhere (in DOMSVGPathSegList).)
112 void InsertingIntoList(DOMSVGPathSegList* aList, uint32_t aListIndex,
113 bool aIsAnimValItem);
115 static uint32_t MaxListIndex() {
116 return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
119 /// This method is called to notify this object that its list index changed.
120 void UpdateListIndex(uint32_t aListIndex) { mListIndex = aListIndex; }
123 * This method is called to notify this DOM object that it is about to be
124 * removed from its current DOM list so that it can first make a copy of its
125 * internal counterpart's values. (If it didn't do this, then it would
126 * "lose" its value on being removed.)
128 void RemovingFromList();
131 * This method converts the segment to a string of floats as found in
132 * SVGPathData (i.e. the first float contains the type of the segment,
133 * encoded into a float, followed by its arguments in the same order as they
134 * are given in the <path> element's 'd' attribute).
136 void ToSVGPathSegEncodedData(float* aRaw);
139 * The type of this path segment.
141 virtual uint32_t Type() const = 0;
143 // WebIDL
144 DOMSVGPathSegList* GetParentObject() { return mList; }
145 uint16_t PathSegType() const { return Type(); }
146 void GetPathSegTypeAsLetter(nsAString& aPathSegTypeAsLetter) {
147 aPathSegTypeAsLetter = SVGPathSegUtils::GetPathSegTypeAsLetter(Type());
149 virtual JSObject* WrapObject(JSContext* aCx,
150 JS::Handle<JSObject*> aGivenProto) override = 0;
152 protected:
154 * Generic ctor for DOMSVGPathSeg objects that are created for an attribute.
156 DOMSVGPathSeg(DOMSVGPathSegList* aList, uint32_t aListIndex,
157 bool aIsAnimValItem);
160 * Ctor for creating the objects returned by
161 * SVGPathElement.createSVGPathSegXxx(), which do not initially belong to an
162 * attribute.
164 DOMSVGPathSeg();
166 virtual ~DOMSVGPathSeg() {
167 // Our mList's weak ref to us must be nulled out when we die. If GC has
168 // unlinked us using the cycle collector code, then that has already
169 // happened, and mList is null.
170 if (mList) {
171 mList->ItemAt(mListIndex) = nullptr;
175 dom::SVGElement* Element() { return mList->Element(); }
178 * Get a reference to the internal SVGPathSeg list item that this DOM wrapper
179 * object currently wraps.
181 * To simplify the code we just have this one method for obtaining both
182 * baseVal and animVal internal items. This means that animVal items don't
183 * get const protection, but then our setter methods guard against changing
184 * animVal items.
186 float* InternalItem();
188 virtual float* PtrToMemberArgs() = 0;
190 #ifdef DEBUG
191 bool IndexIsValid();
192 #endif
194 RefPtr<DOMSVGPathSegList> mList;
196 // Bounds for the following are checked in the ctor, so be sure to update
197 // that if you change the capacity of any of the following.
199 uint32_t mListIndex : MOZ_SVG_LIST_INDEX_BIT_COUNT;
200 uint32_t mIsAnimValItem : 1; // uint32_t because MSVC won't pack otherwise
203 class DOMSVGPathSegClosePath : public DOMSVGPathSeg {
204 public:
205 DOMSVGPathSegClosePath() : DOMSVGPathSeg() {}
207 IMPL_SVGPATHSEG_SUBCLASS_COMMON(ClosePath,
208 dom::SVGPathSeg_Binding::PATHSEG_CLOSEPATH)
210 protected:
211 // To allow IMPL_SVGPATHSEG_SUBCLASS_COMMON above to compile we need an
212 // mArgs, but since C++ doesn't allow zero-sized arrays we need to give it
213 // one (unused) element.
214 float mArgs[1];
217 class DOMSVGPathSegMovetoAbs : public DOMSVGPathSeg {
218 public:
219 DOMSVGPathSegMovetoAbs(float x, float y) : DOMSVGPathSeg() {
220 mArgs[0] = x;
221 mArgs[1] = y;
224 IMPL_SVGPATHSEG_SUBCLASS_COMMON(MovetoAbs,
225 dom::SVGPathSeg_Binding::PATHSEG_MOVETO_ABS)
227 float X();
228 void SetX(float aX, ErrorResult& rv);
229 float Y();
230 void SetY(float aY, ErrorResult& rv);
232 protected:
233 float mArgs[2];
236 class DOMSVGPathSegMovetoRel : public DOMSVGPathSeg {
237 public:
238 DOMSVGPathSegMovetoRel(float x, float y) : DOMSVGPathSeg() {
239 mArgs[0] = x;
240 mArgs[1] = y;
243 IMPL_SVGPATHSEG_SUBCLASS_COMMON(MovetoRel,
244 dom::SVGPathSeg_Binding::PATHSEG_MOVETO_REL)
246 float X();
247 void SetX(float aX, ErrorResult& rv);
248 float Y();
249 void SetY(float aY, ErrorResult& rv);
251 protected:
252 float mArgs[2];
255 class DOMSVGPathSegLinetoAbs : public DOMSVGPathSeg {
256 public:
257 DOMSVGPathSegLinetoAbs(float x, float y) : DOMSVGPathSeg() {
258 mArgs[0] = x;
259 mArgs[1] = y;
262 IMPL_SVGPATHSEG_SUBCLASS_COMMON(LinetoAbs,
263 dom::SVGPathSeg_Binding::PATHSEG_LINETO_ABS)
265 float X();
266 void SetX(float aX, ErrorResult& rv);
267 float Y();
268 void SetY(float aY, ErrorResult& rv);
270 protected:
271 float mArgs[2];
274 class DOMSVGPathSegLinetoRel : public DOMSVGPathSeg {
275 public:
276 DOMSVGPathSegLinetoRel(float x, float y) : DOMSVGPathSeg() {
277 mArgs[0] = x;
278 mArgs[1] = y;
281 IMPL_SVGPATHSEG_SUBCLASS_COMMON(LinetoRel,
282 dom::SVGPathSeg_Binding::PATHSEG_LINETO_REL)
284 float X();
285 void SetX(float aX, ErrorResult& rv);
286 float Y();
287 void SetY(float aY, ErrorResult& rv);
289 protected:
290 float mArgs[2];
293 class DOMSVGPathSegCurvetoCubicAbs : public DOMSVGPathSeg {
294 public:
295 DOMSVGPathSegCurvetoCubicAbs(float x1, float y1, float x2, float y2, float x,
296 float y)
297 : DOMSVGPathSeg() {
298 mArgs[0] = x1;
299 mArgs[1] = y1;
300 mArgs[2] = x2;
301 mArgs[3] = y2;
302 mArgs[4] = x;
303 mArgs[5] = y;
306 float X();
307 void SetX(float aX, ErrorResult& rv);
308 float Y();
309 void SetY(float aY, ErrorResult& rv);
310 float X1();
311 void SetX1(float aX1, ErrorResult& rv);
312 float Y1();
313 void SetY1(float aY1, ErrorResult& rv);
314 float X2();
315 void SetX2(float aX2, ErrorResult& rv);
316 float Y2();
317 void SetY2(float aY2, ErrorResult& rv);
319 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
320 CurvetoCubicAbs, dom::SVGPathSeg_Binding::PATHSEG_CURVETO_CUBIC_ABS)
322 protected:
323 float mArgs[6];
326 class DOMSVGPathSegCurvetoCubicRel : public DOMSVGPathSeg {
327 public:
328 DOMSVGPathSegCurvetoCubicRel(float x1, float y1, float x2, float y2, float x,
329 float y)
330 : DOMSVGPathSeg() {
331 mArgs[0] = x1;
332 mArgs[1] = y1;
333 mArgs[2] = x2;
334 mArgs[3] = y2;
335 mArgs[4] = x;
336 mArgs[5] = y;
339 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
340 CurvetoCubicRel, dom::SVGPathSeg_Binding::PATHSEG_CURVETO_CUBIC_REL)
342 float X();
343 void SetX(float aX, ErrorResult& rv);
344 float Y();
345 void SetY(float aY, ErrorResult& rv);
346 float X1();
347 void SetX1(float aX1, ErrorResult& rv);
348 float Y1();
349 void SetY1(float aY1, ErrorResult& rv);
350 float X2();
351 void SetX2(float aX2, ErrorResult& rv);
352 float Y2();
353 void SetY2(float aY2, ErrorResult& rv);
355 protected:
356 float mArgs[6];
359 class DOMSVGPathSegCurvetoQuadraticAbs : public DOMSVGPathSeg {
360 public:
361 DOMSVGPathSegCurvetoQuadraticAbs(float x1, float y1, float x, float y)
362 : DOMSVGPathSeg() {
363 mArgs[0] = x1;
364 mArgs[1] = y1;
365 mArgs[2] = x;
366 mArgs[3] = y;
369 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
370 CurvetoQuadraticAbs,
371 dom::SVGPathSeg_Binding::PATHSEG_CURVETO_QUADRATIC_ABS)
373 float X();
374 void SetX(float aX, ErrorResult& rv);
375 float Y();
376 void SetY(float aY, ErrorResult& rv);
377 float X1();
378 void SetX1(float aX1, ErrorResult& rv);
379 float Y1();
380 void SetY1(float aY1, ErrorResult& rv);
382 protected:
383 float mArgs[4];
386 class DOMSVGPathSegCurvetoQuadraticRel : public DOMSVGPathSeg {
387 public:
388 DOMSVGPathSegCurvetoQuadraticRel(float x1, float y1, float x, float y)
389 : DOMSVGPathSeg() {
390 mArgs[0] = x1;
391 mArgs[1] = y1;
392 mArgs[2] = x;
393 mArgs[3] = y;
396 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
397 CurvetoQuadraticRel,
398 dom::SVGPathSeg_Binding::PATHSEG_CURVETO_QUADRATIC_REL)
400 float X();
401 void SetX(float aX, ErrorResult& rv);
402 float Y();
403 void SetY(float aY, ErrorResult& rv);
404 float X1();
405 void SetX1(float aX1, ErrorResult& rv);
406 float Y1();
407 void SetY1(float aY1, ErrorResult& rv);
409 protected:
410 float mArgs[4];
413 class DOMSVGPathSegArcAbs : public DOMSVGPathSeg {
414 public:
415 DOMSVGPathSegArcAbs(float r1, float r2, float angle, bool largeArcFlag,
416 bool sweepFlag, float x, float y)
417 : DOMSVGPathSeg() {
418 mArgs[0] = r1;
419 mArgs[1] = r2;
420 mArgs[2] = angle;
421 mArgs[3] = largeArcFlag;
422 mArgs[4] = sweepFlag;
423 mArgs[5] = x;
424 mArgs[6] = y;
427 IMPL_SVGPATHSEG_SUBCLASS_COMMON(ArcAbs,
428 dom::SVGPathSeg_Binding::PATHSEG_ARC_ABS)
430 float X();
431 void SetX(float aX, ErrorResult& rv);
432 float Y();
433 void SetY(float aY, ErrorResult& rv);
434 float R1();
435 void SetR1(float aR1, ErrorResult& rv);
436 float R2();
437 void SetR2(float aR2, ErrorResult& rv);
438 float Angle();
439 void SetAngle(float aAngle, ErrorResult& rv);
440 bool LargeArcFlag();
441 void SetLargeArcFlag(bool aLargeArcFlag, ErrorResult& rv);
442 bool SweepFlag();
443 void SetSweepFlag(bool aSweepFlag, ErrorResult& rv);
445 protected:
446 float mArgs[7];
449 class DOMSVGPathSegArcRel : public DOMSVGPathSeg {
450 public:
451 DOMSVGPathSegArcRel(float r1, float r2, float angle, bool largeArcFlag,
452 bool sweepFlag, float x, float y)
453 : DOMSVGPathSeg() {
454 mArgs[0] = r1;
455 mArgs[1] = r2;
456 mArgs[2] = angle;
457 mArgs[3] = largeArcFlag;
458 mArgs[4] = sweepFlag;
459 mArgs[5] = x;
460 mArgs[6] = y;
463 IMPL_SVGPATHSEG_SUBCLASS_COMMON(ArcRel,
464 dom::SVGPathSeg_Binding::PATHSEG_ARC_REL)
466 float X();
467 void SetX(float aX, ErrorResult& rv);
468 float Y();
469 void SetY(float aY, ErrorResult& rv);
470 float R1();
471 void SetR1(float aR1, ErrorResult& rv);
472 float R2();
473 void SetR2(float aR2, ErrorResult& rv);
474 float Angle();
475 void SetAngle(float aAngle, ErrorResult& rv);
476 bool LargeArcFlag();
477 void SetLargeArcFlag(bool aLargeArcFlag, ErrorResult& rv);
478 bool SweepFlag();
479 void SetSweepFlag(bool aSweepFlag, ErrorResult& rv);
481 protected:
482 float mArgs[7];
485 class DOMSVGPathSegLinetoHorizontalAbs : public DOMSVGPathSeg {
486 public:
487 explicit DOMSVGPathSegLinetoHorizontalAbs(float x) : DOMSVGPathSeg() {
488 mArgs[0] = x;
491 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
492 LinetoHorizontalAbs,
493 dom::SVGPathSeg_Binding::PATHSEG_LINETO_HORIZONTAL_ABS)
495 float X();
496 void SetX(float aX, ErrorResult& rv);
498 protected:
499 float mArgs[1];
502 class DOMSVGPathSegLinetoHorizontalRel : public DOMSVGPathSeg {
503 public:
504 explicit DOMSVGPathSegLinetoHorizontalRel(float x) : DOMSVGPathSeg() {
505 mArgs[0] = x;
508 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
509 LinetoHorizontalRel,
510 dom::SVGPathSeg_Binding::PATHSEG_LINETO_HORIZONTAL_REL)
512 float X();
513 void SetX(float aX, ErrorResult& rv);
515 protected:
516 float mArgs[1];
519 class DOMSVGPathSegLinetoVerticalAbs : public DOMSVGPathSeg {
520 public:
521 explicit DOMSVGPathSegLinetoVerticalAbs(float y) : DOMSVGPathSeg() {
522 mArgs[0] = y;
525 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
526 LinetoVerticalAbs, dom::SVGPathSeg_Binding::PATHSEG_LINETO_VERTICAL_ABS)
528 float Y();
529 void SetY(float aY, ErrorResult& rv);
531 protected:
532 float mArgs[1];
535 class DOMSVGPathSegLinetoVerticalRel : public DOMSVGPathSeg {
536 public:
537 explicit DOMSVGPathSegLinetoVerticalRel(float y) : DOMSVGPathSeg() {
538 mArgs[0] = y;
541 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
542 LinetoVerticalRel, dom::SVGPathSeg_Binding::PATHSEG_LINETO_VERTICAL_REL)
544 float Y();
545 void SetY(float aY, ErrorResult& rv);
547 protected:
548 float mArgs[1];
551 class DOMSVGPathSegCurvetoCubicSmoothAbs : public DOMSVGPathSeg {
552 public:
553 DOMSVGPathSegCurvetoCubicSmoothAbs(float x2, float y2, float x, float y)
554 : DOMSVGPathSeg() {
555 mArgs[0] = x2;
556 mArgs[1] = y2;
557 mArgs[2] = x;
558 mArgs[3] = y;
561 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
562 CurvetoCubicSmoothAbs,
563 dom::SVGPathSeg_Binding::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS)
565 float X();
566 void SetX(float aX, ErrorResult& rv);
567 float Y();
568 void SetY(float aY, ErrorResult& rv);
569 float X2();
570 void SetX2(float aX2, ErrorResult& rv);
571 float Y2();
572 void SetY2(float aY2, ErrorResult& rv);
574 protected:
575 float mArgs[4];
578 class DOMSVGPathSegCurvetoCubicSmoothRel : public DOMSVGPathSeg {
579 public:
580 DOMSVGPathSegCurvetoCubicSmoothRel(float x2, float y2, float x, float y)
581 : DOMSVGPathSeg() {
582 mArgs[0] = x2;
583 mArgs[1] = y2;
584 mArgs[2] = x;
585 mArgs[3] = y;
588 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
589 CurvetoCubicSmoothRel,
590 dom::SVGPathSeg_Binding::PATHSEG_CURVETO_CUBIC_SMOOTH_REL)
592 float X();
593 void SetX(float aX, ErrorResult& rv);
594 float Y();
595 void SetY(float aY, ErrorResult& rv);
596 float X2();
597 void SetX2(float aX2, ErrorResult& rv);
598 float Y2();
599 void SetY2(float aY2, ErrorResult& rv);
601 protected:
602 float mArgs[4];
605 class DOMSVGPathSegCurvetoQuadraticSmoothAbs : public DOMSVGPathSeg {
606 public:
607 DOMSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y) : DOMSVGPathSeg() {
608 mArgs[0] = x;
609 mArgs[1] = y;
612 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
613 CurvetoQuadraticSmoothAbs,
614 dom::SVGPathSeg_Binding::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS)
616 float X();
617 void SetX(float aX, ErrorResult& rv);
618 float Y();
619 void SetY(float aY, ErrorResult& rv);
621 protected:
622 float mArgs[2];
625 class DOMSVGPathSegCurvetoQuadraticSmoothRel : public DOMSVGPathSeg {
626 public:
627 DOMSVGPathSegCurvetoQuadraticSmoothRel(float x, float y) : DOMSVGPathSeg() {
628 mArgs[0] = x;
629 mArgs[1] = y;
632 IMPL_SVGPATHSEG_SUBCLASS_COMMON(
633 CurvetoQuadraticSmoothRel,
634 dom::SVGPathSeg_Binding::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL)
636 float X();
637 void SetX(float aX, ErrorResult& rv);
638 float Y();
639 void SetY(float aY, ErrorResult& rv);
641 protected:
642 float mArgs[2];
645 } // namespace dom
646 } // namespace mozilla
648 #undef MOZ_SVG_LIST_INDEX_BIT_COUNT
650 #endif // MOZILLA_DOMSVGPATHSEG_H__