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 DOM_SMIL_SMILTYPE_H_ 8 #define DOM_SMIL_SMILTYPE_H_ 9 10 #include "mozilla/Attributes.h" 11 #include "nscore.h" 12 13 namespace mozilla { 14 15 class SMILValue; 16 17 ////////////////////////////////////////////////////////////////////////////// 18 // SMILType: Interface for defining the basic operations needed for animating 19 // a particular kind of data (e.g. lengths, colors, transformation matrices). 20 // 21 // This interface is never used directly but always through a SMILValue that 22 // bundles together a pointer to a concrete implementation of this interface and 23 // the data upon which it should operate. 24 // 25 // We keep the data and type separate rather than just providing different 26 // subclasses of SMILValue. This is so that sizeof(SMILValue) is the same 27 // for all value types, allowing us to have a type-agnostic nsTArray of 28 // SMILValue objects (actual objects, not pointers). It also allows most 29 // SMILValues (except those that need to allocate extra memory for their 30 // data) to be allocated on the stack and directly assigned to one another 31 // provided performance benefits for the animation code. 32 // 33 // Note that different types have different capabilities. Roughly speaking there 34 // are probably three main types: 35 // 36 // +---------------------+---------------+-------------+------------------+ 37 // | CATEGORY: | DISCRETE | LINEAR | ADDITIVE | 38 // +---------------------+---------------+-------------+------------------+ 39 // | Example: | strings, | path data? | lengths, | 40 // | | color k/words?| | RGB color values | 41 // | | | | | 42 // | -- Assign? | X | X | X | 43 // | -- Add? | - | X? | X | 44 // | -- SandwichAdd? | - | -? | X | 45 // | -- ComputeDistance? | - | - | X? | 46 // | -- Interpolate? | - | X | X | 47 // +---------------------+---------------+-------------+------------------+ 48 // 49 50 class SMILType { 51 /** 52 * Only give the SMILValue class access to this interface. 53 */ 54 friend class SMILValue; 55 56 protected: 57 /** 58 * Initialises aValue and sets it to some identity value such that adding 59 * aValue to another value of the same type has no effect. 60 * 61 * @pre aValue.IsNull() 62 * @post aValue.mType == this 63 */ 64 virtual void Init(SMILValue& aValue) const = 0; 65 66 /** 67 * Destroys any data associated with a value of this type. 68 * 69 * @pre aValue.mType == this 70 * @post aValue.IsNull() 71 */ 72 virtual void Destroy(SMILValue& aValue) const = 0; 73 74 /** 75 * Assign this object the value of another. Think of this as the assignment 76 * operator. 77 * 78 * @param aDest The left-hand side of the assignment. 79 * @param aSrc The right-hand side of the assignment. 80 * @return NS_OK on success, an error code on failure such as when the 81 * underlying type of the specified object differs. 82 * 83 * @pre aDest.mType == aSrc.mType == this 84 */ 85 virtual nsresult Assign(SMILValue& aDest, const SMILValue& aSrc) const = 0; 86 87 /** 88 * Test two SMILValue objects (of this SMILType) for equality. 89 * 90 * A return value of true represents a guarantee that aLeft and aRight are 91 * equal. (That is, they would behave identically if passed to the methods 92 * Add, SandwichAdd, ComputeDistance, and Interpolate). 93 * 94 * A return value of false simply indicates that we make no guarantee 95 * about equality. 96 * 97 * NOTE: It's perfectly legal for implementations of this method to return 98 * false in all cases. However, smarter implementations will make this 99 * method more useful for optimization. 100 * 101 * @param aLeft The left-hand side of the equality check. 102 * @param aRight The right-hand side of the equality check. 103 * @return true if we're sure the values are equal, false otherwise. 104 * 105 * @pre aDest.mType == aSrc.mType == this 106 */ 107 virtual bool IsEqual(const SMILValue& aLeft, 108 const SMILValue& aRight) const = 0; 109 110 /** 111 * Adds two values. 112 * 113 * The count parameter facilitates repetition. 114 * 115 * By equation, 116 * 117 * aDest += aValueToAdd * aCount 118 * 119 * Therefore, if aCount == 0, aDest will be unaltered. 120 * 121 * This method will fail if this data type is not additive or the value was 122 * not specified using an additive syntax. 123 * 124 * See SVG 1.1, section 19.2.5. In particular, 125 * 126 * "If a given attribute or property can take values of keywords (which are 127 * not additive) or numeric values (which are additive), then additive 128 * animations are possible if the subsequent animation uses a numeric value 129 * even if the base animation uses a keyword value; however, if the 130 * subsequent animation uses a keyword value, additive animation is not 131 * possible." 132 * 133 * If this method fails (e.g. because the data type is not additive), aDest 134 * will be unaltered. 135 * 136 * @param aDest The value to add to. 137 * @param aValueToAdd The value to add. 138 * @param aCount The number of times to add aValueToAdd. 139 * @return NS_OK on success, an error code on failure. 140 * 141 * @pre aValueToAdd.mType == aDest.mType == this 142 */ 143 virtual nsresult Add(SMILValue& aDest, const SMILValue& aValueToAdd, 144 uint32_t aCount) const = 0; 145 146 /** 147 * Adds aValueToAdd to the underlying value in the animation sandwich, aDest. 148 * 149 * For most types this operation is identical to a regular Add() but for some 150 * types (notably <animateTransform>) the operation differs. For 151 * <animateTransform> Add() corresponds to simply adding together the 152 * transform parameters and is used when calculating cumulative values or 153 * by-animation values. On the other hand SandwichAdd() is used when adding to 154 * the underlying value and requires matrix post-multiplication. (This 155 * distinction is most clearly indicated by the SVGT1.2 test suite. It is not 156 * obvious within the SMIL specifications.) 157 * 158 * @param aDest The value to add to. 159 * @param aValueToAdd The value to add. 160 * @return NS_OK on success, an error code on failure. 161 * 162 * @pre aValueToAdd.mType == aDest.mType == this 163 */ SandwichAdd(SMILValue & aDest,const SMILValue & aValueToAdd)164 virtual nsresult SandwichAdd(SMILValue& aDest, 165 const SMILValue& aValueToAdd) const { 166 return Add(aDest, aValueToAdd, 1); 167 } 168 169 /** 170 * Calculates the 'distance' between two values. This is the distance used in 171 * paced interpolation. 172 * 173 * @param aFrom The start of the interval for which the distance should 174 * be calculated. 175 * @param aTo The end of the interval for which the distance should be 176 * calculated. 177 * @param aDistance The result of the calculation. 178 * @return NS_OK on success, or an appropriate error code if there is no 179 * notion of distance for the underlying data type or the distance 180 * could not be calculated. 181 * 182 * @pre aFrom.mType == aTo.mType == this 183 */ 184 virtual nsresult ComputeDistance(const SMILValue& aFrom, const SMILValue& aTo, 185 double& aDistance) const = 0; 186 187 /** 188 * Calculates an interpolated value between two values using the specified 189 * proportion. 190 * 191 * @param aStartVal The value defining the start of the interval of 192 * interpolation. 193 * @param aEndVal The value defining the end of the interval of 194 * interpolation. 195 * @param aUnitDistance A number between 0.0 and 1.0 (inclusive) defining 196 * the distance of the interpolated value in the 197 * interval. 198 * @param aResult The interpolated value. 199 * @return NS_OK on success, NS_ERROR_FAILURE if this data type cannot be 200 * interpolated or NS_ERROR_OUT_OF_MEMORY if insufficient memory was 201 * available for storing the result. 202 * 203 * @pre aStartVal.mType == aEndVal.mType == aResult.mType == this 204 */ 205 virtual nsresult Interpolate(const SMILValue& aStartVal, 206 const SMILValue& aEndVal, double aUnitDistance, 207 SMILValue& aResult) const = 0; 208 }; 209 210 } // namespace mozilla 211 212 #endif // DOM_SMIL_SMILTYPE_H_ 213