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.

Implementation

Mercurial (b6d82b1a6b02)

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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 MOZILLA_SVGTRANSFORM_H__
#define MOZILLA_SVGTRANSFORM_H__

#include "gfxMatrix.h"
#include "mozilla/dom/SVGTransformBinding.h"
#include "mozilla/gfx/Matrix.h"
#include "nsDebug.h"

namespace mozilla {

/*
 * The DOM wrapper class for this class is DOMSVGTransform.
 */
class SVGTransform {
 public:
  // Default ctor initialises to matrix type with identity matrix
  SVGTransform()
      : mMatrix()  // Initialises to identity
        ,
        mAngle(0.f),
        mOriginX(0.f),
        mOriginY(0.f),
        mType(dom::SVGTransform_Binding::SVG_TRANSFORM_MATRIX) {}

  explicit SVGTransform(const gfxMatrix& aMatrix)
      : mMatrix(aMatrix),
        mAngle(0.f),
        mOriginX(0.f),
        mOriginY(0.f),
        mType(dom::SVGTransform_Binding::SVG_TRANSFORM_MATRIX) {}

  bool operator==(const SVGTransform& rhs) const {
    return mType == rhs.mType && MatricesEqual(mMatrix, rhs.mMatrix) &&
           mAngle == rhs.mAngle && mOriginX == rhs.mOriginX &&
           mOriginY == rhs.mOriginY;
  }

  void GetValueAsString(nsAString& aValue) const;

  float Angle() const { return mAngle; }
  void GetRotationOrigin(float& aOriginX, float& aOriginY) const {
    aOriginX = mOriginX;
    aOriginY = mOriginY;
  }
  uint16_t Type() const { return mType; }

  const gfxMatrix& GetMatrix() const { return mMatrix; }
  void SetMatrix(const gfxMatrix& aMatrix);
  void SetTranslate(float aTx, float aTy);
  void SetScale(float aSx, float aSy);
  void SetRotate(float aAngle, float aCx, float aCy);
  nsresult SetSkewX(float aAngle);
  nsresult SetSkewY(float aAngle);

  static bool MatricesEqual(const gfxMatrix& a, const gfxMatrix& b) {
    return a._11 == b._11 && a._12 == b._12 && a._21 == b._21 &&
           a._22 == b._22 && a._31 == b._31 && a._32 == b._32;
  }

 protected:
  gfxMatrix mMatrix;
  float mAngle, mOriginX, mOriginY;
  uint16_t mType;
};

/*
 * A slightly more light-weight version of SVGTransform for SMIL animation.
 *
 * Storing the parameters in an array (rather than a matrix) also allows simpler
 * (transform type-agnostic) interpolation and addition.
 *
 * The meaning of the mParams array depends on the transform type as follows:
 *
 * Type                | mParams[0], mParams[1], mParams[2], ...
 * --------------------+-----------------------------------------
 * translate           | tx, ty
 * scale               | sx, sy
 * rotate              | rotation-angle (in degrees), cx, cy
 * skewX               | skew-angle (in degrees)
 * skewY               | skew-angle (in degrees)
 * matrix              | a, b, c, d, e, f
 *
 * The matrix type is never generated by animation code (it is only produced
 * when the user inserts one via the DOM) and often requires special handling
 * when we do encounter it. Therefore many users of this class are only
 * interested in the first three parameters and so we provide a special
 * constructor for setting those parameters only.
 */
class SVGTransformSMILData {
 public:
  // Number of float-params required in constructor, if constructing one of the
  // 'simple' transform types (all but matrix type)
  static const uint32_t NUM_SIMPLE_PARAMS = 3;

  // Number of float-params required in constructor for matrix type.
  // This is also the number of params we actually store, regardless of type.
  static const uint32_t NUM_STORED_PARAMS = 6;

  explicit SVGTransformSMILData(uint16_t aType) : mTransformType(aType) {
    MOZ_ASSERT(aType >= dom::SVGTransform_Binding::SVG_TRANSFORM_MATRIX &&
                   aType <= dom::SVGTransform_Binding::SVG_TRANSFORM_SKEWY,
               "Unexpected transform type");
    for (uint32_t i = 0; i < NUM_STORED_PARAMS; ++i) {
      mParams[i] = 0.f;
    }
  }

  SVGTransformSMILData(uint16_t aType, float (&aParams)[NUM_SIMPLE_PARAMS])
      : mTransformType(aType) {
    MOZ_ASSERT(aType >= dom::SVGTransform_Binding::SVG_TRANSFORM_TRANSLATE &&
                   aType <= dom::SVGTransform_Binding::SVG_TRANSFORM_SKEWY,
               "Expected 'simple' transform type");
    for (uint32_t i = 0; i < NUM_SIMPLE_PARAMS; ++i) {
      mParams[i] = aParams[i];
    }
    for (uint32_t i = NUM_SIMPLE_PARAMS; i < NUM_STORED_PARAMS; ++i) {
      mParams[i] = 0.f;
    }
  }

  // Conversion to/from a fully-fledged SVGTransform
  explicit SVGTransformSMILData(const SVGTransform& aTransform);
  SVGTransform ToSVGTransform() const;

  bool operator==(const SVGTransformSMILData& aOther) const {
    if (mTransformType != aOther.mTransformType) return false;

    for (uint32_t i = 0; i < NUM_STORED_PARAMS; ++i) {
      if (mParams[i] != aOther.mParams[i]) {
        return false;
      }
    }

    return true;
  }

  bool operator!=(const SVGTransformSMILData& aOther) const {
    return !(*this == aOther);
  }

  uint16_t mTransformType;
  float mParams[NUM_STORED_PARAMS];
};

}  // namespace mozilla

#endif  // MOZILLA_SVGTRANSFORM_H__