DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (31ec81b5d7bb)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef NS_ISMILTYPE_H_
#define NS_ISMILTYPE_H_

#include "mozilla/Attributes.h"
#include "nscore.h"

class nsSMILValue;

//////////////////////////////////////////////////////////////////////////////
// nsISMILType: Interface for defining the basic operations needed for animating
// a particular kind of data (e.g. lengths, colors, transformation matrices).
//
// This interface is never used directly but always through an nsSMILValue that
// bundles together a pointer to a concrete implementation of this interface and
// the data upon which it should operate.
//
// We keep the data and type separate rather than just providing different
// subclasses of nsSMILValue. This is so that sizeof(nsSMILValue) is the same
// for all value types, allowing us to have a type-agnostic nsTArray of
// nsSMILValue objects (actual objects, not pointers). It also allows most
// nsSMILValues (except those that need to allocate extra memory for their
// data) to be allocated on the stack and directly assigned to one another
// provided performance benefits for the animation code.
//
// Note that different types have different capabilities. Roughly speaking there
// are probably three main types:
//
// +---------------------+---------------+-------------+------------------+
// | CATEGORY:           | DISCRETE      | LINEAR      | ADDITIVE         |
// +---------------------+---------------+-------------+------------------+
// | Example:            | strings,      | path data?  | lengths,         |
// |                     | color k/words?|             | RGB color values |
// |                     |               |             |                  |
// | -- Assign?          |     X         |    X        |    X             |
// | -- Add?             |     -         |    X?       |    X             |
// | -- SandwichAdd?     |     -         |    -?       |    X             |
// | -- ComputeDistance? |     -         |    -        |    X?            |
// | -- Interpolate?     |     -         |    X        |    X             |
// +---------------------+---------------+-------------+------------------+
//

class nsISMILType
{
  /**
   * Only give the nsSMILValue class access to this interface.
   */
  friend class nsSMILValue;

protected:
  /**
   * Initialises aValue and sets it to some identity value such that adding
   * aValue to another value of the same type has no effect.
   *
   * @pre  aValue.IsNull()
   * @post aValue.mType == this
   */
  virtual void Init(nsSMILValue& aValue) const = 0;

  /**
   * Destroys any data associated with a value of this type.
   *
   * @pre  aValue.mType == this
   * @post aValue.IsNull()
   */
  virtual void Destroy(nsSMILValue& aValue) const = 0;

  /**
   * Assign this object the value of another. Think of this as the assignment
   * operator.
   *
   * @param   aDest       The left-hand side of the assignment.
   * @param   aSrc        The right-hand side of the assignment.
   * @return  NS_OK on success, an error code on failure such as when the
   *          underlying type of the specified object differs.
   *
   * @pre aDest.mType == aSrc.mType == this
   */
  virtual nsresult Assign(nsSMILValue& aDest,
                          const nsSMILValue& aSrc) const = 0;

  /**
   * Test two nsSMILValue objects (of this nsISMILType) for equality.
   *
   * A return value of true represents a guarantee that aLeft and aRight are
   * equal. (That is, they would behave identically if passed to the methods
   * Add, SandwichAdd, ComputeDistance, and Interpolate).
   *
   * A return value of false simply indicates that we make no guarantee
   * about equality.
   *
   * NOTE: It's perfectly legal for implementations of this method to return
   * false in all cases.  However, smarter implementations will make this
   * method more useful for optimization.
   *
   * @param   aLeft       The left-hand side of the equality check.
   * @param   aRight      The right-hand side of the equality check.
   * @return  true if we're sure the values are equal, false otherwise.
   *
   * @pre aDest.mType == aSrc.mType == this
   */
  virtual bool IsEqual(const nsSMILValue& aLeft,
                         const nsSMILValue& aRight) const = 0;

  /**
   * Adds two values.
   *
   * The count parameter facilitates repetition.
   *
   * By equation,
   *
   *   aDest += aValueToAdd * aCount
   *
   * Therefore, if aCount == 0, aDest will be unaltered.
   *
   * This method will fail if this data type is not additive or the value was
   * not specified using an additive syntax.
   *
   * See SVG 1.1, section 19.2.5. In particular,
   *
   *   "If a given attribute or property can take values of keywords (which are
   *   not additive) or numeric values (which are additive), then additive
   *   animations are possible if the subsequent animation uses a numeric value
   *   even if the base animation uses a keyword value; however, if the
   *   subsequent animation uses a keyword value, additive animation is not
   *   possible."
   *
   * If this method fails (e.g. because the data type is not additive), aDest
   * will be unaltered.
   *
   * @param   aDest       The value to add to.
   * @param   aValueToAdd The value to add.
   * @param   aCount      The number of times to add aValueToAdd.
   * @return  NS_OK on success, an error code on failure.
   *
   * @pre aValueToAdd.mType == aDest.mType == this
   */
  virtual nsresult Add(nsSMILValue& aDest,
                       const nsSMILValue& aValueToAdd,
                       uint32_t aCount) const = 0;

  /**
   * Adds aValueToAdd to the underlying value in the animation sandwich, aDest.
   *
   * For most types this operation is identical to a regular Add() but for some
   * types (notably <animateTransform>) the operation differs. For
   * <animateTransform> Add() corresponds to simply adding together the
   * transform parameters and is used when calculating cumulative values or
   * by-animation values. On the other hand SandwichAdd() is used when adding to
   * the underlying value and requires matrix post-multiplication. (This
   * distinction is most clearly indicated by the SVGT1.2 test suite. It is not
   * obvious within the SMIL specifications.)
   *
   * @param   aDest       The value to add to.
   * @param   aValueToAdd The value to add.
   * @return  NS_OK on success, an error code on failure.
   *
   * @pre aValueToAdd.mType == aDest.mType == this
   */
  virtual nsresult SandwichAdd(nsSMILValue& aDest,
                               const nsSMILValue& aValueToAdd) const
  {
    return Add(aDest, aValueToAdd, 1);
  }

  /**
   * Calculates the 'distance' between two values. This is the distance used in
   * paced interpolation.
   *
   * @param   aFrom     The start of the interval for which the distance should
   *                    be calculated.
   * @param   aTo       The end of the interval for which the distance should be
   *                    calculated.
   * @param   aDistance The result of the calculation.
   * @return  NS_OK on success, or an appropriate error code if there is no
   *          notion of distance for the underlying data type or the distance
   *          could not be calculated.
   *
   * @pre aFrom.mType == aTo.mType == this
   */
  virtual nsresult ComputeDistance(const nsSMILValue& aFrom,
                                   const nsSMILValue& aTo,
                                   double& aDistance) const = 0;

  /**
   * Calculates an interpolated value between two values using the specified
   * proportion.
   *
   * @param   aStartVal     The value defining the start of the interval of
   *                        interpolation.
   * @param   aEndVal       The value defining the end of the interval of
   *                        interpolation.
   * @param   aUnitDistance A number between 0.0 and 1.0 (inclusive) defining
   *                        the distance of the interpolated value in the
   *                        interval.
   * @param   aResult       The interpolated value.
   * @return  NS_OK on success, NS_ERROR_FAILURE if this data type cannot be
   *          interpolated or NS_ERROR_OUT_OF_MEMORY if insufficient memory was
   *          available for storing the result.
   *
   * @pre aStartVal.mType == aEndVal.mType == aResult.mType == this
   */
  virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                               const nsSMILValue& aEndVal,
                               double aUnitDistance,
                               nsSMILValue& aResult) const = 0;
};

#endif // NS_ISMILTYPE_H_