Bug 435356. Stop using nsIDOMSVGMatrix internally. r=longsonr
This commit is contained in:
Родитель
876fcce1ff
Коммит
c35c73bbc6
|
@ -932,8 +932,8 @@ nsSVGElement::GetOwnerSVGElement(nsIDOMSVGSVGElement * *aOwnerSVGElement)
|
|||
NS_IMETHODIMP
|
||||
nsSVGElement::GetViewportElement(nsIDOMSVGElement * *aViewportElement)
|
||||
{
|
||||
nsSVGUtils::GetNearestViewportElement(this, aViewportElement);
|
||||
return NS_OK; // we can't throw exceptions from this API.
|
||||
*aViewportElement = nsSVGUtils::GetNearestViewportElement(this).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "nsSVGLengthList.h"
|
||||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
|
@ -64,7 +65,6 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsSVGPreserveAspectRatio.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGFilterElement.h"
|
||||
#include "nsSVGString.h"
|
||||
|
||||
|
@ -5392,17 +5392,19 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance,
|
|||
imageContainer->GetWidth(&nativeWidth);
|
||||
imageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> trans;
|
||||
const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion;
|
||||
trans = nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
|
||||
0, 0, nativeWidth, nativeHeight,
|
||||
mPreserveAspectRatio);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> xy, fini;
|
||||
NS_NewSVGMatrix(getter_AddRefs(xy), 1, 0, 0, 1, filterSubregion.X(), filterSubregion.Y());
|
||||
xy->Multiply(trans, getter_AddRefs(fini));
|
||||
|
||||
gfxMatrix viewBoxTM =
|
||||
nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
|
||||
0,0, nativeWidth, nativeHeight,
|
||||
mPreserveAspectRatio);
|
||||
|
||||
gfxMatrix xyTM = gfxMatrix().Translate(gfxPoint(filterSubregion.X(), filterSubregion.Y()));
|
||||
|
||||
gfxMatrix TM = viewBoxTM * xyTM;
|
||||
|
||||
gfxContext ctx(aTarget->mImage);
|
||||
nsSVGUtils::CompositePatternMatrix(&ctx, thebesPattern, fini, nativeWidth, nativeHeight, 1.0);
|
||||
nsSVGUtils::CompositePatternMatrix(&ctx, thebesPattern, TM, nativeWidth, nativeHeight, 1.0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -117,25 +117,6 @@ nsSVGForeignObjectElement::PrependLocalTransformTo(const gfxMatrix &aMatrix)
|
|||
return gfxMatrix().Translate(gfxPoint(x, y)) * matrix;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGForeignObjectElement::AppendTransform(nsIDOMSVGMatrix *aCTM,
|
||||
nsIDOMSVGMatrix **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
// foreignObject is one of establishing-viewport elements.
|
||||
// so we are translated by foreignObject's x and y attribs.
|
||||
float x, y;
|
||||
GetAnimatedLengthValues(&x, &y, nsnull);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> translate;
|
||||
rv = NS_NewSVGMatrix(getter_AddRefs(translate), 1, 0, 0, 1, x, y);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
rv = aCTM->Multiply(translate, getter_AddRefs(tmp));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return nsSVGGraphicElement::AppendTransform(tmp, _retval);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
|
|
|
@ -74,9 +74,6 @@ public:
|
|||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
// public helpers
|
||||
nsresult AppendTransform(nsIDOMSVGMatrix *aCTM,
|
||||
nsIDOMSVGMatrix **_retval);
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
|
|
|
@ -75,14 +75,15 @@ nsSVGGraphicElement::nsSVGGraphicElement(nsINodeInfo *aNodeInfo)
|
|||
/* readonly attribute nsIDOMSVGElement nearestViewportElement; */
|
||||
NS_IMETHODIMP nsSVGGraphicElement::GetNearestViewportElement(nsIDOMSVGElement * *aNearestViewportElement)
|
||||
{
|
||||
nsSVGUtils::GetNearestViewportElement(this, aNearestViewportElement);
|
||||
return NS_OK; // we can't throw exceptions from this API.
|
||||
*aNearestViewportElement = nsSVGUtils::GetNearestViewportElement(this).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGElement farthestViewportElement; */
|
||||
NS_IMETHODIMP nsSVGGraphicElement::GetFarthestViewportElement(nsIDOMSVGElement * *aFarthestViewportElement)
|
||||
{
|
||||
return nsSVGUtils::GetFarthestViewportElement(this, aFarthestViewportElement);
|
||||
*aFarthestViewportElement = nsSVGUtils::GetFarthestViewportElement(this).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGRect getBBox (); */
|
||||
|
@ -102,41 +103,20 @@ NS_IMETHODIMP nsSVGGraphicElement::GetBBox(nsIDOMSVGRect **_retval)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* Helper for GetCTM and GetScreenCTM */
|
||||
nsresult
|
||||
nsSVGGraphicElement::AppendTransform(nsIDOMSVGMatrix *aCTM,
|
||||
nsIDOMSVGMatrix **_retval)
|
||||
{
|
||||
if (!mTransforms) {
|
||||
*_retval = aCTM;
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// append our local transformations
|
||||
nsCOMPtr<nsIDOMSVGTransformList> transforms;
|
||||
mTransforms->GetAnimVal(getter_AddRefs(transforms));
|
||||
NS_ENSURE_TRUE(transforms, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix =
|
||||
nsSVGTransformList::GetConsolidationMatrix(transforms);
|
||||
if (!matrix) {
|
||||
*_retval = aCTM;
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
return aCTM->Multiply(matrix, _retval); // addrefs, so we don't
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getCTM (); */
|
||||
NS_IMETHODIMP nsSVGGraphicElement::GetCTM(nsIDOMSVGMatrix * *aCTM)
|
||||
{
|
||||
return nsSVGUtils::GetCTM(this, aCTM);
|
||||
gfxMatrix m = nsSVGUtils::GetCTM(this, PR_FALSE);
|
||||
*aCTM = m.IsSingular() ? nsnull : NS_NewSVGMatrix(m).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getScreenCTM (); */
|
||||
NS_IMETHODIMP nsSVGGraphicElement::GetScreenCTM(nsIDOMSVGMatrix * *aCTM)
|
||||
{
|
||||
return nsSVGUtils::GetScreenCTM(this, aCTM);
|
||||
gfxMatrix m = nsSVGUtils::GetCTM(this, PR_TRUE);
|
||||
*aCTM = m.IsSingular() ? nsnull : NS_NewSVGMatrix(m).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getTransformToElement (in nsIDOMSVGElement element); */
|
||||
|
|
|
@ -64,9 +64,6 @@ public:
|
|||
|
||||
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix);
|
||||
|
||||
// public helpers
|
||||
virtual nsresult AppendTransform(nsIDOMSVGMatrix *aCTM,
|
||||
nsIDOMSVGMatrix **_retval);
|
||||
protected:
|
||||
// nsSVGElement overrides
|
||||
virtual PRBool IsEventName(nsIAtom* aName);
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGLength.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGValue.h"
|
||||
#include "nsTextFormatter.h"
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsDOMError.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGMarkerElement.h"
|
||||
#include "gfxMatrix.h"
|
||||
|
||||
nsSVGElement::LengthInfo nsSVGMarkerElement::sLengthInfo[4] =
|
||||
{
|
||||
|
@ -376,10 +377,9 @@ nsSVGMarkerElement::GetPreserveAspectRatio()
|
|||
//----------------------------------------------------------------------
|
||||
// public helpers
|
||||
|
||||
nsresult
|
||||
gfxMatrix
|
||||
nsSVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAngle,
|
||||
nsIDOMSVGMatrix **_retval)
|
||||
float aX, float aY, float aAngle)
|
||||
{
|
||||
float scale = 1.0;
|
||||
if (mEnumAttributes[MARKERUNITS].GetAnimValue() ==
|
||||
|
@ -390,22 +390,14 @@ nsSVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
|
|||
aAngle = mAngleAttributes[ORIENT].GetAnimValue();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix;
|
||||
NS_NewSVGMatrix(getter_AddRefs(matrix),
|
||||
cos(aAngle) * scale, sin(aAngle) * scale,
|
||||
-sin(aAngle) * scale, cos(aAngle) * scale,
|
||||
aX, aY);
|
||||
|
||||
*_retval = matrix;
|
||||
NS_IF_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
return gfxMatrix(cos(aAngle) * scale, sin(aAngle) * scale,
|
||||
-sin(aAngle) * scale, cos(aAngle) * scale,
|
||||
aX, aY);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGMarkerElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval)
|
||||
gfxMatrix
|
||||
nsSVGMarkerElement::GetViewBoxTransform()
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
if (!mViewBoxToViewportTransform) {
|
||||
float viewportWidth =
|
||||
mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx);
|
||||
|
@ -415,32 +407,27 @@ nsSVGMarkerElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval)
|
|||
const nsSVGViewBoxRect& viewbox = mViewBox.GetAnimValue();
|
||||
|
||||
if (viewbox.width <= 0.0f || viewbox.height <= 0.0f) {
|
||||
return NS_ERROR_FAILURE; // invalid - don't paint element
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // invalid - don't paint element
|
||||
}
|
||||
|
||||
float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
|
||||
float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> vb2vp =
|
||||
gfxMatrix viewBoxTM =
|
||||
nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
|
||||
viewbox.x, viewbox.y,
|
||||
viewbox.width, viewbox.height,
|
||||
mPreserveAspectRatio,
|
||||
PR_TRUE);
|
||||
NS_ENSURE_TRUE(vb2vp, NS_ERROR_OUT_OF_MEMORY);
|
||||
gfxPoint ref = nsSVGUtils::ConvertSVGMatrixToThebes(vb2vp).
|
||||
Transform(gfxPoint(refX, refY));
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> translate;
|
||||
NS_NewSVGMatrix(getter_AddRefs(translate),
|
||||
1.0f, 0.0f, 0.0f, 1.0f, -ref.x, -ref.y);
|
||||
NS_ENSURE_TRUE(translate, NS_ERROR_OUT_OF_MEMORY);
|
||||
translate->Multiply(vb2vp, getter_AddRefs(mViewBoxToViewportTransform));
|
||||
gfxPoint ref = viewBoxTM.Transform(gfxPoint(refX, refY));
|
||||
|
||||
gfxMatrix TM = viewBoxTM * gfxMatrix().Translate(gfxPoint(-ref.x, -ref.y));
|
||||
|
||||
mViewBoxToViewportTransform = NS_NewSVGMatrix(TM);
|
||||
}
|
||||
|
||||
*_retval = mViewBoxToViewportTransform;
|
||||
NS_IF_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
return nsSVGUtils::ConvertSVGMatrixToThebes(mViewBoxToViewportTransform);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -131,10 +131,9 @@ public:
|
|||
virtual void DidChangePreserveAspectRatio(PRBool aDoSetAttr);
|
||||
|
||||
// public helpers
|
||||
nsresult GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAngle,
|
||||
nsIDOMSVGMatrix **_retval);
|
||||
nsresult GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval);
|
||||
gfxMatrix GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAngle);
|
||||
gfxMatrix GetViewBoxTransform();
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ nsSVGPathElement::GetTotalLength(float *_retval)
|
|||
{
|
||||
*_retval = 0;
|
||||
|
||||
nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(nsnull);
|
||||
nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix());
|
||||
|
||||
if (!flat)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -118,7 +118,7 @@ nsSVGPathElement::GetPointAtLength(float distance, nsIDOMSVGPoint **_retval)
|
|||
{
|
||||
NS_ENSURE_FINITE(distance, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(nsnull);
|
||||
nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix());
|
||||
if (!flat)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -494,16 +494,12 @@ nsSVGPathElement::DidModifySVGObservable(nsISVGValue* observable,
|
|||
}
|
||||
|
||||
already_AddRefed<gfxFlattenedPath>
|
||||
nsSVGPathElement::GetFlattenedPath(nsIDOMSVGMatrix *aMatrix)
|
||||
nsSVGPathElement::GetFlattenedPath(const gfxMatrix &aMatrix)
|
||||
{
|
||||
gfxContext ctx(nsSVGUtils::GetThebesComputationalSurface());
|
||||
|
||||
if (aMatrix) {
|
||||
ctx.SetMatrix(nsSVGUtils::ConvertSVGMatrixToThebes(aMatrix));
|
||||
}
|
||||
|
||||
ctx.SetMatrix(aMatrix);
|
||||
mPathData.Playback(&ctx);
|
||||
|
||||
ctx.IdentityMatrix();
|
||||
|
||||
return ctx.GetFlattenedPath();
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
|
||||
virtual void ConstructPath(gfxContext *aCtx);
|
||||
|
||||
virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(nsIDOMSVGMatrix *aMatrix);
|
||||
virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix);
|
||||
|
||||
// nsIContent interface
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
|
|
@ -67,7 +67,7 @@ nsSVGPathGeometryElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
|
|||
}
|
||||
|
||||
already_AddRefed<gfxFlattenedPath>
|
||||
nsSVGPathGeometryElement::GetFlattenedPath(nsIDOMSVGMatrix *aMatrix)
|
||||
nsSVGPathGeometryElement::GetFlattenedPath(const gfxMatrix &aMatrix)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsTArray.h"
|
||||
#include "gfxPath.h"
|
||||
#include "gfxMatrix.h"
|
||||
|
||||
struct nsSVGMark {
|
||||
float x, y, angle;
|
||||
|
@ -47,7 +48,6 @@ struct nsSVGMark {
|
|||
x(aX), y(aY), angle(aAngle) {}
|
||||
};
|
||||
|
||||
class nsIDOMSVGMatrix;
|
||||
class gfxContext;
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGPathGeometryElementBase;
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
virtual PRBool IsMarkable();
|
||||
virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
|
||||
virtual void ConstructPath(gfxContext *aCtx) = 0;
|
||||
virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(nsIDOMSVGMatrix *aMatrix);
|
||||
virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "nsSVGAnimatedTransformList.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGPatternElement.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
|
|
|
@ -746,15 +746,16 @@ nsSVGSVGElement::GetPreserveAspectRatio(nsIDOMSVGAnimatedPreserveAspectRatio
|
|||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetNearestViewportElement(nsIDOMSVGElement * *aNearestViewportElement)
|
||||
{
|
||||
nsSVGUtils::GetNearestViewportElement(this, aNearestViewportElement);
|
||||
return NS_OK; // we can't throw exceptions from this API.
|
||||
*aNearestViewportElement = nsSVGUtils::GetNearestViewportElement(this).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGElement farthestViewportElement; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetFarthestViewportElement(nsIDOMSVGElement * *aFarthestViewportElement)
|
||||
{
|
||||
return nsSVGUtils::GetFarthestViewportElement(this, aFarthestViewportElement);
|
||||
*aFarthestViewportElement = nsSVGUtils::GetFarthestViewportElement(this).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGRect getBBox (); */
|
||||
|
@ -775,68 +776,22 @@ nsSVGSVGElement::GetBBox(nsIDOMSVGRect **_retval)
|
|||
return NS_ERROR_NOT_IMPLEMENTED; // XXX: outer svg
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGSVGElement::AppendTransform(nsIDOMSVGMatrix *aCTM,
|
||||
nsIDOMSVGMatrix **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// first check what are our parents and calculate offsets accordingly.
|
||||
|
||||
float s=1, x=0, y=0;
|
||||
nsIContent *ancestor = nsSVGUtils::GetParentElement(this);
|
||||
if (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
ancestor->Tag() == nsGkAtoms::foreignObject) {
|
||||
// this is a nested <svg> element. immediate parent is an <foreignObject> element.
|
||||
// we ignore this <svg> element's x and y attribs in layout so do the same.
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGElement> nearestViewportElement;
|
||||
rv = nsSVGUtils::GetNearestViewportElement(this, getter_AddRefs(nearestViewportElement));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!nearestViewportElement) {
|
||||
if (IsRoot()) {
|
||||
// we're the root element. get our currentScale and currentTranslate vals
|
||||
s = mCurrentScale;
|
||||
x = mCurrentTranslate.GetX();
|
||||
y = mCurrentTranslate.GetY();
|
||||
} else {
|
||||
// we're inline in some non-SVG content. get our offset from the root
|
||||
GetOffsetToAncestor(nsnull, x, y);
|
||||
}
|
||||
} else {
|
||||
// this is a nested <svg> element.
|
||||
GetAnimatedLengthValues(&x, &y, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> local;
|
||||
rv = NS_NewSVGMatrix(getter_AddRefs(local), s, 0, 0, s, x, y);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// finally append our viewbox transform
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> viewbox;
|
||||
rv = GetViewboxToViewportTransform(getter_AddRefs(viewbox));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
rv = local->Multiply(viewbox, getter_AddRefs(tmp)); // addrefs, so we don't
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return aCTM->Multiply(tmp, _retval); // addrefs, so we don't
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getCTM (); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetCTM(nsIDOMSVGMatrix * *aCTM)
|
||||
{
|
||||
return nsSVGUtils::GetCTM(this, aCTM);
|
||||
gfxMatrix m = nsSVGUtils::GetCTM(this, PR_FALSE);
|
||||
*aCTM = m.IsSingular() ? nsnull : NS_NewSVGMatrix(m).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getScreenCTM (); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetScreenCTM(nsIDOMSVGMatrix **aCTM)
|
||||
{
|
||||
return nsSVGUtils::GetScreenCTM(this, aCTM);
|
||||
gfxMatrix m = nsSVGUtils::GetCTM(this, PR_TRUE);
|
||||
*aCTM = m.IsSingular() ? nsnull : NS_NewSVGMatrix(m).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getTransformToElement (in nsIDOMSVGElement element); */
|
||||
|
@ -1027,43 +982,36 @@ nsSVGSVGElement::IsEventName(nsIAtom* aName)
|
|||
//----------------------------------------------------------------------
|
||||
// public helpers:
|
||||
|
||||
nsresult
|
||||
nsSVGSVGElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval)
|
||||
gfxMatrix
|
||||
nsSVGSVGElement::GetViewBoxTransform()
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
float viewportWidth, viewportHeight;
|
||||
nsSVGSVGElement *ctx = GetCtx();
|
||||
if (!ctx) {
|
||||
// outer svg
|
||||
viewportWidth = mViewportWidth;
|
||||
viewportHeight = mViewportHeight;
|
||||
} else {
|
||||
if (nsSVGUtils::IsInnerSVG(this)) {
|
||||
nsSVGSVGElement *ctx = GetCtx();
|
||||
viewportWidth = mLengthAttributes[WIDTH].GetAnimValue(ctx);
|
||||
viewportHeight = mLengthAttributes[HEIGHT].GetAnimValue(ctx);
|
||||
}
|
||||
|
||||
nsSVGViewBoxRect viewbox;
|
||||
if (mViewBox.IsValid()) {
|
||||
viewbox = mViewBox.GetAnimValue();
|
||||
} else {
|
||||
viewbox.x = viewbox.y = 0.0f;
|
||||
viewbox.width = viewportWidth;
|
||||
viewbox.height = viewportHeight;
|
||||
viewportWidth = mViewportWidth;
|
||||
viewportHeight = mViewportHeight;
|
||||
}
|
||||
|
||||
if (viewbox.width <= 0.0f || viewbox.height <= 0.0f) {
|
||||
return NS_ERROR_FAILURE; // invalid - don't paint element
|
||||
nsSVGViewBoxRect viewBox;
|
||||
if (mViewBox.IsValid()) {
|
||||
viewBox = mViewBox.GetAnimValue();
|
||||
} else {
|
||||
viewBox.x = viewBox.y = 0.0f;
|
||||
viewBox.width = viewportWidth;
|
||||
viewBox.height = viewportHeight;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> xform =
|
||||
nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
|
||||
viewbox.x, viewbox.y,
|
||||
viewbox.width, viewbox.height,
|
||||
mPreserveAspectRatio);
|
||||
xform.swap(*_retval);
|
||||
if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
|
||||
viewBox.x, viewBox.y,
|
||||
viewBox.width, viewBox.height,
|
||||
mPreserveAspectRatio);
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
|
@ -1124,43 +1072,6 @@ nsSVGSVGElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
|||
//----------------------------------------------------------------------
|
||||
// implementation helpers
|
||||
|
||||
// if an ancestor isn't specified, obtains offset from root frame
|
||||
void nsSVGSVGElement::GetOffsetToAncestor(nsIContent* ancestor,
|
||||
float &x, float &y)
|
||||
{
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
if (!document) return;
|
||||
|
||||
// Flush all pending notifications so that our frames are uptodate
|
||||
// Make sure to do this before we start grabbing layout objects like
|
||||
// presshells.
|
||||
document->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
nsIPresShell *presShell = document->GetPrimaryShell();
|
||||
if (!presShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPresContext *context = presShell->GetPresContext();
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
||||
nsIFrame* ancestorFrame = ancestor ?
|
||||
presShell->GetPrimaryFrameFor(ancestor) :
|
||||
presShell->GetRootFrame();
|
||||
|
||||
if (frame && ancestorFrame) {
|
||||
nsPoint point = frame->GetOffsetTo(ancestorFrame);
|
||||
x = nsPresContext::AppUnitsToFloatCSSPixels(point.x);
|
||||
y = nsPresContext::AppUnitsToFloatCSSPixels(point.y);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
PRBool
|
||||
nsSVGSVGElement::WillBeOutermostSVG(nsIContent* aParent,
|
||||
|
@ -1261,19 +1172,21 @@ nsSVGSVGElement::GetMMPerPx(PRUint8 aCtxType)
|
|||
/* virtual */ gfxMatrix
|
||||
nsSVGSVGElement::PrependLocalTransformTo(const gfxMatrix &aMatrix)
|
||||
{
|
||||
NS_ASSERTION(GetCtx(), "Should not be called on outer-<svg>");
|
||||
|
||||
float x, y;
|
||||
GetAnimatedLengthValues(&x, &y, nsnull);
|
||||
gfxMatrix matrix = aMatrix;
|
||||
matrix.PreMultiply(gfxMatrix().Translate(gfxPoint(x, y)));
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> viewBoxTM;
|
||||
nsresult res = GetViewboxToViewportTransform(getter_AddRefs(viewBoxTM));
|
||||
if (NS_FAILED(res)) {
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
|
||||
if (nsSVGUtils::IsInnerSVG(this)) {
|
||||
float x, y;
|
||||
GetAnimatedLengthValues(&x, &y, nsnull);
|
||||
return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
|
||||
}
|
||||
return matrix.PreMultiply(nsSVGUtils::ConvertSVGMatrixToThebes(viewBoxTM));
|
||||
|
||||
if (IsRoot()) {
|
||||
gfxMatrix zoomPanTM;
|
||||
zoomPanTM.Translate(gfxPoint(mCurrentTranslate.GetX(), mCurrentTranslate.GetY()));
|
||||
zoomPanTM.Scale(mCurrentScale, mCurrentScale);
|
||||
return GetViewBoxTransform() * zoomPanTM * aMatrix;
|
||||
}
|
||||
|
||||
// outer-<svg>, but inline in some other content:
|
||||
return GetViewBoxTransform() * aMatrix;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -199,9 +199,7 @@ public:
|
|||
float GetMMPerPx(PRUint8 mCtxType = 0);
|
||||
|
||||
// public helpers:
|
||||
nsresult GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval);
|
||||
nsresult AppendTransform(nsIDOMSVGMatrix *aCTM,
|
||||
nsIDOMSVGMatrix **_retval);
|
||||
gfxMatrix GetViewBoxTransform();
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
|
@ -226,7 +224,6 @@ protected:
|
|||
#endif // MOZ_SMIL
|
||||
|
||||
// implementation helpers:
|
||||
void GetOffsetToAncestor(nsIContent* ancestor, float &x, float &y);
|
||||
|
||||
PRBool IsRoot() {
|
||||
NS_ASSERTION((IsInDoc() && !GetParent()) ==
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
|
||||
class gfxContext;
|
||||
class nsPresContext;
|
||||
class nsIDOMSVGMatrix;
|
||||
class nsSVGRenderState;
|
||||
|
||||
class nsISVGChildFrame : public nsQueryFrame
|
||||
|
|
|
@ -56,7 +56,7 @@ NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
nsresult
|
||||
nsSVGClipPathFrame::ClipPaint(nsSVGRenderState* aContext,
|
||||
nsIFrame* aParent,
|
||||
nsIDOMSVGMatrix *aMatrix)
|
||||
const gfxMatrix &aMatrix)
|
||||
{
|
||||
// If the flag is set when we get here, it means this clipPath frame
|
||||
// has already been used painting the current clip, and the document
|
||||
|
@ -68,7 +68,7 @@ nsSVGClipPathFrame::ClipPaint(nsSVGRenderState* aContext,
|
|||
AutoClipPathReferencer clipRef(this);
|
||||
|
||||
mClipParent = aParent,
|
||||
mClipParentMatrix = aMatrix;
|
||||
mClipParentMatrix = NS_NewSVGMatrix(aMatrix);
|
||||
|
||||
PRBool isTrivial = IsTrivial();
|
||||
|
||||
|
@ -97,7 +97,7 @@ nsSVGClipPathFrame::ClipPaint(nsSVGRenderState* aContext,
|
|||
|
||||
PRBool
|
||||
nsSVGClipPathFrame::ClipHitTest(nsIFrame* aParent,
|
||||
nsIDOMSVGMatrix *aMatrix,
|
||||
const gfxMatrix &aMatrix,
|
||||
const nsPoint &aPoint)
|
||||
{
|
||||
// If the flag is set when we get here, it means this clipPath frame
|
||||
|
@ -110,7 +110,7 @@ nsSVGClipPathFrame::ClipHitTest(nsIFrame* aParent,
|
|||
AutoClipPathReferencer clipRef(this);
|
||||
|
||||
mClipParent = aParent,
|
||||
mClipParentMatrix = aMatrix;
|
||||
mClipParentMatrix = NS_NewSVGMatrix(aMatrix);
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
|
@ -169,18 +169,12 @@ nsSVGClipPathFrame::GetType() const
|
|||
gfxMatrix
|
||||
nsSVGClipPathFrame::GetCanvasTM()
|
||||
{
|
||||
NS_ASSERTION(mClipParentMatrix, "null parent matrix");
|
||||
|
||||
nsSVGClipPathElement *content = static_cast<nsSVGClipPathElement*>(mContent);
|
||||
|
||||
gfxMatrix tm = content->PrependLocalTransformTo(
|
||||
nsSVGUtils::ConvertSVGMatrixToThebes(mClipParentMatrix));
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> canvasTM = NS_NewSVGMatrix(tm);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> fini =
|
||||
nsSVGUtils::AdjustMatrixForUnits(canvasTM,
|
||||
return nsSVGUtils::AdjustMatrixForUnits(tm,
|
||||
&content->mEnumAttributes[nsSVGClipPathElement::CLIPPATHUNITS],
|
||||
mClipParent);
|
||||
|
||||
return nsSVGUtils::ConvertSVGMatrixToThebes(fini);
|
||||
}
|
||||
|
|
|
@ -56,10 +56,10 @@ public:
|
|||
// nsSVGClipPathFrame methods:
|
||||
nsresult ClipPaint(nsSVGRenderState* aContext,
|
||||
nsIFrame* aParent,
|
||||
nsIDOMSVGMatrix *aMatrix);
|
||||
const gfxMatrix &aMatrix);
|
||||
|
||||
PRBool ClipHitTest(nsIFrame* aParent,
|
||||
nsIDOMSVGMatrix *aMatrix,
|
||||
const gfxMatrix &aMatrix,
|
||||
const nsPoint &aPoint);
|
||||
|
||||
// Check if this clipPath is made up of more than one geometry object.
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsISVGChildFrame.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "nsSVGSVGElement.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxMatrix.h"
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
#include "nsSVGFilterFrame.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGOuterSVGFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
@ -141,8 +140,7 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> userToDeviceSpace =
|
||||
NS_NewSVGMatrix(nsSVGUtils::GetCanvasTM(aTarget));
|
||||
gfxMatrix userToDeviceSpace = nsSVGUtils::GetCanvasTM(aTarget);
|
||||
|
||||
// Calculate filterRes (the width and height of the pixel buffer of the
|
||||
// temporary offscreen surface that we'll paint into):
|
||||
|
@ -183,16 +181,14 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
|||
|
||||
// Convert the dirty rects to filter space, and create our nsSVGFilterInstance:
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> filterToUserSpace, filterToDeviceSpace;
|
||||
NS_NewSVGMatrix(getter_AddRefs(filterToUserSpace),
|
||||
filterRegion.Width() / filterRes.width, 0.0f,
|
||||
0.0f, filterRegion.Height() / filterRes.height,
|
||||
filterRegion.X(), filterRegion.Y());
|
||||
userToDeviceSpace->Multiply(filterToUserSpace, getter_AddRefs(filterToDeviceSpace));
|
||||
gfxMatrix filterToUserSpace(filterRegion.Width() / filterRes.width, 0.0f,
|
||||
0.0f, filterRegion.Height() / filterRes.height,
|
||||
filterRegion.X(), filterRegion.Y());
|
||||
gfxMatrix filterToDeviceSpace = filterToUserSpace * userToDeviceSpace;
|
||||
|
||||
// filterToDeviceSpace is always invertible
|
||||
gfxMatrix deviceToFilterSpace
|
||||
= nsSVGUtils::ConvertSVGMatrixToThebes(filterToDeviceSpace).Invert();
|
||||
gfxMatrix deviceToFilterSpace = filterToDeviceSpace;
|
||||
deviceToFilterSpace.Invert();
|
||||
|
||||
nsIntRect dirtyOutputRect =
|
||||
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aDirtyOutputRect);
|
||||
|
@ -234,8 +230,7 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
static nsresult
|
||||
TransformFilterSpaceToDeviceSpace(nsSVGFilterInstance *aInstance, nsIntRect *aRect)
|
||||
{
|
||||
gfxMatrix m = nsSVGUtils::ConvertSVGMatrixToThebes(
|
||||
aInstance->GetFilterSpaceToDeviceSpaceTransform());
|
||||
gfxMatrix m = aInstance->GetFilterSpaceToDeviceSpaceTransform();
|
||||
gfxRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
r = m.TransformBounds(r);
|
||||
r.RoundOut();
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "nsSVGFilterInstance.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsIDOMSVGUnitTypes.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "nsSVGFilterPaintCallback.h"
|
||||
#include "nsSVGFilterElement.h"
|
||||
|
@ -96,18 +95,14 @@ nsSVGFilterInstance::UserSpaceToFilterSpace(const gfxRect& aRect) const
|
|||
return r;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGMatrix>
|
||||
gfxMatrix
|
||||
nsSVGFilterInstance::GetUserSpaceToFilterSpaceTransform() const
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> filterTransform;
|
||||
gfxFloat widthScale = mFilterSpaceSize.width / mFilterRect.Width();
|
||||
gfxFloat heightScale = mFilterSpaceSize.height / mFilterRect.Height();
|
||||
NS_NewSVGMatrix(getter_AddRefs(filterTransform),
|
||||
widthScale, 0.0f,
|
||||
0.0f, heightScale,
|
||||
-mFilterRect.X() * widthScale,
|
||||
-mFilterRect.Y() * heightScale);
|
||||
return filterTransform.forget();
|
||||
return gfxMatrix(widthScale, 0.0f,
|
||||
0.0f, heightScale,
|
||||
-mFilterRect.X() * widthScale, -mFilterRect.Y() * heightScale);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -341,12 +336,7 @@ nsSVGFilterInstance::BuildSourceImages()
|
|||
offscreen->SetDeviceOffset(gfxPoint(-mSurfaceRect.x, -mSurfaceRect.y));
|
||||
|
||||
nsSVGRenderState tmpState(offscreen);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> userSpaceToFilterSpaceTransform
|
||||
= GetUserSpaceToFilterSpaceTransform();
|
||||
if (!userSpaceToFilterSpaceTransform)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
gfxMatrix userSpaceToFilterSpace =
|
||||
nsSVGUtils::ConvertSVGMatrixToThebes(userSpaceToFilterSpaceTransform);
|
||||
gfxMatrix userSpaceToFilterSpace = GetUserSpaceToFilterSpaceTransform();
|
||||
|
||||
gfxRect r(neededRect.x, neededRect.y, neededRect.width, neededRect.height);
|
||||
gfxMatrix m = userSpaceToFilterSpace;
|
||||
|
@ -369,8 +359,7 @@ nsSVGFilterInstance::BuildSourceImages()
|
|||
// space to device space and back again). However, that would make the
|
||||
// code more complex while being hard to get right without introducing
|
||||
// subtle bugs, and in practice it probably makes no real difference.)
|
||||
gfxMatrix deviceToFilterSpace =
|
||||
nsSVGUtils::ConvertSVGMatrixToThebes(GetFilterSpaceToDeviceSpaceTransform()).Invert();
|
||||
gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
|
||||
tmpState.GetGfxContext()->Multiply(deviceToFilterSpace);
|
||||
mPaintCallback->Paint(&tmpState, mTargetFrame, &dirty);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
const gfxRect &aTargetBBox,
|
||||
const gfxRect& aFilterRect,
|
||||
const nsIntSize& aFilterSpaceSize,
|
||||
nsIDOMSVGMatrix *aFilterSpaceToDeviceSpaceTransform,
|
||||
const gfxMatrix &aFilterSpaceToDeviceSpaceTransform,
|
||||
const nsIntRect& aDirtyOutputRect,
|
||||
const nsIntRect& aDirtyInputRect,
|
||||
PRUint16 aPrimitiveUnits) :
|
||||
|
@ -107,9 +107,9 @@ public:
|
|||
nsresult ComputeSourceNeededRect(nsIntRect* aDirty);
|
||||
nsresult ComputeOutputBBox(nsIntRect* aBBox);
|
||||
|
||||
already_AddRefed<nsIDOMSVGMatrix> GetUserSpaceToFilterSpaceTransform() const;
|
||||
nsIDOMSVGMatrix* GetFilterSpaceToDeviceSpaceTransform() const {
|
||||
return mFilterSpaceToDeviceSpaceTransform.get();
|
||||
gfxMatrix GetUserSpaceToFilterSpaceTransform() const;
|
||||
gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
|
||||
return mFilterSpaceToDeviceSpaceTransform;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -185,7 +185,7 @@ private:
|
|||
nsSVGFilterPaintCallback* mPaintCallback;
|
||||
nsSVGFilterElement* mFilterElement;
|
||||
gfxRect mTargetBBox;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mFilterSpaceToDeviceSpaceTransform;
|
||||
gfxMatrix mFilterSpaceToDeviceSpaceTransform;
|
||||
gfxRect mFilterRect;
|
||||
nsIntSize mFilterSpaceSize;
|
||||
nsIntRect mDirtyOutputRect;
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsStubImageDecoderObserver.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
|
@ -43,8 +42,8 @@
|
|||
#include "nsLayoutUtils.h"
|
||||
#include "nsSVGImageElement.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
class nsSVGImageFrame;
|
||||
|
@ -111,7 +110,7 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
already_AddRefed<nsIDOMSVGMatrix> GetImageTransform();
|
||||
gfxMatrix GetImageTransform();
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mListener;
|
||||
|
||||
|
@ -186,11 +185,9 @@ nsSVGImageFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGMatrix>
|
||||
gfxMatrix
|
||||
nsSVGImageFrame::GetImageTransform()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> ctm = NS_NewSVGMatrix(GetCanvasTM());
|
||||
|
||||
float x, y, width, height;
|
||||
nsSVGImageElement *element = static_cast<nsSVGImageElement*>(mContent);
|
||||
element->GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
|
||||
|
@ -199,17 +196,12 @@ nsSVGImageFrame::GetImageTransform()
|
|||
mImageContainer->GetWidth(&nativeWidth);
|
||||
mImageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> trans, ctmXY, fini;
|
||||
trans = nsSVGUtils::GetViewBoxTransform(width, height,
|
||||
0, 0,
|
||||
nativeWidth, nativeHeight,
|
||||
element->mPreserveAspectRatio);
|
||||
ctm->Translate(x, y, getter_AddRefs(ctmXY));
|
||||
ctmXY->Multiply(trans, getter_AddRefs(fini));
|
||||
gfxMatrix viewBoxTM =
|
||||
nsSVGUtils::GetViewBoxTransform(width, height,
|
||||
0, 0, nativeWidth, nativeHeight,
|
||||
element->mPreserveAspectRatio);
|
||||
|
||||
nsIDOMSVGMatrix *retval = nsnull;
|
||||
fini.swap(retval);
|
||||
return retval;
|
||||
return viewBoxTM * gfxMatrix().Translate(gfxPoint(x, y)) * GetCanvasTM();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -264,8 +256,6 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
|
|||
nsSVGUtils::SetClipRect(gfx, GetCanvasTM(), clipRect);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> fini = GetImageTransform();
|
||||
|
||||
// fill-opacity doesn't affect <image>, so if we're allowed to
|
||||
// optimize group opacity, the opacity used for compositing the
|
||||
// image into the current canvas is just the group opacity.
|
||||
|
@ -278,7 +268,8 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
|
|||
mImageContainer->GetWidth(&nativeWidth);
|
||||
mImageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, fini, nativeWidth, nativeHeight, opacity);
|
||||
nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, GetImageTransform(),
|
||||
nativeWidth, nativeHeight, opacity);
|
||||
|
||||
if (GetStyleDisplay()->IsScrollableOverflow())
|
||||
gfx->Restore();
|
||||
|
@ -295,9 +286,7 @@ nsSVGImageFrame::GetFrameForPoint(const nsPoint &aPoint)
|
|||
mImageContainer->GetWidth(&nativeWidth);
|
||||
mImageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> fini = GetImageTransform();
|
||||
|
||||
if (!nsSVGUtils::HitTestRect(fini,
|
||||
if (!nsSVGUtils::HitTestRect(GetImageTransform(),
|
||||
0, 0, nativeWidth, nativeHeight,
|
||||
PresContext()->AppUnitsToDevPixels(aPoint.x),
|
||||
PresContext()->AppUnitsToDevPixels(aPoint.y))) {
|
||||
|
|
|
@ -159,17 +159,13 @@ NS_IMETHODIMP_(nsIFrame*)
|
|||
nsSVGInnerSVGFrame::GetFrameForPoint(const nsPoint &aPoint)
|
||||
{
|
||||
if (GetStyleDisplay()->IsScrollableOverflow()) {
|
||||
nsSVGElement *content = static_cast<nsSVGElement*>(mContent);
|
||||
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent);
|
||||
|
||||
float clipX, clipY, clipWidth, clipHeight;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> clipTransform;
|
||||
content->GetAnimatedLengthValues(&clipX, &clipY, &clipWidth, &clipHeight, nsnull);
|
||||
|
||||
nsSVGElement *svg = static_cast<nsSVGElement*>(mContent);
|
||||
svg->GetAnimatedLengthValues(&clipX, &clipY, &clipWidth, &clipHeight, nsnull);
|
||||
|
||||
nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>
|
||||
(mParent);
|
||||
clipTransform = NS_NewSVGMatrix(parent->GetCanvasTM());
|
||||
|
||||
if (!nsSVGUtils::HitTestRect(clipTransform,
|
||||
if (!nsSVGUtils::HitTestRect(parent->GetCanvasTM(),
|
||||
clipX, clipY, clipWidth, clipHeight,
|
||||
PresContext()->AppUnitsToDevPixels(aPoint.x),
|
||||
PresContext()->AppUnitsToDevPixels(aPoint.y))) {
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "nsRegion.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGFilterPaintCallback.h"
|
||||
#include "nsSVGFilterFrame.h"
|
||||
#include "nsSVGClipPathFrame.h"
|
||||
|
@ -284,7 +283,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsIRenderingContext* aCtx,
|
|||
userSpaceRect = userSpaceRect.ToNearestPixels(appUnitsPerDevPixel).ToAppUnits(appUnitsPerDevPixel);
|
||||
aCtx->Translate(userSpaceRect.x, userSpaceRect.y);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix = GetInitialMatrix(aEffectsFrame);
|
||||
gfxMatrix matrix = GetInitialMatrix(aEffectsFrame);
|
||||
|
||||
PRBool complexEffects = PR_FALSE;
|
||||
/* Check if we need to do additional operations on this child's
|
||||
|
@ -359,19 +358,18 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsIRenderingContext* aCtx,
|
|||
gfx->SetMatrix(savedCTM);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGMatrix>
|
||||
gfxMatrix
|
||||
nsSVGIntegrationUtils::GetInitialMatrix(nsIFrame* aNonSVGFrame)
|
||||
{
|
||||
NS_ASSERTION(!aNonSVGFrame->IsFrameOfType(nsIFrame::eSVG),
|
||||
"SVG frames should not get here");
|
||||
PRInt32 appUnitsPerDevPixel = aNonSVGFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix;
|
||||
float devPxPerCSSPx =
|
||||
1 / nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPixel);
|
||||
NS_NewSVGMatrix(getter_AddRefs(matrix),
|
||||
devPxPerCSSPx, 0.0f,
|
||||
0.0f, devPxPerCSSPx);
|
||||
return matrix.forget();
|
||||
|
||||
return gfxMatrix(devPxPerCSSPx, 0.0,
|
||||
0.0, devPxPerCSSPx,
|
||||
0.0, 0.0);
|
||||
}
|
||||
|
||||
gfxRect
|
||||
|
|
|
@ -41,12 +41,12 @@
|
|||
#include "nsPoint.h"
|
||||
#include "nsRect.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxMatrix.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsDisplayListBuilder;
|
||||
class nsDisplayList;
|
||||
class nsIRenderingContext;
|
||||
class nsIDOMSVGMatrix;
|
||||
|
||||
/***** Integration of SVG effects with regular frame painting *****/
|
||||
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aInnerList);
|
||||
|
||||
static already_AddRefed<nsIDOMSVGMatrix>
|
||||
static gfxMatrix
|
||||
GetInitialMatrix(nsIFrame* aNonSVGFrame);
|
||||
/**
|
||||
* Returns aNonSVGFrame's rect in CSS pixel units. This is the union
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsSVGMarkerFrame.h"
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "nsSVGMarkerElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
|
@ -113,18 +112,10 @@ nsSVGMarkerFrame::GetCanvasTM()
|
|||
gfxMatrix markedTM = mMarkedFrame->GetCanvasTM();
|
||||
mInUse2 = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> markerTM;
|
||||
content->GetMarkerTransform(mStrokeWidth, mX, mY, mAngle, getter_AddRefs(markerTM));
|
||||
gfxMatrix markerTM = content->GetMarkerTransform(mStrokeWidth, mX, mY, mAngle);
|
||||
gfxMatrix viewBoxTM = content->GetViewBoxTransform();
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> viewBoxTM;
|
||||
nsresult res = content->GetViewboxToViewportTransform(getter_AddRefs(viewBoxTM));
|
||||
if (NS_FAILED(res)) {
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
|
||||
}
|
||||
|
||||
markedTM.PreMultiply(nsSVGUtils::ConvertSVGMatrixToThebes(markerTM));
|
||||
markedTM.PreMultiply(nsSVGUtils::ConvertSVGMatrixToThebes(viewBoxTM));
|
||||
return markedTM;
|
||||
return viewBoxTM * markerTM * markedTM;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
@ -54,7 +55,7 @@ NS_NewSVGMaskFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
already_AddRefed<gfxPattern>
|
||||
nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
||||
nsIFrame* aParent,
|
||||
nsIDOMSVGMatrix* aMatrix,
|
||||
const gfxMatrix &aMatrix,
|
||||
float aOpacity)
|
||||
{
|
||||
// If the flag is set when we get here, it means this mask frame
|
||||
|
@ -84,11 +85,11 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
|||
&mask->mLengthAttributes[nsSVGMaskElement::X], bbox, aParent);
|
||||
|
||||
gfx->Save();
|
||||
nsSVGUtils::SetClipRect(gfx, nsSVGUtils::ConvertSVGMatrixToThebes(aMatrix), maskArea);
|
||||
nsSVGUtils::SetClipRect(gfx, aMatrix, maskArea);
|
||||
}
|
||||
|
||||
mMaskParent = aParent;
|
||||
mMaskParentMatrix = aMatrix;
|
||||
mMaskParentMatrix = NS_NewSVGMatrix(aMatrix);
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
|
@ -185,11 +186,8 @@ nsSVGMaskFrame::GetCanvasTM()
|
|||
|
||||
nsSVGMaskElement *mask = static_cast<nsSVGMaskElement*>(mContent);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix =
|
||||
nsSVGUtils::AdjustMatrixForUnits(mMaskParentMatrix,
|
||||
return nsSVGUtils::AdjustMatrixForUnits(nsSVGUtils::ConvertSVGMatrixToThebes(mMaskParentMatrix),
|
||||
&mask->mEnumAttributes[nsSVGMaskElement::MASKCONTENTUNITS],
|
||||
mMaskParent);
|
||||
|
||||
return nsSVGUtils::ConvertSVGMatrixToThebes(matrix);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
// nsSVGMaskFrame method:
|
||||
already_AddRefed<gfxPattern> ComputeMaskAlpha(nsSVGRenderState *aContext,
|
||||
nsIFrame* aParent,
|
||||
nsIDOMSVGMatrix* aMatrix,
|
||||
const gfxMatrix &aMatrix,
|
||||
float aOpacity = 1.0f);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -741,41 +741,23 @@ gfxMatrix
|
|||
nsSVGOuterSVGFrame::GetCanvasTM()
|
||||
{
|
||||
if (!mCanvasTM) {
|
||||
nsSVGSVGElement *svgElement = static_cast<nsSVGSVGElement*>(mContent);
|
||||
nsSVGSVGElement *content = static_cast<nsSVGSVGElement*>(mContent);
|
||||
|
||||
float devPxPerCSSPx =
|
||||
1 / PresContext()->AppUnitsToFloatCSSPixels(
|
||||
1.0f / PresContext()->AppUnitsToFloatCSSPixels(
|
||||
PresContext()->AppUnitsPerDevPixel());
|
||||
nsCOMPtr<nsIDOMSVGMatrix> devPxToCSSPxMatrix;
|
||||
NS_NewSVGMatrix(getter_AddRefs(devPxToCSSPxMatrix),
|
||||
devPxPerCSSPx, 0.0f,
|
||||
0.0f, devPxPerCSSPx);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> viewBoxTM;
|
||||
nsresult res =
|
||||
svgElement->GetViewboxToViewportTransform(getter_AddRefs(viewBoxTM));
|
||||
if (NS_SUCCEEDED(res) && viewBoxTM) {
|
||||
// PRE-multiply px conversion!
|
||||
devPxToCSSPxMatrix->Multiply(viewBoxTM, getter_AddRefs(mCanvasTM));
|
||||
} else {
|
||||
NS_WARNING("We should propagate the fact that the viewBox is invalid.");
|
||||
mCanvasTM = devPxToCSSPxMatrix;
|
||||
}
|
||||
gfxMatrix viewBoxTM = content->GetViewBoxTransform();
|
||||
|
||||
// our content is the document element so we must premultiply the values
|
||||
// of its currentScale and currentTranslate properties
|
||||
gfxMatrix zoomPanTM;
|
||||
if (mIsRootContent) {
|
||||
nsCOMPtr<nsIDOMSVGMatrix> zoomPanMatrix;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> temp;
|
||||
float scale = svgElement->GetCurrentScale();
|
||||
const nsSVGTranslatePoint& translate = svgElement->GetCurrentTranslate();
|
||||
|
||||
svgElement->CreateSVGMatrix(getter_AddRefs(zoomPanMatrix));
|
||||
zoomPanMatrix->Translate(translate.GetX(), translate.GetY(), getter_AddRefs(temp));
|
||||
temp->Scale(scale, getter_AddRefs(zoomPanMatrix));
|
||||
zoomPanMatrix->Multiply(mCanvasTM, getter_AddRefs(temp));
|
||||
temp.swap(mCanvasTM);
|
||||
const nsSVGTranslatePoint& translate = content->GetCurrentTranslate();
|
||||
zoomPanTM.Translate(gfxPoint(translate.GetX(), translate.GetY()));
|
||||
zoomPanTM.Scale(content->GetCurrentScale(), content->GetCurrentScale());
|
||||
}
|
||||
|
||||
gfxMatrix TM = viewBoxTM * zoomPanTM * gfxMatrix().Scale(devPxPerCSSPx, devPxPerCSSPx);
|
||||
mCanvasTM = NS_NewSVGMatrix(TM);
|
||||
}
|
||||
return nsSVGUtils::ConvertSVGMatrixToThebes(mCanvasTM);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGMarkerFrame.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "nsSVGGraphicElement.h"
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "gfxMatrix.h"
|
||||
|
||||
class nsPresContext;
|
||||
class nsIDOMSVGMatrix;
|
||||
class nsSVGMarkerFrame;
|
||||
class nsSVGMarkerProperty;
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "gfxContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "gfxMatrix.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -197,16 +198,19 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
|||
// the geometry that is being rendered with a pattern
|
||||
nsSVGElement *callerContent;
|
||||
gfxRect callerBBox;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> callerCTM;
|
||||
if (NS_FAILED(GetTargetGeometry(getter_AddRefs(callerCTM),
|
||||
gfxMatrix callerCTM;
|
||||
if (NS_FAILED(GetTargetGeometry(&callerCTM,
|
||||
&callerBBox,
|
||||
&callerContent, aSource)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Construct the CTM that we will provide to our children when we
|
||||
// render them into the tile.
|
||||
if (NS_FAILED(ConstructCTM(getter_AddRefs(mCTM), callerBBox, callerCTM)))
|
||||
gfxMatrix ctm = ConstructCTM(callerBBox, callerCTM);
|
||||
if (ctm.IsSingular()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mCTM = NS_NewSVGMatrix(ctm);
|
||||
|
||||
// Get the bounding box of the pattern. This will be used to determine
|
||||
// the size of the surface, and will also be used to define the bounding
|
||||
|
@ -474,7 +478,7 @@ nsSVGPatternFrame::GetPatternWithAttr(nsIAtom *aAttrName, nsIContent *aDefault)
|
|||
|
||||
gfxRect
|
||||
nsSVGPatternFrame::GetPatternRect(const gfxRect &aTargetBBox,
|
||||
nsIDOMSVGMatrix *aTargetCTM,
|
||||
const gfxMatrix &aTargetCTM,
|
||||
nsSVGElement *aTarget)
|
||||
{
|
||||
// Get our type
|
||||
|
@ -512,52 +516,42 @@ GetLengthValue(const nsSVGLength2 *aLength)
|
|||
return aLength->GetAnimValue(static_cast<nsSVGSVGElement*>(nsnull));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGPatternFrame::ConstructCTM(nsIDOMSVGMatrix **aCTM,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM)
|
||||
gfxMatrix
|
||||
nsSVGPatternFrame::ConstructCTM(const gfxRect &callerBBox,
|
||||
const gfxMatrix &callerCTM)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tCTM, tempTM;
|
||||
gfxMatrix tCTM;
|
||||
|
||||
// Begin by handling the objectBoundingBox conversion since
|
||||
// this must be handled in the CTM
|
||||
PRUint16 type = GetPatternContentUnits();
|
||||
|
||||
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
NS_NewSVGMatrix(getter_AddRefs(tCTM), callerBBox.Width(), 0.0f, 0.0f,
|
||||
callerBBox.Height(), 0.0f, 0.0f);
|
||||
// The objectBoundingBox conversion must be handled in the CTM:
|
||||
if (GetPatternContentUnits() ==
|
||||
nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
tCTM.Scale(callerBBox.Width(), callerBBox.Height());
|
||||
} else {
|
||||
float scale = nsSVGUtils::MaxExpansion(callerCTM);
|
||||
NS_NewSVGMatrix(getter_AddRefs(tCTM), scale, 0, 0, scale, 0, 0);
|
||||
tCTM.Scale(scale, scale);
|
||||
}
|
||||
|
||||
gfxMatrix viewBoxTM;
|
||||
const nsSVGViewBoxRect viewBox = GetViewBox().GetAnimValue();
|
||||
|
||||
if (viewBox.height > 0.0f && viewBox.width > 0.0f) {
|
||||
|
||||
float viewportWidth = GetLengthValue(GetWidth());
|
||||
float viewportHeight = GetLengthValue(GetHeight());
|
||||
float refX = GetLengthValue(GetX());
|
||||
float refY = GetLengthValue(GetY());
|
||||
|
||||
tempTM = nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
|
||||
viewBox.x + refX, viewBox.y + refY,
|
||||
viewBox.width, viewBox.height,
|
||||
GetPreserveAspectRatio(),
|
||||
PR_TRUE);
|
||||
|
||||
} else {
|
||||
// No viewBox, construct from the (modified) parent matrix
|
||||
NS_NewSVGMatrix(getter_AddRefs(tempTM));
|
||||
viewBoxTM = nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
|
||||
viewBox.x + refX, viewBox.y + refY,
|
||||
viewBox.width, viewBox.height,
|
||||
GetPreserveAspectRatio(),
|
||||
PR_TRUE);
|
||||
}
|
||||
tCTM->Multiply(tempTM, aCTM);
|
||||
return NS_OK;
|
||||
return viewBoxTM * tCTM;
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
nsSVGPatternFrame::GetPatternMatrix(const gfxRect &bbox,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM)
|
||||
const gfxMatrix &callerCTM)
|
||||
{
|
||||
// Get the pattern transform
|
||||
gfxMatrix patternTransform = GetPatternTransform();
|
||||
|
@ -580,12 +574,11 @@ nsSVGPatternFrame::GetPatternMatrix(const gfxRect &bbox,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsSVGPatternFrame::GetTargetGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
nsSVGPatternFrame::GetTargetGeometry(gfxMatrix *aCTM,
|
||||
gfxRect *aBBox,
|
||||
nsSVGElement **aTargetContent,
|
||||
nsSVGGeometryFrame *aTarget)
|
||||
{
|
||||
*aCTM = nsnull;
|
||||
*aTargetContent = nsnull;
|
||||
|
||||
// Make sure the callerContent is an SVG element. If we are attempting
|
||||
|
@ -618,7 +611,7 @@ nsSVGPatternFrame::GetTargetGeometry(nsIDOMSVGMatrix **aCTM,
|
|||
}
|
||||
|
||||
// Get the transformation matrix from our calling geometry
|
||||
*aCTM = NS_NewSVGMatrix(aTarget->GetCanvasTM()).get();
|
||||
*aCTM = aTarget->GetCanvasTM();
|
||||
|
||||
// OK, now fix up the bounding box to reflect user coordinates
|
||||
// We handle device unit scaling in pattern matrix
|
||||
|
|
|
@ -129,15 +129,14 @@ protected:
|
|||
|
||||
NS_IMETHOD GetPatternFirstChild(nsIFrame **kid);
|
||||
gfxRect GetPatternRect(const gfxRect &bbox,
|
||||
nsIDOMSVGMatrix *callerCTM,
|
||||
const gfxMatrix &callerCTM,
|
||||
nsSVGElement *content);
|
||||
gfxMatrix GetPatternMatrix(const gfxRect &bbox,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM);
|
||||
nsresult ConstructCTM(nsIDOMSVGMatrix **ctm,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM);
|
||||
nsresult GetTargetGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
const gfxMatrix &callerCTM);
|
||||
gfxMatrix ConstructCTM(const gfxRect &callerBBox,
|
||||
const gfxMatrix &callerCTM);
|
||||
nsresult GetTargetGeometry(gfxMatrix *aCTM,
|
||||
gfxRect *aBBox,
|
||||
nsSVGElement **aTargetContent,
|
||||
nsSVGGeometryFrame *aTarget);
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGTextFrame.h"
|
||||
#include "nsSVGOuterSVGFrame.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "nsSVGContainerFrame.h"
|
||||
#include "nsSVGTextFrame.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGOuterSVGFrame.h"
|
||||
#include "nsIDOMSVGTextElement.h"
|
||||
#include "nsIDOMSVGAnimatedLengthList.h"
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGTextPathElement.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
@ -153,13 +152,11 @@ already_AddRefed<gfxFlattenedPath>
|
|||
nsSVGTextPathFrame::GetFlattenedPath(nsIFrame *path)
|
||||
{
|
||||
NS_PRECONDITION(path, "Unexpected null path");
|
||||
nsSVGPathGeometryElement *element = static_cast<nsSVGPathGeometryElement*>
|
||||
(path->GetContent());
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> localTM =
|
||||
NS_NewSVGMatrix(element->PrependLocalTransformTo(gfxMatrix()));
|
||||
nsSVGPathGeometryElement *element =
|
||||
static_cast<nsSVGPathGeometryElement*>(path->GetContent());
|
||||
|
||||
return element->GetFlattenedPath(localTM);
|
||||
return element->GetFlattenedPath(element->PrependLocalTransformTo(gfxMatrix()));
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
#include "nsSVGGFrame.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsIDOMSVGUseElement.h"
|
||||
#include "nsIDOMSVGTransformable.h"
|
||||
#include "nsSVGElement.h"
|
||||
|
|
|
@ -436,124 +436,111 @@ nsSVGUtils::CoordToFloat(nsPresContext *aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGUtils::GetNearestViewportElement(nsIContent *aContent,
|
||||
nsIDOMSVGElement * *aNearestViewportElement)
|
||||
PRBool
|
||||
nsSVGUtils::EstablishesViewport(nsIContent *aContent)
|
||||
{
|
||||
*aNearestViewportElement = nsnull;
|
||||
return aContent && aContent->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
(aContent->Tag() == nsGkAtoms::svg ||
|
||||
aContent->Tag() == nsGkAtoms::image ||
|
||||
aContent->Tag() == nsGkAtoms::foreignObject ||
|
||||
aContent->Tag() == nsGkAtoms::symbol);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGElement>
|
||||
nsSVGUtils::GetNearestViewportElement(nsIContent *aContent)
|
||||
{
|
||||
nsIContent *element = GetParentElement(aContent);
|
||||
|
||||
while (element && element->GetNameSpaceID() == kNameSpaceID_SVG) {
|
||||
if (EstablishesViewport(element)) {
|
||||
if (element->Tag() == nsGkAtoms::foreignObject) {
|
||||
return nsnull;
|
||||
}
|
||||
return nsCOMPtr<nsIDOMSVGElement>(do_QueryInterface(element)).forget();
|
||||
}
|
||||
element = GetParentElement(element);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGElement>
|
||||
nsSVGUtils::GetFarthestViewportElement(nsIContent *aContent)
|
||||
{
|
||||
nsIContent *element = nsnull;
|
||||
nsIContent *ancestor = GetParentElement(aContent);
|
||||
|
||||
while (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
ancestor->Tag() != nsGkAtoms::foreignObject) {
|
||||
|
||||
nsCOMPtr<nsIDOMSVGFitToViewBox> fitToViewBox = do_QueryInterface(ancestor);
|
||||
|
||||
if (fitToViewBox) {
|
||||
// right interface
|
||||
nsCOMPtr<nsIDOMSVGElement> element = do_QueryInterface(ancestor);
|
||||
element.swap(*aNearestViewportElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ancestor = GetParentElement(ancestor);
|
||||
ancestor->Tag() != nsGkAtoms::foreignObject) {
|
||||
element = ancestor;
|
||||
ancestor = GetParentElement(element);
|
||||
}
|
||||
if (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
ancestor->Tag() == nsGkAtoms::foreignObject )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
if (element && element->Tag() == nsGkAtoms::svg) {
|
||||
return nsCOMPtr<nsIDOMSVGElement>(do_QueryInterface(element)).forget();
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGUtils::AppendTransformUptoElement(nsIContent *aContent, nsIDOMSVGElement *aElement, nsIDOMSVGMatrix * *aCTM){
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMSVGElement> element = do_QueryInterface(aContent);
|
||||
nsIContent *ancestor = GetParentElement(aContent);
|
||||
if (!aElement) {
|
||||
// calculating GetScreenCTM(): traverse upto the root or non-SVG content.
|
||||
if (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG) {
|
||||
if (ancestor->Tag() == nsGkAtoms::foreignObject && aContent->Tag() != nsGkAtoms::svg)
|
||||
return NS_ERROR_FAILURE;
|
||||
rv = AppendTransformUptoElement(ancestor, aElement, aCTM);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
} else if (element != aElement) { // calculating GetCTM(): stop at aElement.
|
||||
NS_ASSERTION(ancestor != nsnull, "ancestor shouldn't be null.");
|
||||
if (!ancestor)
|
||||
return NS_ERROR_FAILURE;
|
||||
rv = AppendTransformUptoElement(ancestor, aElement, aCTM);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
if (nsCOMPtr<nsIDOMSVGSVGElement>(do_QueryInterface(aContent))) {
|
||||
nsSVGSVGElement *svgElement = static_cast<nsSVGSVGElement*>(aContent);
|
||||
rv = svgElement->AppendTransform(*aCTM, getter_AddRefs(tmp));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
} else if (nsCOMPtr<nsIDOMSVGTransformable>(do_QueryInterface(aContent))) {
|
||||
nsSVGGraphicElement *graphicElement = static_cast<nsSVGGraphicElement*>(aContent);
|
||||
rv = graphicElement->AppendTransform(*aCTM, getter_AddRefs(tmp));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
} else {
|
||||
//XXX aContent may be other type of viewport-establising elements
|
||||
// (e.g. <use> and <symbol>) and handle them?
|
||||
}
|
||||
if (tmp)
|
||||
tmp.swap(*aCTM);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGUtils::GetCTM(nsIContent *aContent, nsIDOMSVGMatrix * *aCTM)
|
||||
gfxMatrix
|
||||
nsSVGUtils::GetCTM(nsSVGElement *aElement, PRBool aScreenCTM)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIDocument* currentDoc = aContent->GetCurrentDoc();
|
||||
nsIDocument* currentDoc = aElement->GetCurrentDoc();
|
||||
if (currentDoc) {
|
||||
// Flush all pending notifications so that our frames are uptodate
|
||||
// Flush all pending notifications so that our frames are up to date
|
||||
currentDoc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
*aCTM = nsnull;
|
||||
nsCOMPtr<nsIDOMSVGElement> nearestViewportElement;
|
||||
rv = GetNearestViewportElement(aContent, getter_AddRefs(nearestViewportElement));
|
||||
// According to the spec(http://www.w3.org/TR/SVG11/types.html#InterfaceSVGLocatable),
|
||||
// GetCTM is strictly defined to be the CTM for nearestViewportElement,
|
||||
// Thus, if it is null, this is null, too.
|
||||
if (NS_FAILED(rv) || !nearestViewportElement)
|
||||
return NS_OK; // we can't throw exceptions from this API.
|
||||
gfxMatrix matrix = aElement->PrependLocalTransformTo(gfxMatrix());
|
||||
nsSVGElement *element = aElement;
|
||||
nsIContent *ancestor = GetParentElement(aElement);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
rv = NS_NewSVGMatrix(getter_AddRefs(tmp), 1, 0, 0, 1, 0, 0);
|
||||
if (NS_FAILED(rv)) return NS_OK; // we can't throw exceptions from this API.
|
||||
tmp.swap(*aCTM);
|
||||
rv = AppendTransformUptoElement(aContent, nearestViewportElement, aCTM);
|
||||
if (NS_FAILED(rv))
|
||||
tmp.swap(*aCTM);
|
||||
return NS_OK; // we can't throw exceptions from this API.
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGUtils::GetScreenCTM(nsIContent *aContent, nsIDOMSVGMatrix * *aCTM)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIDocument* currentDoc = aContent->GetCurrentDoc();
|
||||
if (currentDoc) {
|
||||
// Flush all pending notifications so that our frames are uptodate
|
||||
currentDoc->FlushPendingNotifications(Flush_Layout);
|
||||
while (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
ancestor->Tag() != nsGkAtoms::foreignObject) {
|
||||
element = static_cast<nsSVGElement*>(ancestor);
|
||||
matrix *= element->PrependLocalTransformTo(gfxMatrix()); // i.e. *A*ppend
|
||||
if (!aScreenCTM && EstablishesViewport(element)) {
|
||||
if (!element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG) &&
|
||||
!element->NodeInfo()->Equals(nsGkAtoms::symbol, kNameSpaceID_SVG)) {
|
||||
NS_ERROR("New (SVG > 1.1) SVG viewport establishing element?");
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
|
||||
}
|
||||
// XXX spec seems to say x,y translation should be undone for IsInnerSVG
|
||||
return matrix;
|
||||
}
|
||||
ancestor = GetParentElement(element);
|
||||
}
|
||||
|
||||
*aCTM = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
rv = NS_NewSVGMatrix(getter_AddRefs(tmp), 1, 0, 0, 1, 0, 0);
|
||||
if (NS_FAILED(rv)) return NS_OK; // we can't throw exceptions from this API.
|
||||
tmp.swap(*aCTM);
|
||||
rv = AppendTransformUptoElement(aContent, nsnull, aCTM);
|
||||
if (NS_FAILED(rv))
|
||||
tmp.swap(*aCTM);
|
||||
return NS_OK; // we can't throw exceptions from this API.
|
||||
if (!aScreenCTM) {
|
||||
// didn't find a nearestViewportElement
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
|
||||
}
|
||||
if (!ancestor || !ancestor->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
return matrix;
|
||||
}
|
||||
if (ancestor->GetNameSpaceID() == kNameSpaceID_SVG) {
|
||||
if (element->Tag() != nsGkAtoms::svg) {
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
|
||||
}
|
||||
return matrix * GetCTM(static_cast<nsSVGElement*>(ancestor), PR_TRUE);
|
||||
}
|
||||
// XXX this does not take into account CSS transform, or that the non-SVG
|
||||
// content that we've hit may itself be inside an SVG foreignObject higher up
|
||||
float x = 0.0f, y = 0.0f;
|
||||
if (element->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG)) {
|
||||
nsIPresShell *presShell = currentDoc->GetPrimaryShell();
|
||||
if (element && presShell) {
|
||||
nsPresContext *context = presShell->GetPresContext();
|
||||
if (context) {
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(element);
|
||||
nsIFrame* ancestorFrame = presShell->GetRootFrame();
|
||||
if (frame && ancestorFrame) {
|
||||
nsPoint point = frame->GetOffsetTo(ancestorFrame);
|
||||
x = nsPresContext::AppUnitsToFloatCSSPixels(point.x);
|
||||
y = nsPresContext::AppUnitsToFloatCSSPixels(point.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return matrix * gfxMatrix().Translate(gfxPoint(x, y));
|
||||
}
|
||||
|
||||
nsSVGDisplayContainerFrame*
|
||||
|
@ -574,33 +561,6 @@ nsSVGUtils::GetNearestSVGViewport(nsIFrame *aFrame)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGUtils::GetFarthestViewportElement(nsIContent *aContent,
|
||||
nsIDOMSVGElement * *aFarthestViewportElement)
|
||||
{
|
||||
*aFarthestViewportElement = nsnull;
|
||||
|
||||
nsIContent *ancestor = GetParentElement(aContent);
|
||||
nsCOMPtr<nsIDOMSVGElement> element;
|
||||
|
||||
while (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
ancestor->Tag() != nsGkAtoms::foreignObject) {
|
||||
|
||||
nsCOMPtr<nsIDOMSVGFitToViewBox> fitToViewBox = do_QueryInterface(ancestor);
|
||||
|
||||
if (fitToViewBox) {
|
||||
// right interface
|
||||
element = do_QueryInterface(ancestor);
|
||||
}
|
||||
|
||||
ancestor = GetParentElement(ancestor);
|
||||
}
|
||||
|
||||
element.swap(*aFarthestViewportElement);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsSVGUtils::FindFilterInvalidation(nsIFrame *aFrame, const nsRect& aRect)
|
||||
{
|
||||
|
@ -805,7 +765,7 @@ nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(nsIFrame* aFrame, nsRect* aRect)
|
|||
return GetOuterSVGFrame(aFrame);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGMatrix>
|
||||
gfxMatrix
|
||||
nsSVGUtils::GetViewBoxTransform(float aViewportWidth, float aViewportHeight,
|
||||
float aViewboxX, float aViewboxY,
|
||||
float aViewboxWidth, float aViewboxHeight,
|
||||
|
@ -891,9 +851,7 @@ nsSVGUtils::GetViewBoxTransform(float aViewportWidth, float aViewportHeight,
|
|||
if (aViewboxX) e += -a * aViewboxX;
|
||||
if (aViewboxY) f += -d * aViewboxY;
|
||||
|
||||
nsIDOMSVGMatrix *retval;
|
||||
NS_NewSVGMatrix(&retval, a, 0.0f, 0.0f, d, e, f);
|
||||
return retval;
|
||||
return gfxMatrix(a, 0.0f, 0.0f, d, e, f);
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
|
@ -902,8 +860,7 @@ nsSVGUtils::GetCanvasTM(nsIFrame *aFrame)
|
|||
// XXX yuck, we really need a common interface for GetCanvasTM
|
||||
|
||||
if (!aFrame->IsFrameOfType(nsIFrame::eSVG)) {
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix = nsSVGIntegrationUtils::GetInitialMatrix(aFrame);
|
||||
return ConvertSVGMatrixToThebes(matrix);
|
||||
return nsSVGIntegrationUtils::GetInitialMatrix(aFrame);
|
||||
}
|
||||
|
||||
nsIAtom* type = aFrame->GetType();
|
||||
|
@ -1038,8 +995,9 @@ nsSVGUtils::PaintFrameWithEffects(nsSVGRenderState *aContext,
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix =
|
||||
(clipPathFrame || maskFrame) ? NS_NewSVGMatrix(GetCanvasTM(aFrame)) : nsnull;
|
||||
gfxMatrix matrix;
|
||||
if (clipPathFrame || maskFrame)
|
||||
matrix = GetCanvasTM(aFrame);
|
||||
|
||||
/* Check if we need to do additional operations on this child's
|
||||
* rendering, which necessitates rendering into another surface. */
|
||||
|
@ -1122,8 +1080,7 @@ nsSVGUtils::HitTestClip(nsIFrame *aFrame, const nsPoint &aPoint)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> matrix = NS_NewSVGMatrix(GetCanvasTM(aFrame));
|
||||
return clipPathFrame->ClipHitTest(aFrame, matrix, aPoint);
|
||||
return clipPathFrame->ClipHitTest(aFrame, GetCanvasTM(aFrame), aPoint);
|
||||
}
|
||||
|
||||
nsIFrame *
|
||||
|
@ -1274,25 +1231,19 @@ nsSVGUtils::ConvertSVGMatrixToThebes(nsIDOMSVGMatrix *aMatrix)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsSVGUtils::HitTestRect(nsIDOMSVGMatrix *aMatrix,
|
||||
nsSVGUtils::HitTestRect(const gfxMatrix &aMatrix,
|
||||
float aRX, float aRY, float aRWidth, float aRHeight,
|
||||
float aX, float aY)
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
if (aMatrix) {
|
||||
gfxContext ctx(GetThebesComputationalSurface());
|
||||
ctx.SetMatrix(ConvertSVGMatrixToThebes(aMatrix));
|
||||
|
||||
ctx.NewPath();
|
||||
ctx.Rectangle(gfxRect(aRX, aRY, aRWidth, aRHeight));
|
||||
ctx.IdentityMatrix();
|
||||
|
||||
if (!ctx.PointInFill(gfxPoint(aX, aY)))
|
||||
result = PR_FALSE;
|
||||
if (aMatrix.IsSingular()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return result;
|
||||
gfxContext ctx(GetThebesComputationalSurface());
|
||||
ctx.SetMatrix(aMatrix);
|
||||
ctx.NewPath();
|
||||
ctx.Rectangle(gfxRect(aRX, aRY, aRWidth, aRHeight));
|
||||
ctx.IdentityMatrix();
|
||||
return ctx.PointInFill(gfxPoint(aX, aY));
|
||||
}
|
||||
|
||||
gfxRect
|
||||
|
@ -1339,40 +1290,31 @@ nsSVGUtils::GetClipRectForFrame(nsIFrame *aFrame,
|
|||
void
|
||||
nsSVGUtils::CompositeSurfaceMatrix(gfxContext *aContext,
|
||||
gfxASurface *aSurface,
|
||||
nsIDOMSVGMatrix *aCTM, float aOpacity)
|
||||
const gfxMatrix &aCTM, float aOpacity)
|
||||
{
|
||||
gfxMatrix matrix = ConvertSVGMatrixToThebes(aCTM);
|
||||
if (matrix.IsSingular())
|
||||
if (aCTM.IsSingular())
|
||||
return;
|
||||
|
||||
aContext->Save();
|
||||
|
||||
aContext->Multiply(matrix);
|
||||
|
||||
aContext->Multiply(aCTM);
|
||||
aContext->SetSource(aSurface);
|
||||
aContext->Paint(aOpacity);
|
||||
|
||||
aContext->Restore();
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::CompositePatternMatrix(gfxContext *aContext,
|
||||
gfxPattern *aPattern,
|
||||
nsIDOMSVGMatrix *aCTM, float aWidth, float aHeight, float aOpacity)
|
||||
const gfxMatrix &aCTM, float aWidth, float aHeight, float aOpacity)
|
||||
{
|
||||
gfxMatrix matrix = ConvertSVGMatrixToThebes(aCTM);
|
||||
if (matrix.IsSingular())
|
||||
if (aCTM.IsSingular())
|
||||
return;
|
||||
|
||||
aContext->Save();
|
||||
|
||||
SetClipRect(aContext, ConvertSVGMatrixToThebes(aCTM), gfxRect(0, 0, aWidth, aHeight));
|
||||
|
||||
aContext->Multiply(matrix);
|
||||
|
||||
SetClipRect(aContext, aCTM, gfxRect(0, 0, aWidth, aHeight));
|
||||
aContext->Multiply(aCTM);
|
||||
aContext->SetPattern(aPattern);
|
||||
aContext->Paint(aOpacity);
|
||||
|
||||
aContext->Restore();
|
||||
}
|
||||
|
||||
|
@ -1461,40 +1403,34 @@ nsSVGUtils::CanOptimizeOpacity(nsIFrame *aFrame)
|
|||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::MaxExpansion(nsIDOMSVGMatrix *aMatrix)
|
||||
nsSVGUtils::MaxExpansion(const gfxMatrix &aMatrix)
|
||||
{
|
||||
float a, b, c, d;
|
||||
aMatrix->GetA(&a);
|
||||
aMatrix->GetB(&b);
|
||||
aMatrix->GetC(&c);
|
||||
aMatrix->GetD(&d);
|
||||
|
||||
// maximum expansion derivation from
|
||||
// http://lists.cairographics.org/archives/cairo/2004-October/001980.html
|
||||
float f = (a * a + b * b + c * c + d * d) / 2;
|
||||
float g = (a * a + b * b - c * c - d * d) / 2;
|
||||
float h = a * c + b * d;
|
||||
// and also implemented in cairo_matrix_transformed_circle_major_axis
|
||||
double a = aMatrix.xx;
|
||||
double b = aMatrix.yx;
|
||||
double c = aMatrix.xy;
|
||||
double d = aMatrix.yy;
|
||||
double f = (a * a + b * b + c * c + d * d) / 2;
|
||||
double g = (a * a + b * b - c * c - d * d) / 2;
|
||||
double h = a * c + b * d;
|
||||
return sqrt(f + sqrt(g * g + h * h));
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGMatrix>
|
||||
nsSVGUtils::AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
|
||||
gfxMatrix
|
||||
nsSVGUtils::AdjustMatrixForUnits(const gfxMatrix &aMatrix,
|
||||
nsSVGEnum *aUnits,
|
||||
nsIFrame *aFrame)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> fini = aMatrix;
|
||||
|
||||
if (aFrame &&
|
||||
aUnits->GetAnimValue() == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
gfxRect bbox = GetBBox(aFrame);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
aMatrix->Translate(bbox.X(), bbox.Y(), getter_AddRefs(tmp));
|
||||
tmp->ScaleNonUniform(bbox.Width(), bbox.Height(), getter_AddRefs(fini));
|
||||
return gfxMatrix().Scale(bbox.Width(), bbox.Height()) *
|
||||
gfxMatrix().Translate(gfxPoint(bbox.X(), bbox.Y())) *
|
||||
aMatrix;
|
||||
}
|
||||
|
||||
nsIDOMSVGMatrix* retval = fini.get();
|
||||
NS_IF_ADDREF(retval);
|
||||
return retval;
|
||||
return aMatrix;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
@ -1567,6 +1503,17 @@ nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
|||
return strokeExtents;
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsSVGUtils::IsInnerSVG(nsIContent* aContent)
|
||||
{
|
||||
if (!aContent->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsIContent *ancestor = GetParentElement(aContent);
|
||||
return ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
|
||||
ancestor->Tag() != nsGkAtoms::foreignObject;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
nsSVGRenderState::nsSVGRenderState(nsIRenderingContext *aContext) :
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsIRenderingContext.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
|
||||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
|
@ -58,7 +59,6 @@ class nsIFrame;
|
|||
struct nsStyleSVGPaint;
|
||||
class nsIDOMSVGElement;
|
||||
class nsIDOMSVGLength;
|
||||
class nsIDOMSVGMatrix;
|
||||
class nsIURI;
|
||||
class nsSVGOuterSVGFrame;
|
||||
class nsIPresShell;
|
||||
|
@ -251,32 +251,19 @@ public:
|
|||
nsSVGElement *aContent,
|
||||
const nsStyleCoord &aCoord);
|
||||
|
||||
/*
|
||||
* This does the actual job for GetCTM and GetScreenCTM. When called,
|
||||
* this goes up the tree starting from aContent, until reaching to aElement.
|
||||
* When aElement is null, this goes up to the outermost SVG parent. Then,
|
||||
* this post-multiplies aCTM by each parent node's transformation matrix,
|
||||
* going down the tree from aElement to aContent.
|
||||
* This doesn't initialize aCTM. So callers usually should pass
|
||||
* the identity matrix by aCTM.
|
||||
*/
|
||||
static nsresult AppendTransformUptoElement(nsIContent *aContent,
|
||||
nsIDOMSVGElement *aElement,
|
||||
nsIDOMSVGMatrix * *aCTM);
|
||||
/*
|
||||
* Return the CTM
|
||||
*/
|
||||
static nsresult GetCTM(nsIContent *aContent, nsIDOMSVGMatrix * *aCTM);
|
||||
static gfxMatrix GetCTM(nsSVGElement *aElement, PRBool aScreenCTM);
|
||||
|
||||
/*
|
||||
* Return the screen CTM
|
||||
/**
|
||||
* Check if this is one of the SVG elements that SVG 1.1 Full says
|
||||
* establishes a viewport: svg, symbol, image or foreignObject.
|
||||
*/
|
||||
static nsresult GetScreenCTM(nsIContent *aContent, nsIDOMSVGMatrix * *aCTM);
|
||||
/*
|
||||
* Return the nearest viewport element
|
||||
*/
|
||||
static nsresult GetNearestViewportElement(nsIContent *aContent,
|
||||
nsIDOMSVGElement * *aNearestViewportElement);
|
||||
static PRBool EstablishesViewport(nsIContent *aContent);
|
||||
|
||||
static already_AddRefed<nsIDOMSVGElement>
|
||||
GetNearestViewportElement(nsIContent *aContent);
|
||||
|
||||
static already_AddRefed<nsIDOMSVGElement>
|
||||
GetFarthestViewportElement(nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Gets the nearest nsSVGInnerSVGFrame or nsSVGOuterSVGFrame frame. aFrame
|
||||
|
@ -284,13 +271,7 @@ public:
|
|||
* returns nsnull.
|
||||
*/
|
||||
static nsSVGDisplayContainerFrame* GetNearestSVGViewport(nsIFrame *aFrame);
|
||||
|
||||
/*
|
||||
* Get the farthest viewport element
|
||||
*/
|
||||
static nsresult GetFarthestViewportElement(nsIContent *aContent,
|
||||
nsIDOMSVGElement * *aFarthestViewportElement);
|
||||
|
||||
|
||||
/**
|
||||
* Figures out the worst case invalidation area for a frame, taking
|
||||
* filters into account.
|
||||
|
@ -361,7 +342,7 @@ public:
|
|||
|
||||
/* Generate a viewbox to viewport tranformation matrix */
|
||||
|
||||
static already_AddRefed<nsIDOMSVGMatrix>
|
||||
static gfxMatrix
|
||||
GetViewBoxTransform(float aViewportWidth, float aViewportHeight,
|
||||
float aViewboxX, float aViewboxY,
|
||||
float aViewboxWidth, float aViewboxHeight,
|
||||
|
@ -441,7 +422,7 @@ public:
|
|||
* Hit test a given rectangle/matrix.
|
||||
*/
|
||||
static PRBool
|
||||
HitTestRect(nsIDOMSVGMatrix *aMatrix,
|
||||
HitTestRect(const gfxMatrix &aMatrix,
|
||||
float aRX, float aRY, float aRWidth, float aRHeight,
|
||||
float aX, float aY);
|
||||
|
||||
|
@ -459,11 +440,11 @@ public:
|
|||
|
||||
static void CompositeSurfaceMatrix(gfxContext *aContext,
|
||||
gfxASurface *aSurface,
|
||||
nsIDOMSVGMatrix *aCTM, float aOpacity);
|
||||
const gfxMatrix &aCTM, float aOpacity);
|
||||
|
||||
static void CompositePatternMatrix(gfxContext *aContext,
|
||||
gfxPattern *aPattern,
|
||||
nsIDOMSVGMatrix *aCTM, float aWidth, float aHeight, float aOpacity);
|
||||
const gfxMatrix &aCTM, float aWidth, float aHeight, float aOpacity);
|
||||
|
||||
static void SetClipRect(gfxContext *aContext,
|
||||
const gfxMatrix &aCTM,
|
||||
|
@ -491,7 +472,7 @@ public:
|
|||
|
||||
/* Calculate the maximum expansion of a matrix */
|
||||
static float
|
||||
MaxExpansion(nsIDOMSVGMatrix *aMatrix);
|
||||
MaxExpansion(const gfxMatrix &aMatrix);
|
||||
|
||||
/**
|
||||
* Take the CTM to userspace for an element, and adjust it to a CTM to its
|
||||
|
@ -501,8 +482,8 @@ public:
|
|||
*
|
||||
* If the bbox is empty, this will return a singular matrix.
|
||||
*/
|
||||
static already_AddRefed<nsIDOMSVGMatrix>
|
||||
AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
|
||||
static gfxMatrix
|
||||
AdjustMatrixForUnits(const gfxMatrix &aMatrix,
|
||||
nsSVGEnum *aUnits,
|
||||
nsIFrame *aFrame);
|
||||
|
||||
|
@ -551,6 +532,12 @@ public:
|
|||
static gfxRect PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
||||
nsSVGGeometryFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Returns true if aContent is an SVG <svg> element that is the child of
|
||||
* another non-foreignObject SVG element.
|
||||
*/
|
||||
static PRBool IsInnerSVG(nsIContent* aContent);
|
||||
|
||||
private:
|
||||
/* Computational (nil) surfaces */
|
||||
static gfxASurface *mThebesComputationalSurface;
|
||||
|
|
Загрузка…
Ссылка в новой задаче