зеркало из https://github.com/mozilla/pjs.git
Bug 495938. Stop using nsIDOMSVGRect objects on the stack. r=longsonr
This commit is contained in:
Родитель
2ee7e4670a
Коммит
bb7678b0ca
|
@ -48,7 +48,7 @@
|
|||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "nsSVGRect.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
@ -95,10 +95,8 @@ NS_IMETHODIMP nsSVGGraphicElement::GetBBox(nsIDOMSVGRect **_retval)
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsISVGChildFrame* svgframe = do_QueryFrame(frame);
|
||||
NS_ASSERTION(svgframe, "wrong frame type");
|
||||
if (svgframe) {
|
||||
*_retval = nsSVGUtils::GetBBox(frame).get();
|
||||
return NS_OK;
|
||||
return NS_NewSVGRect(_retval, nsSVGUtils::GetBBox(frame));
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#include "nsSVGLength.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGValue.h"
|
||||
#include "nsTextFormatter.h"
|
||||
|
|
|
@ -770,12 +770,9 @@ nsSVGSVGElement::GetBBox(nsIDOMSVGRect **_retval)
|
|||
|
||||
nsISVGChildFrame* svgframe = do_QueryFrame(frame);
|
||||
if (svgframe) {
|
||||
*_retval = nsSVGUtils::GetBBox(frame).get();
|
||||
return NS_OK;
|
||||
} else {
|
||||
// XXX: outer svg
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return NS_NewSVGRect(_retval, nsSVGUtils::GetBBox(frame));
|
||||
}
|
||||
return NS_ERROR_NOT_IMPLEMENTED; // XXX: outer svg
|
||||
}
|
||||
|
||||
/* nsIDOMSVGMatrix getCTM (); */
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
|
||||
class gfxContext;
|
||||
class nsPresContext;
|
||||
class nsIDOMSVGRect;
|
||||
class nsIDOMSVGMatrix;
|
||||
class nsSVGRenderState;
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGClipPathElement.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -111,22 +111,14 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
|||
PRUint16 primitiveUnits =
|
||||
filter->mEnumAttributes[nsSVGFilterElement::PRIMITIVEUNITS].GetAnimValue();
|
||||
|
||||
nsCOMPtr<nsIDOMSVGRect> bbox;
|
||||
gfxRect bbox;
|
||||
if (aOverrideSourceBBox) {
|
||||
NS_NewSVGRect(getter_AddRefs(bbox),
|
||||
aOverrideSourceBBox->x, aOverrideSourceBBox->y,
|
||||
aOverrideSourceBBox->width, aOverrideSourceBBox->height);
|
||||
bbox = gfxRect(aOverrideSourceBBox->x, aOverrideSourceBBox->y,
|
||||
aOverrideSourceBBox->width, aOverrideSourceBBox->height);
|
||||
} else {
|
||||
bbox = nsSVGUtils::GetBBox(aTarget);
|
||||
}
|
||||
|
||||
if (!bbox &&
|
||||
(filterUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX ||
|
||||
primitiveUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)) {
|
||||
// XXX dispatch error console warning?
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the filter region (in the filtered element's user space):
|
||||
|
||||
// XXX if filterUnits is set (or has defaulted) to objectBoundingBox, we
|
||||
|
|
|
@ -155,20 +155,11 @@ nsSVGFilterInstance::BuildSources()
|
|||
mSourceAlpha.mImage.mFilterPrimitiveSubregion = filterRegion;
|
||||
|
||||
nsIntRect sourceBoundsInt;
|
||||
if (mTargetBBox) {
|
||||
float x, y, w, h;
|
||||
mTargetBBox->GetX(&x);
|
||||
mTargetBBox->GetY(&y);
|
||||
mTargetBBox->GetWidth(&w);
|
||||
mTargetBBox->GetHeight(&h);
|
||||
|
||||
gfxRect sourceBounds = UserSpaceToFilterSpace(gfxRect(x, y, w, h));
|
||||
|
||||
sourceBounds.RoundOut();
|
||||
// Detect possible float->int overflow
|
||||
if (NS_FAILED(nsSVGUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt)))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
gfxRect sourceBounds = UserSpaceToFilterSpace(mTargetBBox);
|
||||
sourceBounds.RoundOut();
|
||||
// Detect possible float->int overflow
|
||||
if (NS_FAILED(nsSVGUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mSourceColorAlpha.mResultBoundingBox = sourceBoundsInt;
|
||||
mSourceAlpha.mResultBoundingBox = sourceBoundsInt;
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#define __NS_SVGFILTERINSTANCE_H__
|
||||
|
||||
#include "nsIDOMSVGLength.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "nsIDOMSVGFilters.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIContent.h"
|
||||
|
@ -53,6 +52,7 @@ class nsSVGLength2;
|
|||
class nsSVGElement;
|
||||
class nsSVGFilterElement;
|
||||
class nsSVGFilterPaintCallback;
|
||||
struct gfxRect;
|
||||
|
||||
/**
|
||||
* This class performs all filter processing.
|
||||
|
@ -69,7 +69,7 @@ public:
|
|||
nsSVGFilterInstance(nsIFrame *aTargetFrame,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
nsSVGFilterElement *aFilterElement,
|
||||
nsIDOMSVGRect *aTargetBBox,
|
||||
const gfxRect &aTargetBBox,
|
||||
const gfxRect& aFilterRect,
|
||||
const nsIntSize& aFilterSpaceSize,
|
||||
nsIDOMSVGMatrix *aFilterSpaceToDeviceSpaceTransform,
|
||||
|
@ -184,7 +184,7 @@ private:
|
|||
nsIFrame* mTargetFrame;
|
||||
nsSVGFilterPaintCallback* mPaintCallback;
|
||||
nsSVGFilterElement* mFilterElement;
|
||||
nsCOMPtr<nsIDOMSVGRect> mTargetBBox;
|
||||
gfxRect mTargetBBox;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mFilterSpaceToDeviceSpaceTransform;
|
||||
gfxRect mFilterRect;
|
||||
nsIntSize mFilterSpaceSize;
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsSVGGradientFrame.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -168,15 +167,8 @@ nsSVGGradientFrame::GetGradientTransform(nsSVGGeometryFrame *aSource)
|
|||
|
||||
nsIFrame *frame = (callerType == nsGkAtoms::svgGlyphFrame) ?
|
||||
aSource->GetParent() : aSource;
|
||||
nsCOMPtr<nsIDOMSVGRect> rect = nsSVGUtils::GetBBox(frame);
|
||||
if (rect) {
|
||||
float x, y, width, height;
|
||||
rect->GetX(&x);
|
||||
rect->GetY(&y);
|
||||
rect->GetWidth(&width);
|
||||
rect->GetHeight(&height);
|
||||
bboxMatrix = gfxMatrix(width, 0, 0, height, x, y);
|
||||
}
|
||||
gfxRect bbox = nsSVGUtils::GetBBox(frame);
|
||||
bboxMatrix = gfxMatrix(bbox.Width(), 0, 0, bbox.Height(), bbox.X(), bbox.Y());
|
||||
}
|
||||
|
||||
nsSVGGradientElement *element =
|
||||
|
|
|
@ -103,6 +103,8 @@ private:
|
|||
PRUint32 GetStopCount();
|
||||
void GetStopInformation(PRInt32 aIndex,
|
||||
float *aOffset, nscolor *aColor, float *aStopOpacity);
|
||||
|
||||
// Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
|
||||
gfxMatrix GetGradientTransform(nsSVGGeometryFrame *aSource);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "nsSVGMaskElement.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -76,11 +75,9 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
|||
|
||||
PRUint16 units =
|
||||
mask->mEnumAttributes[nsSVGMaskElement::MASKUNITS].GetAnimValue();
|
||||
nsCOMPtr<nsIDOMSVGRect> bbox;
|
||||
gfxRect bbox;
|
||||
if (units == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
bbox = nsSVGUtils::GetBBox(aParent);
|
||||
if (!bbox)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
gfxRect maskArea = nsSVGUtils::GetRelativeRect(units,
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "nsStyleContext.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsISVGChildFrame.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
@ -56,11 +55,6 @@
|
|||
#include "gfxPlatform.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
static void printCTM(char *msg, gfxMatrix aCTM);
|
||||
static void printCTM(char *msg, nsIDOMSVGMatrix *aCTM);
|
||||
static void printRect(char *msg, nsIDOMSVGRect *aRect);
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
@ -202,10 +196,10 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
|||
// Get all of the information we need from our "caller" -- i.e.
|
||||
// the geometry that is being rendered with a pattern
|
||||
nsSVGElement *callerContent;
|
||||
nsCOMPtr<nsIDOMSVGRect> callerBBox;
|
||||
gfxRect callerBBox;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> callerCTM;
|
||||
if (NS_FAILED(GetCallerGeometry(getter_AddRefs(callerCTM),
|
||||
getter_AddRefs(callerBBox),
|
||||
if (NS_FAILED(GetTargetGeometry(getter_AddRefs(callerCTM),
|
||||
&callerBBox,
|
||||
&callerContent, aSource)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -217,28 +211,16 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
|||
// 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
|
||||
// box for the pattern tile.
|
||||
nsCOMPtr<nsIDOMSVGRect> bbox;
|
||||
if (NS_FAILED(GetPatternRect(getter_AddRefs(bbox),
|
||||
callerBBox, callerCTM,
|
||||
callerContent)))
|
||||
return NS_ERROR_FAILURE;
|
||||
gfxRect bbox = GetPatternRect(callerBBox, callerCTM, callerContent);
|
||||
|
||||
// Get the transformation matrix that we will hand to the renderer's pattern
|
||||
// routine.
|
||||
*patternMatrix = GetPatternMatrix(bbox, callerBBox, callerCTM);
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
printRect("Geometry Rect: ", callerBBox);
|
||||
printRect("Pattern Rect: ", bbox);
|
||||
printCTM("Pattern TM ", *patternMatrix);
|
||||
printCTM("Child TM ", mCTM);
|
||||
#endif
|
||||
|
||||
// Now that we have all of the necessary geometries, we can
|
||||
// create our surface.
|
||||
float patternWidth, patternHeight;
|
||||
bbox->GetWidth(&patternWidth);
|
||||
bbox->GetHeight(&patternHeight);
|
||||
float patternWidth = bbox.Width();
|
||||
float patternHeight = bbox.Height();
|
||||
|
||||
PRBool resultOverflows;
|
||||
gfxIntSize surfaceSize =
|
||||
|
@ -264,10 +246,6 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
|||
patternHeight / surfaceSize.height);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
printf("Creating %dX%d surface\n", int(surfaceSize.width), int(surfaceSize.height));
|
||||
#endif
|
||||
|
||||
nsRefPtr<gfxASurface> tmpSurface =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(surfaceSize,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
@ -494,11 +472,10 @@ nsSVGPatternFrame::GetPatternWithAttr(nsIAtom *aAttrName, nsIContent *aDefault)
|
|||
// Helper functions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsSVGPatternFrame::GetPatternRect(nsIDOMSVGRect **patternRect,
|
||||
nsIDOMSVGRect *bbox,
|
||||
nsIDOMSVGMatrix *callerCTM,
|
||||
nsSVGElement *content)
|
||||
gfxRect
|
||||
nsSVGPatternFrame::GetPatternRect(const gfxRect &aTargetBBox,
|
||||
nsIDOMSVGMatrix *aTargetCTM,
|
||||
nsSVGElement *aTarget)
|
||||
{
|
||||
// Get our type
|
||||
PRUint16 type = GetPatternUnits();
|
||||
|
@ -514,19 +491,19 @@ nsSVGPatternFrame::GetPatternRect(nsIDOMSVGRect **patternRect,
|
|||
tmpWidth = GetWidth();
|
||||
|
||||
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
x = nsSVGUtils::ObjectSpace(bbox, tmpX);
|
||||
y = nsSVGUtils::ObjectSpace(bbox, tmpY);
|
||||
width = nsSVGUtils::ObjectSpace(bbox, tmpWidth);
|
||||
height = nsSVGUtils::ObjectSpace(bbox, tmpHeight);
|
||||
x = nsSVGUtils::ObjectSpace(aTargetBBox, tmpX);
|
||||
y = nsSVGUtils::ObjectSpace(aTargetBBox, tmpY);
|
||||
width = nsSVGUtils::ObjectSpace(aTargetBBox, tmpWidth);
|
||||
height = nsSVGUtils::ObjectSpace(aTargetBBox, tmpHeight);
|
||||
} else {
|
||||
float scale = nsSVGUtils::MaxExpansion(callerCTM);
|
||||
x = nsSVGUtils::UserSpace(content, tmpX) * scale;
|
||||
y = nsSVGUtils::UserSpace(content, tmpY) * scale;
|
||||
width = nsSVGUtils::UserSpace(content, tmpWidth) * scale;
|
||||
height = nsSVGUtils::UserSpace(content, tmpHeight) * scale;
|
||||
float scale = nsSVGUtils::MaxExpansion(aTargetCTM);
|
||||
x = nsSVGUtils::UserSpace(aTarget, tmpX) * scale;
|
||||
y = nsSVGUtils::UserSpace(aTarget, tmpY) * scale;
|
||||
width = nsSVGUtils::UserSpace(aTarget, tmpWidth) * scale;
|
||||
height = nsSVGUtils::UserSpace(aTarget, tmpHeight) * scale;
|
||||
}
|
||||
|
||||
return NS_NewSVGRect(patternRect, x, y, width, height);
|
||||
return gfxRect(x, y, width, height);
|
||||
}
|
||||
|
||||
static float
|
||||
|
@ -537,7 +514,7 @@ GetLengthValue(const nsSVGLength2 *aLength)
|
|||
|
||||
nsresult
|
||||
nsSVGPatternFrame::ConstructCTM(nsIDOMSVGMatrix **aCTM,
|
||||
nsIDOMSVGRect *callerBBox,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tCTM, tempTM;
|
||||
|
@ -547,12 +524,8 @@ nsSVGPatternFrame::ConstructCTM(nsIDOMSVGMatrix **aCTM,
|
|||
PRUint16 type = GetPatternContentUnits();
|
||||
|
||||
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
// Use the bounding box
|
||||
float width, height;
|
||||
callerBBox->GetWidth(&width);
|
||||
callerBBox->GetHeight(&height);
|
||||
NS_NewSVGMatrix(getter_AddRefs(tCTM), width, 0.0f, 0.0f,
|
||||
height, 0.0f, 0.0f);
|
||||
NS_NewSVGMatrix(getter_AddRefs(tCTM), callerBBox.Width(), 0.0f, 0.0f,
|
||||
callerBBox.Height(), 0.0f, 0.0f);
|
||||
} else {
|
||||
float scale = nsSVGUtils::MaxExpansion(callerCTM);
|
||||
NS_NewSVGMatrix(getter_AddRefs(tCTM), scale, 0, 0, scale, 0, 0);
|
||||
|
@ -582,25 +555,21 @@ nsSVGPatternFrame::ConstructCTM(nsIDOMSVGMatrix **aCTM,
|
|||
}
|
||||
|
||||
gfxMatrix
|
||||
nsSVGPatternFrame::GetPatternMatrix(nsIDOMSVGRect *bbox,
|
||||
nsIDOMSVGRect *callerBBox,
|
||||
nsSVGPatternFrame::GetPatternMatrix(const gfxRect &bbox,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM)
|
||||
{
|
||||
// Get the pattern transform
|
||||
gfxMatrix patternTransform = GetPatternTransform();
|
||||
|
||||
// We really want the pattern matrix to handle translations
|
||||
float minx, miny;
|
||||
bbox->GetX(&minx);
|
||||
bbox->GetY(&miny);
|
||||
float minx = bbox.X();
|
||||
float miny = bbox.Y();
|
||||
|
||||
PRUint16 type = GetPatternContentUnits();
|
||||
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
float x, y;
|
||||
callerBBox->GetX(&x);
|
||||
callerBBox->GetY(&y);
|
||||
minx += x;
|
||||
miny += y;
|
||||
minx += callerBBox.X();
|
||||
miny += callerBBox.Y();
|
||||
}
|
||||
|
||||
float scale = 1.0f / nsSVGUtils::MaxExpansion(callerCTM);
|
||||
|
@ -611,71 +580,54 @@ nsSVGPatternFrame::GetPatternMatrix(nsIDOMSVGRect *bbox,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsSVGPatternFrame::GetCallerGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
nsIDOMSVGRect **aBBox,
|
||||
nsSVGElement **aContent,
|
||||
nsSVGGeometryFrame *aSource)
|
||||
nsSVGPatternFrame::GetTargetGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
gfxRect *aBBox,
|
||||
nsSVGElement **aTargetContent,
|
||||
nsSVGGeometryFrame *aTarget)
|
||||
{
|
||||
*aCTM = nsnull;
|
||||
*aBBox = nsnull;
|
||||
*aContent = nsnull;
|
||||
*aTargetContent = nsnull;
|
||||
|
||||
// Make sure the callerContent is an SVG element. If we are attempting
|
||||
// to paint a pattern for text, then the content will be the #text, so we
|
||||
// actually want the parent, which should be the <svg:text> or <svg:tspan>
|
||||
// element.
|
||||
nsIAtom *callerType = aSource->GetType();
|
||||
nsIAtom *callerType = aTarget->GetType();
|
||||
if (callerType == nsGkAtoms::svgGlyphFrame) {
|
||||
*aContent = static_cast<nsSVGElement*>
|
||||
(aSource->GetContent()->GetParent());
|
||||
*aTargetContent = static_cast<nsSVGElement*>
|
||||
(aTarget->GetContent()->GetParent());
|
||||
} else {
|
||||
*aContent = static_cast<nsSVGElement*>(aSource->GetContent());
|
||||
*aTargetContent = static_cast<nsSVGElement*>(aTarget->GetContent());
|
||||
}
|
||||
NS_ASSERTION(aContent,"Caller does not have any content!");
|
||||
if (!aContent)
|
||||
NS_ASSERTION(aTargetContent,"Caller does not have any content!");
|
||||
if (!aTargetContent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (callerType == nsGkAtoms::svgGlyphFrame) {
|
||||
*aBBox = nsSVGUtils::GetBBox(aSource->GetParent()).get();
|
||||
*aBBox = nsSVGUtils::GetBBox(aTarget->GetParent());
|
||||
} else {
|
||||
*aBBox = nsSVGUtils::GetBBox(aSource).get();
|
||||
*aBBox = nsSVGUtils::GetBBox(aTarget);
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
PRUint16 type = GetPatternUnits();
|
||||
if (type == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
float width, height;
|
||||
(*aBBox)->GetWidth(&width);
|
||||
(*aBBox)->GetHeight(&height);
|
||||
if (width <= 0 || height <= 0) {
|
||||
if (aBBox->Width() <= 0 || aBBox->Height() <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the transformation matrix from our calling geometry
|
||||
*aCTM = NS_NewSVGMatrix(aSource->GetCanvasTM()).get();
|
||||
*aCTM = NS_NewSVGMatrix(aTarget->GetCanvasTM()).get();
|
||||
|
||||
// OK, now fix up the bounding box to reflect user coordinates
|
||||
// We handle device unit scaling in pattern matrix
|
||||
{
|
||||
float x, y, width, height;
|
||||
(*aBBox)->GetX(&x);
|
||||
(*aBBox)->GetY(&y);
|
||||
(*aBBox)->GetWidth(&width);
|
||||
(*aBBox)->GetHeight(&height);
|
||||
float scale = nsSVGUtils::MaxExpansion(*aCTM);
|
||||
#ifdef DEBUG_scooter
|
||||
fprintf(stderr, "pattern scale %f\n", scale);
|
||||
fprintf(stderr, "x,y,width,height: %f %f %f %f\n", x, y, width, height);
|
||||
#endif
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
width *= scale;
|
||||
height *= scale;
|
||||
(*aBBox)->SetX(x);
|
||||
(*aBBox)->SetY(y);
|
||||
(*aBBox)->SetWidth(width);
|
||||
(*aBBox)->SetHeight(height);
|
||||
if (scale <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aBBox->Scale(scale);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -736,32 +688,3 @@ nsIFrame* NS_NewSVGPatternFrame(nsIPresShell* aPresShell,
|
|||
return new (aPresShell) nsSVGPatternFrame(aContext);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
static void printCTM(char *msg, gfxMatrix aCTM)
|
||||
{
|
||||
printf("%s {%f,%f,%f,%f,%f,%f}\n", msg,
|
||||
aCTM.xx, aCTM.yx, aCTM.xy, aCTM.yy, aCTM.x0, aCTM.y0);
|
||||
}
|
||||
|
||||
static void printCTM(char *msg, nsIDOMSVGMatrix *aCTM)
|
||||
{
|
||||
float a,b,c,d,e,f;
|
||||
aCTM->GetA(&a);
|
||||
aCTM->GetB(&b);
|
||||
aCTM->GetC(&c);
|
||||
aCTM->GetD(&d);
|
||||
aCTM->GetE(&e);
|
||||
aCTM->GetF(&f);
|
||||
printf("%s {%f,%f,%f,%f,%f,%f}\n",msg,a,b,c,d,e,f);
|
||||
}
|
||||
|
||||
static void printRect(char *msg, nsIDOMSVGRect *aRect)
|
||||
{
|
||||
float x,y,width,height;
|
||||
aRect->GetX(&x);
|
||||
aRect->GetY(&y);
|
||||
aRect->GetWidth(&width);
|
||||
aRect->GetHeight(&height);
|
||||
printf("%s {%f,%f,%f,%f}\n",msg,x,y,width,height);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -128,20 +128,19 @@ protected:
|
|||
const nsSVGPreserveAspectRatio &GetPreserveAspectRatio();
|
||||
|
||||
NS_IMETHOD GetPatternFirstChild(nsIFrame **kid);
|
||||
nsresult GetPatternRect(nsIDOMSVGRect **patternRect,
|
||||
nsIDOMSVGRect *bbox,
|
||||
gfxRect GetPatternRect(const gfxRect &bbox,
|
||||
nsIDOMSVGMatrix *callerCTM,
|
||||
nsSVGElement *content);
|
||||
gfxMatrix GetPatternMatrix(nsIDOMSVGRect *bbox,
|
||||
nsIDOMSVGRect *callerBBox,
|
||||
gfxMatrix GetPatternMatrix(const gfxRect &bbox,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM);
|
||||
nsresult ConstructCTM(nsIDOMSVGMatrix **ctm,
|
||||
nsIDOMSVGRect *callerBBox,
|
||||
const gfxRect &callerBBox,
|
||||
nsIDOMSVGMatrix *callerCTM);
|
||||
nsresult GetCallerGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
nsIDOMSVGRect **aBBox,
|
||||
nsSVGElement **aContent,
|
||||
nsSVGGeometryFrame *aSource);
|
||||
nsresult GetTargetGeometry(nsIDOMSVGMatrix **aCTM,
|
||||
gfxRect *aBBox,
|
||||
nsSVGElement **aTargetContent,
|
||||
nsSVGGeometryFrame *aTarget);
|
||||
|
||||
private:
|
||||
// this is a *temporary* reference to the frame of the element currently
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
#include "nsSVGGFrame.h"
|
||||
#include "nsSVGSwitchElement.h"
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxMatrix.h"
|
||||
|
||||
|
|
|
@ -637,24 +637,19 @@ nsSVGUtils::ComputeNormalizedHypotenuse(double aWidth, double aHeight)
|
|||
}
|
||||
|
||||
float
|
||||
nsSVGUtils::ObjectSpace(nsIDOMSVGRect *aRect, const nsSVGLength2 *aLength)
|
||||
nsSVGUtils::ObjectSpace(const gfxRect &aRect, const nsSVGLength2 *aLength)
|
||||
{
|
||||
float fraction, axis;
|
||||
|
||||
switch (aLength->GetCtxType()) {
|
||||
case X:
|
||||
aRect->GetWidth(&axis);
|
||||
axis = aRect.Width();
|
||||
break;
|
||||
case Y:
|
||||
aRect->GetHeight(&axis);
|
||||
axis = aRect.Height();
|
||||
break;
|
||||
case XY:
|
||||
{
|
||||
float width, height;
|
||||
aRect->GetWidth(&width);
|
||||
aRect->GetHeight(&height);
|
||||
axis = float(ComputeNormalizedHypotenuse(width, height));
|
||||
}
|
||||
axis = float(ComputeNormalizedHypotenuse(aRect.Width(), aRect.Height()));
|
||||
}
|
||||
|
||||
if (aLength->IsPercentage()) {
|
||||
|
@ -1300,33 +1295,28 @@ nsSVGUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut)
|
|||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGRect>
|
||||
gfxRect
|
||||
nsSVGUtils::GetBBox(nsIFrame *aFrame)
|
||||
{
|
||||
gfxRect bbox;
|
||||
nsISVGChildFrame *svg = do_QueryFrame(aFrame);
|
||||
if (!svg) {
|
||||
nsIDOMSVGRect *rect = nsnull;
|
||||
gfxRect r = nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame);
|
||||
NS_NewSVGRect(&rect, r);
|
||||
return rect;
|
||||
if (svg) {
|
||||
bbox = svg->GetBBoxContribution(gfxMatrix());
|
||||
} else {
|
||||
bbox = nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGRect> bbox;
|
||||
NS_NewSVGRect(getter_AddRefs(bbox), svg->GetBBoxContribution(gfxMatrix()));
|
||||
|
||||
return bbox.forget();
|
||||
NS_ASSERTION(bbox.Width() >= 0.0 && bbox.Height() >= 0.0, "Invalid bbox!");
|
||||
return bbox;
|
||||
}
|
||||
|
||||
gfxRect
|
||||
nsSVGUtils::GetRelativeRect(PRUint16 aUnits, const nsSVGLength2 *aXYWH,
|
||||
nsIDOMSVGRect *aBBox, nsIFrame *aFrame)
|
||||
const gfxRect &aBBox, nsIFrame *aFrame)
|
||||
{
|
||||
float x, y, width, height;
|
||||
if (aUnits == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
aBBox->GetX(&x);
|
||||
x += ObjectSpace(aBBox, &aXYWH[0]);
|
||||
aBBox->GetY(&y);
|
||||
y += ObjectSpace(aBBox, &aXYWH[1]);
|
||||
x = aBBox.X() + ObjectSpace(aBBox, &aXYWH[0]);
|
||||
y = aBBox.Y() + ObjectSpace(aBBox, &aXYWH[1]);
|
||||
width = ObjectSpace(aBBox, &aXYWH[2]);
|
||||
height = ObjectSpace(aBBox, &aXYWH[3]);
|
||||
} else {
|
||||
|
@ -1381,32 +1371,10 @@ nsSVGUtils::AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
|
|||
|
||||
if (aFrame &&
|
||||
aUnits->GetAnimValue() == nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
|
||||
float minx, miny, width, height;
|
||||
|
||||
PRBool gotRect = PR_FALSE;
|
||||
if (aFrame->IsFrameOfType(nsIFrame::eSVG)) {
|
||||
nsCOMPtr<nsIDOMSVGRect> rect = GetBBox(aFrame);
|
||||
if (rect) {
|
||||
gotRect = PR_TRUE;
|
||||
rect->GetX(&minx);
|
||||
rect->GetY(&miny);
|
||||
rect->GetWidth(&width);
|
||||
rect->GetHeight(&height);
|
||||
}
|
||||
} else {
|
||||
gotRect = PR_TRUE;
|
||||
gfxRect r = nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame);
|
||||
minx = r.X();
|
||||
miny = r.Y();
|
||||
width = r.Width();
|
||||
height = r.Height();
|
||||
}
|
||||
|
||||
if (gotRect) {
|
||||
nsCOMPtr<nsIDOMSVGMatrix> tmp;
|
||||
aMatrix->Translate(minx, miny, getter_AddRefs(tmp));
|
||||
tmp->ScaleNonUniform(width, height, getter_AddRefs(fini));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
nsIDOMSVGMatrix* retval = fini.get();
|
||||
|
@ -1510,3 +1478,4 @@ nsSVGRenderState::GetRenderingContext(nsIFrame *aFrame)
|
|||
}
|
||||
return mRenderingContext;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,6 @@ class gfxContext;
|
|||
class gfxASurface;
|
||||
class gfxPattern;
|
||||
class gfxImageSurface;
|
||||
struct gfxRect;
|
||||
struct gfxMatrix;
|
||||
struct gfxSize;
|
||||
struct gfxIntSize;
|
||||
|
@ -308,7 +307,7 @@ public:
|
|||
Input: rect - bounding box
|
||||
length - length to be converted
|
||||
*/
|
||||
static float ObjectSpace(nsIDOMSVGRect *aRect, const nsSVGLength2 *aLength);
|
||||
static float ObjectSpace(const gfxRect &aRect, const nsSVGLength2 *aLength);
|
||||
|
||||
/* Computes the input length in terms of user space coordinates.
|
||||
Input: content - object to be used for determining user space
|
||||
|
@ -466,7 +465,14 @@ public:
|
|||
static float
|
||||
MaxExpansion(nsIDOMSVGMatrix *aMatrix);
|
||||
|
||||
/* Take a CTM and adjust for object bounding box coordinates, if needed */
|
||||
/**
|
||||
* Take the CTM to userspace for an element, and adjust it to a CTM to its
|
||||
* object bounding box space if aUnits is SVG_UNIT_TYPE_OBJECTBOUNDINGBOX.
|
||||
* (I.e. so that [0,0] is at the top left of its bbox, and [1,1] is at the
|
||||
* bottom right of its bbox).
|
||||
*
|
||||
* If the bbox is empty, this will return a singular matrix.
|
||||
*/
|
||||
static already_AddRefed<nsIDOMSVGMatrix>
|
||||
AdjustMatrixForUnits(nsIDOMSVGMatrix *aMatrix,
|
||||
nsSVGEnum *aUnits,
|
||||
|
@ -476,8 +482,7 @@ public:
|
|||
* Get bounding-box for aFrame. Matrix propagation is disabled so the
|
||||
* bounding box is computed in terms of aFrame's own user space.
|
||||
*/
|
||||
static already_AddRefed<nsIDOMSVGRect>
|
||||
GetBBox(nsIFrame *aFrame);
|
||||
static gfxRect GetBBox(nsIFrame *aFrame);
|
||||
/**
|
||||
* Compute a rectangle in userSpaceOnUse or objectBoundingBoxUnits.
|
||||
* @param aXYWH pointer to 4 consecutive nsSVGLength2 objects containing
|
||||
|
@ -488,8 +493,8 @@ public:
|
|||
* may be null if aUnits is SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
|
||||
*/
|
||||
static gfxRect
|
||||
GetRelativeRect(PRUint16 aUnits, const nsSVGLength2 *aXYWH, nsIDOMSVGRect *aBBox,
|
||||
nsIFrame *aFrame);
|
||||
GetRelativeRect(PRUint16 aUnits, const nsSVGLength2 *aXYWH,
|
||||
const gfxRect &aBBox, nsIFrame *aFrame);
|
||||
|
||||
/**
|
||||
* Find the first frame, starting with aStartFrame and going up its
|
||||
|
|
Загрузка…
Ссылка в новой задаче