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 : #ifndef SVGTRANSFORMLISTSMILTYPE_H_
8 : #define SVGTRANSFORMLISTSMILTYPE_H_
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "nsISMILType.h"
12 : #include "nsTArray.h"
13 :
14 : class nsSMILValue;
15 :
16 : namespace mozilla {
17 :
18 : class nsSVGTransform;
19 : class SVGTransformList;
20 : class SVGTransformSMILData;
21 :
22 : ////////////////////////////////////////////////////////////////////////
23 : // SVGTransformListSMILType
24 : //
25 : // Operations for animating an nsSVGTransformList.
26 : //
27 : // This class is confused somewhat by the fact that:
28 : // (i) An <animateTransform> element animates an SVGTransformList
29 : // (ii) BUT <animateTransform> only allows the user to specify animation values
30 : // for an nsSVGTransform
31 : //
32 : // This may be rectified in a future edition of SVG but for now it means that
33 : // the underlying value of an animation may be something of the form:
34 : //
35 : // rotate(90) scale(2) skewX(50)
36 : //
37 : // BUT the animation values can only ever be SINGLE transform operations such as
38 : //
39 : // rotate(90)
40 : //
41 : // (actually the syntax here is:
42 : // <animateTransform type="rotate" from="0" to="90"...
43 : // OR maybe
44 : // <animateTransform type="rotate" values="0; 90; 30; 50"...
45 : // OR even (with a rotation centre)
46 : // <animateTransform type="rotate" values="0 50 20; 30 50 20; 70 0 0"...)
47 : //
48 : // This has many implications for the number of elements we expect in the
49 : // transform array supplied for each operation.
50 : //
51 : // For example, Add() only ever operates on the values specified on an
52 : // <animateTransform> element and so these values can only ever contain 0 or
53 : // 1 TRANSFORM elements as the syntax doesn't allow more. (A "value" here is
54 : // a single element in the values array such as "0 50 20" above.)
55 : //
56 : // Likewise ComputeDistance() only ever operates within the values specified on
57 : // an <animateTransform> element so similar conditions hold.
58 : //
59 : // However, SandwichAdd() combines with a base value which may contain 0..n
60 : // transforms either because the base value of the attribute specifies a series
61 : // of transforms, e.g.
62 : //
63 : // <circle transform="translate(30) rotate(50)"... >
64 : // <animateTransform.../>
65 : // </circle>
66 : //
67 : // or because several animations target the same attribute and are additive and
68 : // so are simply appended on to the transformation array, e.g.
69 : //
70 : // <circle transform="translate(30)"... >
71 : // <animateTransform type="rotate" additive="sum".../>
72 : // <animateTransform type="scale" additive="sum".../>
73 : // <animateTransform type="skewX" additive="sum".../>
74 : // </circle>
75 : //
76 : // Similar conditions hold for Interpolate() which in cases such as to-animation
77 : // may have use a start-value the base value of the target attribute (which as
78 : // we have seen above can contain 0..n elements) whilst the end-value comes from
79 : // the <animateTransform> and so can only hold 1 transform.
80 : //
81 : class SVGTransformListSMILType : public nsISMILType
82 : {
83 : public:
84 : // Singleton for nsSMILValue objects to hold onto.
85 : static SVGTransformListSMILType*
86 0 : Singleton()
87 : {
88 0 : static SVGTransformListSMILType sSingleton;
89 0 : return &sSingleton;
90 : }
91 :
92 : protected:
93 : // nsISMILType Methods
94 : // -------------------
95 : virtual void Init(nsSMILValue& aValue) const override;
96 : virtual void Destroy(nsSMILValue& aValue) const override;
97 : virtual nsresult Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const override;
98 : virtual bool IsEqual(const nsSMILValue& aLeft,
99 : const nsSMILValue& aRight) const override;
100 : virtual nsresult Add(nsSMILValue& aDest,
101 : const nsSMILValue& aValueToAdd,
102 : uint32_t aCount) const override;
103 : virtual nsresult SandwichAdd(nsSMILValue& aDest,
104 : const nsSMILValue& aValueToAdd) const override;
105 : virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
106 : const nsSMILValue& aTo,
107 : double& aDistance) const override;
108 : virtual nsresult Interpolate(const nsSMILValue& aStartVal,
109 : const nsSMILValue& aEndVal,
110 : double aUnitDistance,
111 : nsSMILValue& aResult) const override;
112 :
113 : public:
114 : // Transform array accessors
115 : // -------------------------
116 : static nsresult AppendTransform(const SVGTransformSMILData& aTransform,
117 : nsSMILValue& aValue);
118 : static bool AppendTransforms(const SVGTransformList& aList,
119 : nsSMILValue& aValue);
120 : static bool GetTransforms(const nsSMILValue& aValue,
121 : FallibleTArray<nsSVGTransform>& aTransforms);
122 :
123 :
124 : private:
125 : // Private constructor: prevent instances beyond my singleton.
126 0 : constexpr SVGTransformListSMILType() {}
127 : };
128 :
129 : } // end namespace mozilla
130 :
131 : #endif // SVGLISTTRANSFORMSMILTYPE_H_
|