/work/obj-fuzz/dist/include/mozilla/dom/SVGMatrix.h
Line | Count | Source (jump to first uncovered line) |
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 | | /** |
8 | | * Notes on transforms in Mozilla and the SVG code. |
9 | | * |
10 | | * It's important to note that the matrix convention used in the SVG standard |
11 | | * is the opposite convention to the one used in the Mozilla code or, more |
12 | | * specifically, the convention used in Thebes code (code using gfxMatrix). |
13 | | * Whereas the SVG standard uses the column vector convention, Thebes code uses |
14 | | * the row vector convention. Thus, whereas in the SVG standard you have |
15 | | * [M1][M2][M3]|p|, in Thebes you have |p|'[M3]'[M2]'[M1]'. In other words, the |
16 | | * following are equivalent: |
17 | | * |
18 | | * / a1 c1 tx1 \ / a2 c2 tx2 \ / a3 c3 tx3 \ / x \ |
19 | | * SVG: | b1 d1 ty1 | | b2 d2 ty2 | | b3 d3 ty3 | | y | |
20 | | * \ 0 0 1 / \ 0 0 1 / \ 0 0 1 / \ 1 / |
21 | | * |
22 | | * / a3 b3 0 \ / a2 b2 0 \ / a1 b1 0 \ |
23 | | * Thebes: [ x y 1 ] | c3 d3 0 | | c2 d2 0 | | c1 d1 0 | |
24 | | * \ tx3 ty3 1 / \ tx2 ty2 1 / \ tx1 ty1 1 / |
25 | | * |
26 | | * Because the Thebes representation of a transform is the transpose of the SVG |
27 | | * representation, our transform order must be reversed when representing SVG |
28 | | * transforms using gfxMatrix in the SVG code. Since the SVG implementation |
29 | | * stores and obtains matrices in SVG order, to do this we must pre-multiply |
30 | | * gfxMatrix objects that represent SVG transforms instead of post-multiplying |
31 | | * them as we would for matrices using SVG's column vector convention. |
32 | | * Pre-multiplying may look wrong if you're only familiar with the SVG |
33 | | * convention, but in that case hopefully the above explanation clears things |
34 | | * up. |
35 | | */ |
36 | | |
37 | | #ifndef mozilla_dom_SVGMatrix_h |
38 | | #define mozilla_dom_SVGMatrix_h |
39 | | |
40 | | #include "mozilla/dom/SVGTransform.h" |
41 | | #include "gfxMatrix.h" |
42 | | #include "nsCycleCollectionParticipant.h" |
43 | | #include "nsWrapperCache.h" |
44 | | #include "mozilla/Attributes.h" |
45 | | |
46 | | namespace mozilla { |
47 | | namespace dom { |
48 | | |
49 | | /** |
50 | | * DOM wrapper for an SVG matrix. |
51 | | */ |
52 | | class SVGMatrix final : public nsWrapperCache |
53 | | { |
54 | | public: |
55 | | NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(SVGMatrix) |
56 | | NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(SVGMatrix) |
57 | | |
58 | | /** |
59 | | * Ctor for SVGMatrix objects that belong to a SVGTransform. |
60 | | */ |
61 | 0 | explicit SVGMatrix(SVGTransform& aTransform) : mTransform(&aTransform) {} |
62 | | |
63 | | /** |
64 | | * Ctors for SVGMatrix objects created independently of a SVGTransform. |
65 | | */ |
66 | | // Default ctor for gfxMatrix will produce identity mx |
67 | 0 | SVGMatrix() {} |
68 | | |
69 | 0 | explicit SVGMatrix(const gfxMatrix &aMatrix) : mMatrix(aMatrix) {} |
70 | | |
71 | 0 | const gfxMatrix& GetMatrix() const { |
72 | 0 | return mTransform ? mTransform->Matrixgfx() : mMatrix; |
73 | 0 | } |
74 | | |
75 | | // WebIDL |
76 | | SVGTransform* GetParentObject() const; |
77 | | virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; |
78 | | |
79 | 0 | float A() const { return static_cast<float>(GetMatrix()._11); } |
80 | | void SetA(float aA, ErrorResult& rv); |
81 | 0 | float B() const { return static_cast<float>(GetMatrix()._12); } |
82 | | void SetB(float aB, ErrorResult& rv); |
83 | 0 | float C() const { return static_cast<float>(GetMatrix()._21); } |
84 | | void SetC(float aC, ErrorResult& rv); |
85 | 0 | float D() const { return static_cast<float>(GetMatrix()._22); } |
86 | | void SetD(float aD, ErrorResult& rv); |
87 | 0 | float E() const { return static_cast<float>(GetMatrix()._31); } |
88 | | void SetE(float aE, ErrorResult& rv); |
89 | 0 | float F() const { return static_cast<float>(GetMatrix()._32); } |
90 | | void SetF(float aF, ErrorResult& rv); |
91 | | already_AddRefed<SVGMatrix> Multiply(SVGMatrix& aMatrix); |
92 | | already_AddRefed<SVGMatrix> Inverse(ErrorResult& aRv); |
93 | | already_AddRefed<SVGMatrix> Translate(float x, float y); |
94 | | already_AddRefed<SVGMatrix> Scale(float scaleFactor); |
95 | | already_AddRefed<SVGMatrix> ScaleNonUniform(float scaleFactorX, |
96 | | float scaleFactorY); |
97 | | already_AddRefed<SVGMatrix> Rotate(float angle); |
98 | | already_AddRefed<SVGMatrix> RotateFromVector(float x, |
99 | | float y, |
100 | | ErrorResult& aRv); |
101 | | already_AddRefed<SVGMatrix> FlipX(); |
102 | | already_AddRefed<SVGMatrix> FlipY(); |
103 | | already_AddRefed<SVGMatrix> SkewX(float angle, ErrorResult& rv); |
104 | | already_AddRefed<SVGMatrix> SkewY(float angle, ErrorResult& rv); |
105 | | |
106 | | private: |
107 | 0 | ~SVGMatrix() {} |
108 | | |
109 | 0 | void SetMatrix(const gfxMatrix& aMatrix) { |
110 | 0 | if (mTransform) { |
111 | 0 | mTransform->SetMatrix(aMatrix); |
112 | 0 | } else { |
113 | 0 | mMatrix = aMatrix; |
114 | 0 | } |
115 | 0 | } |
116 | | |
117 | 0 | bool IsAnimVal() const { |
118 | 0 | return mTransform ? mTransform->IsAnimVal() : false; |
119 | 0 | } |
120 | | |
121 | | RefPtr<SVGTransform> mTransform; |
122 | | |
123 | | // Typically we operate on the matrix data accessed via mTransform but for |
124 | | // matrices that exist independently of an SVGTransform we use mMatrix below. |
125 | | gfxMatrix mMatrix; |
126 | | }; |
127 | | |
128 | | } // namespace dom |
129 | | } // namespace mozilla |
130 | | |
131 | | #endif // mozilla_dom_SVGMatrix_h |