Line data Source code
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/. */
6 :
7 : #include "DOMSVGPoint.h"
8 : #include "DOMSVGPointList.h"
9 : #include "SVGPoint.h"
10 : #include "gfx2DGlue.h"
11 : #include "nsSVGElement.h"
12 : #include "nsError.h"
13 : #include "mozilla/dom/SVGMatrix.h"
14 :
15 : // See the architecture comment in DOMSVGPointList.h.
16 :
17 : using namespace mozilla;
18 : using namespace mozilla::gfx;
19 :
20 : namespace mozilla {
21 :
22 : //----------------------------------------------------------------------
23 : // Helper class: AutoChangePointNotifier
24 : // Stack-based helper class to pair calls to WillChangePointList and
25 : // DidChangePointList.
26 : class MOZ_RAII AutoChangePointNotifier
27 : {
28 : public:
29 0 : explicit AutoChangePointNotifier(DOMSVGPoint* aPoint MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
30 0 : : mPoint(aPoint)
31 : {
32 0 : MOZ_GUARD_OBJECT_NOTIFIER_INIT;
33 0 : MOZ_ASSERT(mPoint, "Expecting non-null point");
34 0 : MOZ_ASSERT(mPoint->HasOwner(),
35 : "Expecting list to have an owner for notification");
36 : mEmptyOrOldValue =
37 0 : mPoint->Element()->WillChangePointList();
38 0 : }
39 :
40 0 : ~AutoChangePointNotifier()
41 0 : {
42 0 : mPoint->Element()->DidChangePointList(mEmptyOrOldValue);
43 0 : if (mPoint->mList->AttrIsAnimating()) {
44 0 : mPoint->Element()->AnimationNeedsResample();
45 : }
46 0 : }
47 :
48 : private:
49 : DOMSVGPoint* const mPoint;
50 : nsAttrValue mEmptyOrOldValue;
51 : MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
52 : };
53 :
54 : } // namespace mozilla
55 :
56 : float
57 0 : DOMSVGPoint::X()
58 : {
59 0 : if (mIsAnimValItem && HasOwner()) {
60 0 : Element()->FlushAnimations(); // May make HasOwner() == false
61 : }
62 0 : return HasOwner() ? InternalItem().mX : mPt.mX;
63 : }
64 :
65 : void
66 0 : DOMSVGPoint::SetX(float aX, ErrorResult& rv)
67 : {
68 0 : if (mIsAnimValItem || mIsReadonly) {
69 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
70 0 : return;
71 : }
72 :
73 0 : if (HasOwner()) {
74 0 : if (InternalItem().mX == aX) {
75 0 : return;
76 : }
77 0 : AutoChangePointNotifier notifier(this);
78 0 : InternalItem().mX = aX;
79 0 : return;
80 : }
81 0 : mPt.mX = aX;
82 : }
83 :
84 : float
85 0 : DOMSVGPoint::Y()
86 : {
87 0 : if (mIsAnimValItem && HasOwner()) {
88 0 : Element()->FlushAnimations(); // May make HasOwner() == false
89 : }
90 0 : return HasOwner() ? InternalItem().mY : mPt.mY;
91 : }
92 :
93 : void
94 0 : DOMSVGPoint::SetY(float aY, ErrorResult& rv)
95 : {
96 0 : if (mIsAnimValItem || mIsReadonly) {
97 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
98 0 : return;
99 : }
100 :
101 0 : if (HasOwner()) {
102 0 : if (InternalItem().mY == aY) {
103 0 : return;
104 : }
105 0 : AutoChangePointNotifier notifier(this);
106 0 : InternalItem().mY = aY;
107 0 : return;
108 : }
109 0 : mPt.mY = aY;
110 : }
111 :
112 : already_AddRefed<nsISVGPoint>
113 0 : DOMSVGPoint::MatrixTransform(dom::SVGMatrix& matrix)
114 : {
115 0 : float x = HasOwner() ? InternalItem().mX : mPt.mX;
116 0 : float y = HasOwner() ? InternalItem().mY : mPt.mY;
117 :
118 0 : Point pt = ToMatrix(matrix.GetMatrix()).TransformPoint(Point(x, y));
119 0 : nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt);
120 0 : return newPoint.forget();
121 : }
|