Bug 435356. Stop using nsIDOMSVGMatrix internally. r=longsonr

This commit is contained in:
Jonathan Watt 2009-07-23 10:35:59 +02:00
Родитель 876fcce1ff
Коммит c35c73bbc6
41 изменённых файлов: 363 добавлений и 668 удалений

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

@ -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(),
gfxMatrix viewBoxTM =
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 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,
return gfxMatrix(cos(aAngle) * scale, sin(aAngle) * scale,
-sin(aAngle) * scale, cos(aAngle) * scale,
aX, aY);
*_retval = matrix;
NS_IF_ADDREF(*_retval);
return NS_OK;
}
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;
if (nsSVGUtils::IsInnerSVG(this)) {
nsSVGSVGElement *ctx = GetCtx();
if (!ctx) {
// outer svg
viewportWidth = mViewportWidth;
viewportHeight = mViewportHeight;
} else {
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,
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 nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
viewBox.x, viewBox.y,
viewBox.width, viewBox.height,
mPreserveAspectRatio);
xform.swap(*_retval);
return NS_OK;
}
#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>");
if (nsSVGUtils::IsInnerSVG(this)) {
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
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,
gfxMatrix filterToUserSpace(filterRegion.Width() / filterRes.width, 0.0f,
0.0f, filterRegion.Height() / filterRes.height,
filterRegion.X(), filterRegion.Y());
userToDeviceSpace->Multiply(filterToUserSpace, getter_AddRefs(filterToDeviceSpace));
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,
return gfxMatrix(widthScale, 0.0f,
0.0f, heightScale,
-mFilterRect.X() * widthScale,
-mFilterRect.Y() * heightScale);
return filterTransform.forget();
-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,
gfxMatrix viewBoxTM =
nsSVGUtils::GetViewBoxTransform(width, height,
0, 0, nativeWidth, nativeHeight,
element->mPreserveAspectRatio);
ctm->Translate(x, y, getter_AddRefs(ctmXY));
ctmXY->Multiply(trans, getter_AddRefs(fini));
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,
viewBoxTM = 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));
}
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;
element = ancestor;
ancestor = GetParentElement(element);
}
ancestor = GetParentElement(ancestor);
if (element && element->Tag() == nsGkAtoms::svg) {
return nsCOMPtr<nsIDOMSVGElement>(do_QueryInterface(element)).forget();
}
if (ancestor && ancestor->GetNameSpaceID() == kNameSpaceID_SVG &&
ancestor->Tag() == nsGkAtoms::foreignObject )
return NS_ERROR_FAILURE;
return NS_OK;
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 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.
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
}
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);
// XXX spec seems to say x,y translation should be undone for IsInnerSVG
return matrix;
}
*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.
ancestor = GetParentElement(element);
}
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) {
if (aMatrix.IsSingular()) {
return PR_FALSE;
}
gfxContext ctx(GetThebesComputationalSurface());
ctx.SetMatrix(ConvertSVGMatrixToThebes(aMatrix));
ctx.SetMatrix(aMatrix);
ctx.NewPath();
ctx.Rectangle(gfxRect(aRX, aRY, aRWidth, aRHeight));
ctx.IdentityMatrix();
if (!ctx.PointInFill(gfxPoint(aX, aY)))
result = PR_FALSE;
}
return result;
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
@ -285,12 +272,6 @@ public:
*/
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;