Bug 1377090 - Make the Matrix class templated so we can instantiate it with a double type. r?Bas
This extracts a BaseMatrix template of which Matrix is now a particular
specialization. The BaseMatrix allows us to reuse the same code for
floats and doubles, much like the other "base" classes (BasePoint,
BaseRect, etc.).
MozReview-Commit-ID: HO7bA83S9E0
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -28,17 +28,17 @@ include JavaScriptTypes;
include URIParams;
include PPrintingTypes;
include PTabContext;
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/LayersMessageUtils.h";
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
-using class mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h";
+using mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDevicePoint from "Units.h";
using mozilla::ScreenIntPoint from "Units.h";
using ScreenIntSize from "Units.h";
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
using struct mozilla::layers::ZoomConstraints from "FrameMetrics.h";
using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
--- a/dom/svg/SVGContentUtils.h
+++ b/dom/svg/SVGContentUtils.h
@@ -29,19 +29,16 @@ class nsSVGAnimatedTransformList;
class SVGAnimatedPreserveAspectRatio;
class SVGContextPaint;
class SVGPreserveAspectRatio;
namespace dom {
class Element;
class SVGSVGElement;
} // namespace dom
-namespace gfx {
-class Matrix;
-} // namespace gfx
} // namespace mozilla
#define SVG_ZERO_LENGTH_PATH_FIX_FACTOR 512
/**
* SVGTransformTypes controls the transforms that PrependLocalTransformsTo
* applies.
*
--- a/dom/svg/SVGMotionSMILType.h
+++ b/dom/svg/SVGMotionSMILType.h
@@ -12,20 +12,16 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/Attributes.h"
#include "nsISMILType.h"
class nsSMILValue;
namespace mozilla {
-namespace gfx {
-class Matrix;
-} // namespace gfx
-
/**
* MotionRotateType: Enum to indicate the type of our "rotate" attribute.
*/
enum RotateType {
eRotateType_Explicit, // for e.g. rotate="45"/"45deg"/"0.785rad"
eRotateType_Auto, // for rotate="auto"
eRotateType_AutoReverse // for rotate="auto-reverse"
};
--- a/dom/svg/nsSVGElement.h
+++ b/dom/svg/nsSVGElement.h
@@ -15,16 +15,17 @@
#include "mozilla/Attributes.h"
#include "nsAutoPtr.h"
#include "nsChangeHint.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsError.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/Element.h"
+#include "mozilla/gfx/MatrixFwd.h"
#include "nsISupportsImpl.h"
#include "nsStyledElement.h"
#include "nsSVGClass.h"
#include "nsIDOMSVGElement.h"
#include "SVGContentUtils.h"
class nsSVGAngle;
class nsSVGBoolean;
@@ -55,20 +56,16 @@ class SVGAnimatedLengthList;
class SVGUserUnitList;
class SVGAnimatedPointList;
class SVGAnimatedPathSegList;
class SVGAnimatedPreserveAspectRatio;
class nsSVGAnimatedTransformList;
class SVGStringList;
class DOMSVGStringList;
-namespace gfx {
-class Matrix;
-} // namespace gfx
-
} // namespace mozilla
class gfxMatrix;
struct nsSVGEnumMapping;
typedef nsStyledElement nsSVGElementBase;
class nsSVGElement : public nsSVGElementBase // nsIContent
--- a/gfx/2d/Matrix.cpp
+++ b/gfx/2d/Matrix.cpp
@@ -54,45 +54,33 @@ SafeTangent(double aTheta)
if (cosTheta >= 0 && cosTheta < kEpsilon) {
cosTheta = kEpsilon;
} else if (cosTheta < 0 && cosTheta >= -kEpsilon) {
cosTheta = -kEpsilon;
}
return FlushToZero(sinTheta / cosTheta);
}
-std::ostream&
-operator<<(std::ostream& aStream, const Matrix& aMatrix)
-{
- return aStream << "[ " << aMatrix._11
- << " " << aMatrix._12
- << "; " << aMatrix._21
- << " " << aMatrix._22
- << "; " << aMatrix._31
- << " " << aMatrix._32
- << "; ]";
-}
-
-Matrix
+template<> Matrix
Matrix::Rotation(Float aAngle)
{
Matrix newMatrix;
Float s = sinf(aAngle);
Float c = cosf(aAngle);
newMatrix._11 = c;
newMatrix._12 = s;
newMatrix._21 = -s;
newMatrix._22 = c;
return newMatrix;
}
-Rect
+template<> Rect
Matrix::TransformBounds(const Rect &aRect) const
{
int i;
Point quad[4];
Float min_x, max_x;
Float min_y, max_y;
quad[0] = TransformPoint(aRect.TopLeft());
@@ -113,17 +101,17 @@ Matrix::TransformBounds(const Rect &aRec
min_y = quad[i].y;
if (quad[i].y > max_y)
max_y = quad[i].y;
}
return Rect(min_x, min_y, max_x - min_x, max_y - min_y);
}
-Matrix&
+template<> Matrix&
Matrix::NudgeToIntegers()
{
NudgeToInteger(&_11);
NudgeToInteger(&_12);
NudgeToInteger(&_21);
NudgeToInteger(&_22);
NudgeToInteger(&_31);
NudgeToInteger(&_32);
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -15,49 +15,59 @@
#include <math.h>
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/FloatingPoint.h"
namespace mozilla {
namespace gfx {
-static bool FuzzyEqual(Float aV1, Float aV2) {
+static inline bool FuzzyEqual(Float aV1, Float aV2) {
// XXX - Check if fabs does the smart thing and just negates the sign bit.
return fabs(aV2 - aV1) < 1e-6;
}
-class Matrix
+template<class T>
+class BaseMatrix
{
public:
- Matrix()
+ BaseMatrix()
: _11(1.0f), _12(0)
, _21(0), _22(1.0f)
, _31(0), _32(0)
{}
- Matrix(Float a11, Float a12, Float a21, Float a22, Float a31, Float a32)
+ BaseMatrix(T a11, T a12, T a21, T a22, T a31, T a32)
: _11(a11), _12(a12)
, _21(a21), _22(a22)
, _31(a31), _32(a32)
{}
union {
struct {
- Float _11, _12;
- Float _21, _22;
- Float _31, _32;
+ T _11, _12;
+ T _21, _22;
+ T _31, _32;
};
- Float components[6];
+ T components[6];
};
- MOZ_ALWAYS_INLINE Matrix Copy() const
+ MOZ_ALWAYS_INLINE BaseMatrix Copy() const
{
- return Matrix(*this);
+ return BaseMatrix<T>(*this);
}
- friend std::ostream& operator<<(std::ostream& aStream, const Matrix& aMatrix);
+ friend std::ostream& operator<<(std::ostream& aStream, const BaseMatrix& aMatrix)
+ {
+ return aStream << "[ " << aMatrix._11
+ << " " << aMatrix._12
+ << "; " << aMatrix._21
+ << " " << aMatrix._22
+ << "; " << aMatrix._31
+ << " " << aMatrix._32
+ << "; ]";
+ }
Point TransformPoint(const Point &aPoint) const
{
Point retPoint;
retPoint.x = aPoint.x * _11 + aPoint.y * _21 + _31;
retPoint.y = aPoint.x * _12 + aPoint.y * _22 + _32;
@@ -69,213 +79,213 @@ public:
Size retSize;
retSize.width = aSize.width * _11 + aSize.height * _21;
retSize.height = aSize.width * _12 + aSize.height * _22;
return retSize;
}
- GFX2D_API Rect TransformBounds(const Rect& rect) const;
+ GFX2D_API Rect TransformBounds(const Rect& aRect) const;
- static Matrix Translation(Float aX, Float aY)
+ static BaseMatrix<T> Translation(T aX, T aY)
{
- return Matrix(1.0f, 0.0f, 0.0f, 1.0f, aX, aY);
+ return BaseMatrix<T>(1.0f, 0.0f, 0.0f, 1.0f, aX, aY);
}
- static Matrix Translation(Point aPoint)
+ static BaseMatrix<T> Translation(Point aPoint)
{
return Translation(aPoint.x, aPoint.y);
}
/**
* Apply a translation to this matrix.
*
* The "Pre" in this method's name means that the translation is applied
* -before- this matrix's existing transformation. That is, any vector that
* is multiplied by the resulting matrix will first be translated, then be
* transformed by the original transform.
*
* Calling this method will result in this matrix having the same value as
* the result of:
*
- * Matrix::Translation(x, y) * this
+ * BaseMatrix<T>::Translation(x, y) * this
*
* (Note that in performance critical code multiplying by the result of a
* Translation()/Scaling() call is not recommended since that results in a
* full matrix multiply involving 12 floating-point multiplications. Calling
* this method would be preferred since it only involves four floating-point
* multiplications.)
*/
- Matrix &PreTranslate(Float aX, Float aY)
+ BaseMatrix<T> &PreTranslate(T aX, T aY)
{
_31 += _11 * aX + _21 * aY;
_32 += _12 * aX + _22 * aY;
return *this;
}
- Matrix &PreTranslate(const Point &aPoint)
+ BaseMatrix<T> &PreTranslate(const Point &aPoint)
{
return PreTranslate(aPoint.x, aPoint.y);
}
/**
* Similar to PreTranslate, but the translation is applied -after- this
* matrix's existing transformation instead of before it.
*
* This method is generally less used than PreTranslate since typically code
* want to adjust an existing user space to device space matrix to create a
* transform to device space from a -new- user space (translated from the
* previous user space). In that case consumers will need to use the Pre*
* variants of the matrix methods rather than using the Post* methods, since
* the Post* methods add a transform to the device space end of the
* transformation.
*/
- Matrix &PostTranslate(Float aX, Float aY)
+ BaseMatrix<T> &PostTranslate(T aX, T aY)
{
_31 += aX;
_32 += aY;
return *this;
}
- Matrix &PostTranslate(const Point &aPoint)
+ BaseMatrix<T> &PostTranslate(const Point &aPoint)
{
return PostTranslate(aPoint.x, aPoint.y);
}
- static Matrix Scaling(Float aScaleX, Float aScaleY)
+ static BaseMatrix<T> Scaling(T aScaleX, T aScaleY)
{
- return Matrix(aScaleX, 0.0f, 0.0f, aScaleY, 0.0f, 0.0f);
+ return BaseMatrix<T>(aScaleX, 0.0f, 0.0f, aScaleY, 0.0f, 0.0f);
}
/**
* Similar to PreTranslate, but applies a scale instead of a translation.
*/
- Matrix &PreScale(Float aX, Float aY)
+ BaseMatrix<T> &PreScale(T aX, T aY)
{
_11 *= aX;
_12 *= aX;
_21 *= aY;
_22 *= aY;
return *this;
}
/**
* Similar to PostTranslate, but applies a scale instead of a translation.
*/
- Matrix &PostScale(Float aScaleX, Float aScaleY)
+ BaseMatrix<T> &PostScale(T aScaleX, T aScaleY)
{
_11 *= aScaleX;
_12 *= aScaleY;
_21 *= aScaleX;
_22 *= aScaleY;
_31 *= aScaleX;
_32 *= aScaleY;
return *this;
}
- GFX2D_API static Matrix Rotation(Float aAngle);
+ GFX2D_API static BaseMatrix<T> Rotation(T aAngle);
/**
* Similar to PreTranslate, but applies a rotation instead of a translation.
*/
- Matrix &PreRotate(Float aAngle)
+ BaseMatrix<T> &PreRotate(T aAngle)
{
- return *this = Matrix::Rotation(aAngle) * *this;
+ return *this = BaseMatrix<T>::Rotation(aAngle) * *this;
}
bool Invert()
{
// Compute co-factors.
- Float A = _22;
- Float B = -_21;
- Float C = _21 * _32 - _22 * _31;
- Float D = -_12;
- Float E = _11;
- Float F = _31 * _12 - _11 * _32;
+ T A = _22;
+ T B = -_21;
+ T C = _21 * _32 - _22 * _31;
+ T D = -_12;
+ T E = _11;
+ T F = _31 * _12 - _11 * _32;
- Float det = Determinant();
+ T det = Determinant();
if (!det) {
return false;
}
- Float inv_det = 1 / det;
+ T inv_det = 1 / det;
_11 = inv_det * A;
_12 = inv_det * D;
_21 = inv_det * B;
_22 = inv_det * E;
_31 = inv_det * C;
_32 = inv_det * F;
return true;
}
- Matrix Inverse() const
+ BaseMatrix<T> Inverse() const
{
- Matrix clone = *this;
+ BaseMatrix<T> clone = *this;
DebugOnly<bool> inverted = clone.Invert();
MOZ_ASSERT(inverted, "Attempted to get the inverse of a non-invertible matrix");
return clone;
}
- Float Determinant() const
+ T Determinant() const
{
return _11 * _22 - _12 * _21;
}
- Matrix operator*(const Matrix &aMatrix) const
+ BaseMatrix<T> operator*(const BaseMatrix<T> &aMatrix) const
{
- Matrix resultMatrix;
+ BaseMatrix<T> resultMatrix;
resultMatrix._11 = this->_11 * aMatrix._11 + this->_12 * aMatrix._21;
resultMatrix._12 = this->_11 * aMatrix._12 + this->_12 * aMatrix._22;
resultMatrix._21 = this->_21 * aMatrix._11 + this->_22 * aMatrix._21;
resultMatrix._22 = this->_21 * aMatrix._12 + this->_22 * aMatrix._22;
resultMatrix._31 = this->_31 * aMatrix._11 + this->_32 * aMatrix._21 + aMatrix._31;
resultMatrix._32 = this->_31 * aMatrix._12 + this->_32 * aMatrix._22 + aMatrix._32;
return resultMatrix;
}
- Matrix& operator*=(const Matrix &aMatrix)
+ BaseMatrix<T>& operator*=(const BaseMatrix<T> &aMatrix)
{
*this = *this * aMatrix;
return *this;
}
/**
* Multiplies in the opposite order to operator=*.
*/
- Matrix &PreMultiply(const Matrix &aMatrix)
+ BaseMatrix<T> &PreMultiply(const BaseMatrix<T> &aMatrix)
{
*this = aMatrix * *this;
return *this;
}
/* Returns true if the other matrix is fuzzy-equal to this matrix.
* Note that this isn't a cheap comparison!
*/
- bool operator==(const Matrix& other) const
+ bool operator==(const BaseMatrix<T>& other) const
{
return FuzzyEqual(_11, other._11) && FuzzyEqual(_12, other._12) &&
FuzzyEqual(_21, other._21) && FuzzyEqual(_22, other._22) &&
FuzzyEqual(_31, other._31) && FuzzyEqual(_32, other._32);
}
- bool operator!=(const Matrix& other) const
+ bool operator!=(const BaseMatrix<T>& other) const
{
return !(*this == other);
}
- bool ExactlyEquals(const Matrix& o) const
+ bool ExactlyEquals(const BaseMatrix<T>& o) const
{
return _11 == o._11 && _12 == o._12 &&
_21 == o._21 && _22 == o._22 &&
_31 == o._31 && _32 == o._32;
}
/* Verifies that the matrix contains no Infs or NaNs. */
bool IsFinite() const
@@ -299,18 +309,18 @@ public:
}
/**
* Returns true if the matrix is anything other than a straight
* translation by integers.
*/
bool HasNonIntegerTranslation() const {
return HasNonTranslation() ||
- !FuzzyEqual(_31, floor(_31 + Float(0.5))) ||
- !FuzzyEqual(_32, floor(_32 + Float(0.5)));
+ !FuzzyEqual(_31, floor(_31 + T(0.5))) ||
+ !FuzzyEqual(_32, floor(_32 + T(0.5)));
}
/**
* Returns true if the matrix only has an integer translation.
*/
bool HasOnlyIntegerTranslation() const {
return !HasNonIntegerTranslation();
}
@@ -342,29 +352,29 @@ public:
_21 == 0.0f && _22 == 1.0f &&
_31 == 0.0f && _32 == 0.0f;
}
/* Returns true if the matrix is singular.
*/
bool IsSingular() const
{
- Float det = Determinant();
+ T det = Determinant();
return !mozilla::IsFinite(det) || det == 0;
}
- GFX2D_API Matrix &NudgeToIntegers();
+ GFX2D_API BaseMatrix<T> &NudgeToIntegers();
bool IsTranslation() const
{
return FuzzyEqual(_11, 1.0f) && FuzzyEqual(_12, 0.0f) &&
FuzzyEqual(_21, 0.0f) && FuzzyEqual(_22, 1.0f);
}
- static bool FuzzyIsInteger(Float aValue)
+ static bool FuzzyIsInteger(T aValue)
{
return FuzzyEqual(aValue, floorf(aValue + 0.5f));
}
bool IsIntegerTranslation() const
{
return IsTranslation() && FuzzyIsInteger(_31) && FuzzyIsInteger(_32);
}
@@ -401,16 +411,18 @@ public:
/**
* Returns true if the matrix has negative scaling (i.e. flip).
*/
bool HasNegativeScaling() const {
return (_11 < 0.0) || (_22 < 0.0);
}
};
+typedef BaseMatrix<Float> Matrix;
+
// Helper functions used by Matrix4x4Typed defined in Matrix.cpp
double
SafeTangent(double aTheta);
double
FlushToZero(double aVal);
template<class Units, class F>
Point4DTyped<Units, F>
--- a/gfx/2d/MatrixFwd.h
+++ b/gfx/2d/MatrixFwd.h
@@ -3,21 +3,27 @@
* 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_GFX_MATRIX_FWD_H_
#define MOZILLA_GFX_MATRIX_FWD_H_
-// Forward declare enough things to define the typedef |Matrix4x4|.
+// Forward declare enough things to define the typedefs |Matrix| and |Matrix4x4|.
namespace mozilla {
namespace gfx {
+template<class T>
+class BaseMatrix;
+
+typedef float Float;
+typedef BaseMatrix<Float> Matrix;
+
struct UnknownUnits;
template<class SourceUnits, class TargetUnits>
class Matrix4x4Typed;
typedef Matrix4x4Typed<UnknownUnits, UnknownUnits> Matrix4x4;
} // namespace gfx
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -5,17 +5,17 @@
#ifndef MOZILLA_GFX_COMPOSITOR_H
#define MOZILLA_GFX_COMPOSITOR_H
#include "Units.h" // for ScreenPoint
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h" // for already_AddRefed, RefCounted
#include "mozilla/gfx/2D.h" // for DrawTarget
-#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
+#include "mozilla/gfx/MatrixFwd.h" // for Matrix, Matrix4x4
#include "mozilla/gfx/Point.h" // for IntSize, Point
#include "mozilla/gfx/Polygon.h" // for Polygon
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
#include "mozilla/gfx/Types.h" // for Float
#include "mozilla/gfx/Triangle.h" // for Triangle, TexturedTriangle
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "mozilla/layers/TextureSourceProvider.h"
@@ -109,17 +109,16 @@
* Depending on the type of data that needs to be serialized, you may need to
* add specific TextureClient implementations.
*/
class nsIWidget;
namespace mozilla {
namespace gfx {
-class Matrix;
class DrawTarget;
class DataSourceSurface;
} // namespace gfx
namespace layers {
struct Effect;
struct EffectChain;
--- a/gfx/layers/RotatedBuffer.h
+++ b/gfx/layers/RotatedBuffer.h
@@ -6,28 +6,25 @@
#ifndef ROTATEDBUFFER_H_
#define ROTATEDBUFFER_H_
#include "gfxTypes.h"
#include <stdint.h> // for uint32_t
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h" // for RefPtr, already_AddRefed
#include "mozilla/gfx/2D.h" // for DrawTarget, etc
+#include "mozilla/gfx/MatrixFwd.h" // for Matrix
#include "mozilla/mozalloc.h" // for operator delete
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsRegion.h" // for nsIntRegion
#include "LayersTypes.h"
namespace mozilla {
-namespace gfx {
-class Matrix;
-} // namespace gfx
-
namespace layers {
class TextureClient;
class PaintedLayer;
/**
* This is a cairo/Thebes surface, but with a literal twist. Scrolling
* causes the layer's visible region to move. We want to keep
--- a/layout/base/Units.h
+++ b/layout/base/Units.h
@@ -3,17 +3,16 @@
/* 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 MOZ_UNITS_H_
#define MOZ_UNITS_H_
#include "mozilla/gfx/Coord.h"
-#include "mozilla/gfx/Matrix.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/ScaleFactor.h"
#include "mozilla/gfx/ScaleFactors2D.h"
#include "nsMargin.h"
#include "nsRect.h"
#include "nsRegion.h"
#include "mozilla/AppUnits.h"
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -38,16 +38,17 @@
#include "nsLayoutUtils.h"
#include "nsQueryFrame.h"
#include "nsStringGlue.h"
#include "nsStyleContext.h"
#include "nsStyleStruct.h"
#include "Visibility.h"
#include "nsChangeHint.h"
#include "nsStyleContextInlines.h"
+#include "mozilla/gfx/MatrixFwd.h"
#ifdef ACCESSIBILITY
#include "mozilla/a11y/AccTypes.h"
#endif
/**
* New rules of reflow:
* 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
@@ -103,19 +104,16 @@ class ReflowOutput;
class ServoRestyleState;
class DisplayItemData;
class EffectSet;
namespace layers {
class Layer;
} // namespace layers
-namespace gfx {
-class Matrix;
-} // namespace gfx
} // namespace mozilla
/**
* Indication of how the frame can be split. This is used when doing runaround
* of floats, and when pulling up child frames from a next-in-flow.
*
* The choices are splittable, not splittable at all, and splittable in
* a non-rectangular fashion. This last type only applies to block-level
--- a/layout/svg/nsSVGDisplayableFrame.h
+++ b/layout/svg/nsSVGDisplayableFrame.h
@@ -3,34 +3,32 @@
* 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_ISVGCHILDFRAME_H__
#define __NS_ISVGCHILDFRAME_H__
#include "gfxRect.h"
#include "nsQueryFrame.h"
+#include "mozilla/gfx/MatrixFwd.h"
class gfxContext;
class gfxMatrix;
class nsIFrame;
class SVGBBox;
struct nsRect;
namespace mozilla {
class SVGAnimatedLengthList;
class SVGAnimatedNumberList;
class SVGLengthList;
class SVGNumberList;
class SVGUserUnitList;
-namespace gfx {
-class Matrix;
-} // namespace gfx
} // namespace mozilla
/**
* This class is used for elements that can be part of a directly displayable
* section of a document. This includes SVGGeometryFrame and nsSVGGframe.
* (Even though the latter doesn't display anything itself, if it contains
* SVGGeometryFrame descendants it is can still be part of a displayable
* section of a document) This class is not used for elements that can never