зеркало из https://github.com/mozilla/gecko-dev.git
Bug 660216, part 2 - Allow PrependLocalTransformsTo callers to specify which transforms they want. r=heycam.
This commit is contained in:
Родитель
643ca48cdf
Коммит
53393f795c
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче