Bug 660216, part 2 - Allow PrependLocalTransformsTo callers to specify which transforms they want. r=heycam.

This commit is contained in:
Jonathan Watt 2012-02-17 08:12:47 +00:00
Родитель 643ca48cdf
Коммит 53393f795c
10 изменённых файлов: 108 добавлений и 22 удалений

Просмотреть файл

@ -1486,7 +1486,8 @@ nsSVGElement::GetCtx() const
}
/* virtual */ gfxMatrix
nsSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix) const
nsSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{
return aMatrix;
}

Просмотреть файл

@ -151,11 +151,36 @@ public:
// nsnull for outer <svg> or SVG without an <svg> parent (invalid SVG).
nsSVGSVGElement* GetCtx() const;
enum TransformTypes {
eAllTransforms
,eUserSpaceToParent
,eChildToUserSpace
};
/**
* Returns aMatrix post-multiplied by the transform from the userspace
* established by this element to the userspace established by its parent.
* Returns aMatrix pre-multiplied by (explicit or implicit) transforms that
* are introduced by attributes on this element.
*
* If aWhich is eAllTransforms, then all the transforms from the coordinate
* space established by this element for its children to the coordinate
* space established by this element's parent element for this element, are
* included.
*
* If aWhich is eUserSpaceToParent, then only the transforms from this
* element's userspace to the coordinate space established by its parent is
* included. This includes any transforms introduced by the 'transform'
* attribute, transform animations and animateMotion, but not any offsets
* due to e.g. 'x'/'y' attributes, or any transform due to a 'viewBox'
* attribute. (SVG userspace is defined to be the coordinate space in which
* coordinates on an element apply.)
*
* If aWhich is eChildToUserSpace, then only the transforms from the
* coordinate space established by this element for its childre to this
* elements userspace are included. This includes any offsets due to e.g.
* 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
* does not include any transforms due to the 'transform' attribute.
*/
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix) const;
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// Setter for to set the current <animateMotion> transformation
// Only visible for nsSVGGraphicElement, so it's a no-op here, and that

Просмотреть файл

@ -112,16 +112,28 @@ NS_IMETHODIMP nsSVGForeignObjectElement::GetHeight(nsIDOMSVGAnimatedLength * *aH
// nsSVGElement methods
/* virtual */ gfxMatrix
nsSVGForeignObjectElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix) const
nsSVGForeignObjectElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
// 'transform' attribute:
gfxMatrix matrix = nsSVGForeignObjectElementBase::PrependLocalTransformsTo(aMatrix);
// now translate by our 'x' and 'y':
gfxMatrix fromUserSpace =
nsSVGForeignObjectElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
if (aWhich == eUserSpaceToParent) {
return fromUserSpace;
}
// our 'x' and 'y' attributes:
float x, y;
const_cast<nsSVGForeignObjectElement*>(this)->
GetAnimatedLengthValues(&x, &y, nsnull);
return gfxMatrix().Translate(gfxPoint(x, y)) * matrix;
gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
if (aWhich == eChildToUserSpace) {
return toUserSpace;
}
NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
return toUserSpace * fromUserSpace;
}
//----------------------------------------------------------------------

Просмотреть файл

@ -69,7 +69,8 @@ public:
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGForeignObjectElementBase::)
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix) const;
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;

Просмотреть файл

@ -189,10 +189,25 @@ nsSVGGraphicElement::IsEventName(nsIAtom* aName)
}
gfxMatrix
nsSVGGraphicElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix) const
nsSVGGraphicElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
gfxMatrix result(aMatrix);
if (aWhich == eChildToUserSpace) {
// We don't have anything to prepend.
// eChildToUserSpace is not the common case, which is why we return
// 'result' to benefit from NRVO rather than returning aMatrix before
// creating 'result'.
return result;
}
NS_ABORT_IF_FALSE(aWhich == eAllTransforms || aWhich == eUserSpaceToParent,
"Unknown TransformTypes");
// animateMotion's resulting transform is supposed to apply *on top of*
// any transformations from the |transform| attribute. So since we're
// PRE-multiplying, we need to apply the animateMotion transform *first*.

Просмотреть файл

@ -62,7 +62,8 @@ public:
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix) const;
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix);
virtual mozilla::SVGAnimatedTransformList* GetAnimatedTransformList();

Просмотреть файл

@ -1180,12 +1180,29 @@ nsSVGSVGElement::GetLength(PRUint8 aCtxType)
// nsSVGElement methods
/* virtual */ gfxMatrix
nsSVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix) const
nsSVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
if (IsInner()) {
float x, y;
const_cast<nsSVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nsnull);
return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
if (aWhich == eAllTransforms) {
// the common case
return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
}
if (aWhich == eUserSpaceToParent) {
return gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
}
NS_ABORT_IF_FALSE(aWhich == eChildToUserSpace, "Unknown TransformTypes");
return GetViewBoxTransform(); // no need to multiply identity aMatrix
}
if (aWhich == eUserSpaceToParent) {
// only inner-<svg> has eUserSpaceToParent transforms
return aMatrix;
}
if (IsRoot()) {

Просмотреть файл

@ -186,8 +186,9 @@ public:
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix) const;
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// nsSVGSVGElement methods:
float GetLength(PRUint8 mCtxType);

Просмотреть файл

@ -488,15 +488,27 @@ nsSVGUseElement::UnlinkSource()
// nsSVGElement methods
/* virtual */ gfxMatrix
nsSVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix) const
nsSVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{
// 'transform' attribute:
gfxMatrix matrix = nsSVGUseElementBase::PrependLocalTransformsTo(aMatrix);
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
// now translate by our 'x' and 'y':
// 'transform' attribute:
gfxMatrix fromUserSpace =
nsSVGUseElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
if (aWhich == eUserSpaceToParent) {
return fromUserSpace;
}
// our 'x' and 'y' attributes:
float x, y;
const_cast<nsSVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nsnull);
return matrix.PreMultiply(gfxMatrix().Translate(gfxPoint(x, y)));
gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
if (aWhich == eChildToUserSpace) {
return toUserSpace;
}
NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
return toUserSpace * fromUserSpace;
}
nsSVGElement::LengthAttributesInfo

Просмотреть файл

@ -103,7 +103,8 @@ public:
void DestroyAnonymousContent();
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix) const;
virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// nsIContent interface
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;