зеркало из https://github.com/mozilla/gecko-dev.git
Bug 765505 - Clean up filter code. r=longsonr.
This commit is contained in:
Родитель
75f06b250a
Коммит
faa9392008
|
@ -3306,10 +3306,10 @@ nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance,
|
|||
InitSeed((PRInt32)seed);
|
||||
|
||||
// XXXroc this makes absolutely no sense to me.
|
||||
float filterX = instance->GetFilterRect().X();
|
||||
float filterY = instance->GetFilterRect().Y();
|
||||
float filterWidth = instance->GetFilterRect().Width();
|
||||
float filterHeight = instance->GetFilterRect().Height();
|
||||
float filterX = instance->GetFilterRegion().X();
|
||||
float filterY = instance->GetFilterRegion().Y();
|
||||
float filterWidth = instance->GetFilterRegion().Width();
|
||||
float filterHeight = instance->GetFilterRegion().Height();
|
||||
|
||||
bool doStitch = false;
|
||||
if (stitch == nsIDOMSVGFETurbulenceElement::SVG_STITCHTYPE_STITCH) {
|
||||
|
|
|
@ -66,8 +66,8 @@ public:
|
|||
nsAutoFilterInstance(nsIFrame *aTarget,
|
||||
nsSVGFilterFrame *aFilterFrame,
|
||||
nsSVGFilterPaintCallback *aPaint,
|
||||
const nsIntRect *aDirtyOutputRect,
|
||||
const nsIntRect *aDirtyInputRect,
|
||||
const nsIntRect *aPostFilterDirtyRect,
|
||||
const nsIntRect *aPreFilterDirtyRect,
|
||||
const nsIntRect *aOverrideSourceBBox,
|
||||
const gfxMatrix *aOverrideUserToDeviceSpace = nsnull);
|
||||
~nsAutoFilterInstance() {}
|
||||
|
@ -83,8 +83,8 @@ private:
|
|||
nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
||||
nsSVGFilterFrame *aFilterFrame,
|
||||
nsSVGFilterPaintCallback *aPaint,
|
||||
const nsIntRect *aDirtyOutputRect,
|
||||
const nsIntRect *aDirtyInputRect,
|
||||
const nsIntRect *aPostFilterDirtyRect,
|
||||
const nsIntRect *aPreFilterDirtyRect,
|
||||
const nsIntRect *aOverrideSourceBBox,
|
||||
const gfxMatrix *aOverrideUserToDeviceSpace)
|
||||
{
|
||||
|
@ -198,10 +198,10 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
|||
gfxMatrix deviceToFilterSpace = filterToDeviceSpace;
|
||||
deviceToFilterSpace.Invert();
|
||||
|
||||
nsIntRect dirtyOutputRect =
|
||||
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aDirtyOutputRect);
|
||||
nsIntRect dirtyInputRect =
|
||||
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aDirtyInputRect);
|
||||
nsIntRect postFilterDirtyRect =
|
||||
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aPostFilterDirtyRect);
|
||||
nsIntRect preFilterDirtyRect =
|
||||
MapDeviceRectToFilterSpace(deviceToFilterSpace, filterRes, aPreFilterDirtyRect);
|
||||
nsIntRect targetBoundsDeviceSpace;
|
||||
nsISVGChildFrame* svgTarget = do_QueryFrame(aTarget);
|
||||
if (svgTarget) {
|
||||
|
@ -212,8 +212,8 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
|||
// space. In this case GetCoveredRegion() is not what we want since it is
|
||||
// in outer-<svg> space, GetFilterBBox passes in the pre-filter bounds of
|
||||
// the frame in frame space for us to use instead.
|
||||
NS_ASSERTION(aDirtyInputRect, "Who passed aOverrideUserToDeviceSpace?");
|
||||
targetBoundsDeviceSpace = *aDirtyInputRect;
|
||||
NS_ASSERTION(aPreFilterDirtyRect, "Who passed aOverrideUserToDeviceSpace?");
|
||||
targetBoundsDeviceSpace = *aPreFilterDirtyRect;
|
||||
} else {
|
||||
targetBoundsDeviceSpace =
|
||||
svgTarget->GetCoveredRegion().ToOutsidePixels(aTarget->
|
||||
|
@ -227,7 +227,7 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
|
|||
mInstance = new nsSVGFilterInstance(aTarget, aPaint, filter, bbox, filterRegion,
|
||||
nsIntSize(filterRes.width, filterRes.height),
|
||||
filterToDeviceSpace, targetBoundsFilterSpace,
|
||||
dirtyOutputRect, dirtyInputRect,
|
||||
postFilterDirtyRect, preFilterDirtyRect,
|
||||
primitiveUnits);
|
||||
}
|
||||
|
||||
|
@ -385,13 +385,13 @@ nsSVGFilterFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsSVGFilterFrame::FilterPaint(nsRenderingContext *aContext,
|
||||
nsIFrame *aTarget,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsIntRect *aDirtyRect)
|
||||
nsSVGFilterFrame::PaintFilteredFrame(nsRenderingContext *aContext,
|
||||
nsIFrame *aFilteredFrame,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsIntRect *aDirtyArea)
|
||||
{
|
||||
nsAutoFilterInstance instance(aTarget, this, aPaintCallback,
|
||||
aDirtyRect, nsnull, nsnull);
|
||||
nsAutoFilterInstance instance(aFilteredFrame, this, aPaintCallback,
|
||||
aDirtyArea, nsnull, nsnull);
|
||||
if (!instance.get())
|
||||
return NS_OK;
|
||||
|
||||
|
@ -405,7 +405,8 @@ nsSVGFilterFrame::FilterPaint(nsRenderingContext *aContext,
|
|||
}
|
||||
|
||||
static nsresult
|
||||
TransformFilterSpaceToDeviceSpace(nsSVGFilterInstance *aInstance, nsIntRect *aRect)
|
||||
TransformFilterSpaceToDeviceSpace(nsSVGFilterInstance *aInstance,
|
||||
nsIntRect *aRect)
|
||||
{
|
||||
gfxMatrix m = aInstance->GetFilterSpaceToDeviceSpaceTransform();
|
||||
gfxRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
|
@ -419,9 +420,11 @@ TransformFilterSpaceToDeviceSpace(nsSVGFilterInstance *aInstance, nsIntRect *aRe
|
|||
}
|
||||
|
||||
nsIntRect
|
||||
nsSVGFilterFrame::GetInvalidationBBox(nsIFrame *aTarget, const nsIntRect& aRect)
|
||||
nsSVGFilterFrame::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
|
||||
const nsIntRect& aPreFilterDirtyRect)
|
||||
{
|
||||
nsAutoFilterInstance instance(aTarget, this, nsnull, nsnull, &aRect, nsnull);
|
||||
nsAutoFilterInstance instance(aFilteredFrame, this, nsnull, nsnull,
|
||||
&aPreFilterDirtyRect, nsnull);
|
||||
if (!instance.get())
|
||||
return nsIntRect();
|
||||
|
||||
|
@ -429,7 +432,7 @@ nsSVGFilterFrame::GetInvalidationBBox(nsIFrame *aTarget, const nsIntRect& aRect)
|
|||
// Now we can ask the instance to compute the area of the filter output
|
||||
// that's dirty.
|
||||
nsIntRect dirtyRect;
|
||||
nsresult rv = instance.get()->ComputeOutputDirtyRect(&dirtyRect);
|
||||
nsresult rv = instance.get()->ComputePostFilterDirtyRect(&dirtyRect);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = TransformFilterSpaceToDeviceSpace(instance.get(), &dirtyRect);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
|
@ -440,9 +443,11 @@ nsSVGFilterFrame::GetInvalidationBBox(nsIFrame *aTarget, const nsIntRect& aRect)
|
|||
}
|
||||
|
||||
nsIntRect
|
||||
nsSVGFilterFrame::GetSourceForInvalidArea(nsIFrame *aTarget, const nsIntRect& aRect)
|
||||
nsSVGFilterFrame::GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
|
||||
const nsIntRect& aPostFilterDirtyRect)
|
||||
{
|
||||
nsAutoFilterInstance instance(aTarget, this, nsnull, &aRect, nsnull, nsnull);
|
||||
nsAutoFilterInstance instance(aFilteredFrame, this, nsnull,
|
||||
&aPostFilterDirtyRect, nsnull, nsnull);
|
||||
if (!instance.get())
|
||||
return nsIntRect();
|
||||
|
||||
|
@ -460,27 +465,29 @@ nsSVGFilterFrame::GetSourceForInvalidArea(nsIFrame *aTarget, const nsIntRect& aR
|
|||
}
|
||||
|
||||
nsIntRect
|
||||
nsSVGFilterFrame::GetFilterBBox(nsIFrame *aTarget,
|
||||
const nsIntRect *aOverrideBBox,
|
||||
const nsIntRect *aPreFilterBounds)
|
||||
nsSVGFilterFrame::GetPostFilterBounds(nsIFrame *aFilteredFrame,
|
||||
const nsIntRect *aOverrideBBox,
|
||||
const nsIntRect *aPreFilterBounds)
|
||||
{
|
||||
bool overrideCTM = false;
|
||||
gfxMatrix ctm;
|
||||
|
||||
if (aTarget->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
|
||||
if (aFilteredFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
|
||||
// For most filter operations on SVG frames we want information in
|
||||
// outer-<svg> device space, but in this case we want the visual overflow
|
||||
// rect relative to aTarget itself. For that we need to prevent the filter
|
||||
// code using GetCanvasTM().
|
||||
overrideCTM = true;
|
||||
PRInt32 appUnitsPerDevPixel = aTarget->PresContext()->AppUnitsPerDevPixel();
|
||||
PRInt32 appUnitsPerDevPixel =
|
||||
aFilteredFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
float devPxPerCSSPx =
|
||||
1 / nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPixel);
|
||||
ctm.Scale(devPxPerCSSPx, devPxPerCSSPx);
|
||||
}
|
||||
|
||||
nsAutoFilterInstance instance(aTarget, this, nsnull, nsnull, aPreFilterBounds,
|
||||
aOverrideBBox, overrideCTM ? &ctm : nsnull);
|
||||
nsAutoFilterInstance instance(aFilteredFrame, this, nsnull, nsnull,
|
||||
aPreFilterBounds, aOverrideBBox,
|
||||
overrideCTM ? &ctm : nsnull);
|
||||
if (!instance.get())
|
||||
return nsIntRect();
|
||||
|
||||
|
|
|
@ -45,34 +45,38 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
nsresult FilterPaint(nsRenderingContext *aContext,
|
||||
nsIFrame *aTarget, nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsIntRect* aDirtyRect);
|
||||
nsresult PaintFilteredFrame(nsRenderingContext *aContext,
|
||||
nsIFrame *aFilteredFrame,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsIntRect* aDirtyArea);
|
||||
|
||||
/**
|
||||
* Returns the area that could change when the given rect of the source changes.
|
||||
* The rectangles are relative to the origin of the outer svg, if aTarget is SVG,
|
||||
* relative to aTarget itself otherwise, in device pixels.
|
||||
* Returns the post-filter area that could be dirtied when the given
|
||||
* pre-filter area of aFilteredFrame changes. The rects are in device pixels,
|
||||
* relative to the origin of the outer-<svg> if aFilteredFrame is SVG, or
|
||||
* else relative to aFilteredFrame itself.
|
||||
*/
|
||||
nsIntRect GetInvalidationBBox(nsIFrame *aTarget, const nsIntRect& aRect);
|
||||
nsIntRect GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
|
||||
const nsIntRect& aPreFilterDirtyRect);
|
||||
|
||||
/**
|
||||
* Returns the area in device pixels that is needed from the source when
|
||||
* the given area needs to be repainted.
|
||||
* The rectangles are relative to the origin of the outer svg, if aTarget is SVG,
|
||||
* relative to aTarget itself otherwise, in device pixels.
|
||||
* Returns the pre-filter area that is needed from aFilteredFrame when the
|
||||
* given post-filter area needs to be repainted. The rects are in device
|
||||
* pixels, relative to the origin of the outer-<svg> if aFilteredFrame is
|
||||
* SVG, or else relative to aFilteredFrame itself.
|
||||
*/
|
||||
nsIntRect GetSourceForInvalidArea(nsIFrame *aTarget, const nsIntRect& aRect);
|
||||
nsIntRect GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
|
||||
const nsIntRect& aPostFilterDirtyRect);
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the post-filter area of aTarget.
|
||||
* The rectangles are relative to the origin of the outer svg, if aTarget is SVG,
|
||||
* relative to aTarget itself otherwise, in device pixels.
|
||||
* Returns the post-filter paint bounds of aFilteredFrame. The rects are in
|
||||
* device pixels, relative to the origin of the outer-<svg> if aFilteredFrame
|
||||
* is SVG, or else relative to aFilteredFrame itself.
|
||||
* @param aOverrideBBox overrides the normal bbox for the source, if non-null
|
||||
*/
|
||||
nsIntRect GetFilterBBox(nsIFrame *aTarget,
|
||||
const nsIntRect *aOverrideBBox = nsnull,
|
||||
const nsIntRect *aPreFilterBounds = nsnull);
|
||||
nsIntRect GetPostFilterBounds(nsIFrame *aFilteredFrame,
|
||||
const nsIntRect *aOverrideBBox = nsnull,
|
||||
const nsIntRect *aPreFilterBounds = nsnull);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD Init(nsIContent* aContent,
|
||||
|
|
|
@ -31,14 +31,14 @@ nsSVGFilterInstance::GetPrimitiveNumber(PRUint8 aCtxType, float aValue) const
|
|||
|
||||
switch (aCtxType) {
|
||||
case nsSVGUtils::X:
|
||||
return value * mFilterSpaceSize.width / mFilterRect.Width();
|
||||
return value * mFilterSpaceSize.width / mFilterRegion.Width();
|
||||
case nsSVGUtils::Y:
|
||||
return value * mFilterSpaceSize.height / mFilterRect.Height();
|
||||
return value * mFilterSpaceSize.height / mFilterRegion.Height();
|
||||
case nsSVGUtils::XY:
|
||||
default:
|
||||
return value * nsSVGUtils::ComputeNormalizedHypotenuse(
|
||||
mFilterSpaceSize.width / mFilterRect.Width(),
|
||||
mFilterSpaceSize.height / mFilterRect.Height());
|
||||
mFilterSpaceSize.width / mFilterRegion.Width(),
|
||||
mFilterSpaceSize.height / mFilterRegion.Height());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,27 +83,27 @@ nsSVGFilterInstance::CreateImage()
|
|||
gfxRect
|
||||
nsSVGFilterInstance::UserSpaceToFilterSpace(const gfxRect& aRect) const
|
||||
{
|
||||
gfxRect r = aRect - mFilterRect.TopLeft();
|
||||
r.Scale(mFilterSpaceSize.width / mFilterRect.Width(),
|
||||
mFilterSpaceSize.height / mFilterRect.Height());
|
||||
gfxRect r = aRect - mFilterRegion.TopLeft();
|
||||
r.Scale(mFilterSpaceSize.width / mFilterRegion.Width(),
|
||||
mFilterSpaceSize.height / mFilterRegion.Height());
|
||||
return r;
|
||||
}
|
||||
|
||||
gfxPoint
|
||||
nsSVGFilterInstance::FilterSpaceToUserSpace(const gfxPoint& aPt) const
|
||||
{
|
||||
return gfxPoint(aPt.x * mFilterRect.Width() / mFilterSpaceSize.width + mFilterRect.X(),
|
||||
aPt.y * mFilterRect.Height() / mFilterSpaceSize.height + mFilterRect.Y());
|
||||
return gfxPoint(aPt.x * mFilterRegion.Width() / mFilterSpaceSize.width + mFilterRegion.X(),
|
||||
aPt.y * mFilterRegion.Height() / mFilterSpaceSize.height + mFilterRegion.Y());
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
nsSVGFilterInstance::GetUserSpaceToFilterSpaceTransform() const
|
||||
{
|
||||
gfxFloat widthScale = mFilterSpaceSize.width / mFilterRect.Width();
|
||||
gfxFloat heightScale = mFilterSpaceSize.height / mFilterRect.Height();
|
||||
gfxFloat widthScale = mFilterSpaceSize.width / mFilterRegion.Width();
|
||||
gfxFloat heightScale = mFilterSpaceSize.height / mFilterRegion.Height();
|
||||
return gfxMatrix(widthScale, 0.0f,
|
||||
0.0f, heightScale,
|
||||
-mFilterRect.X() * widthScale, -mFilterRect.Y() * heightScale);
|
||||
-mFilterRegion.X() * widthScale, -mFilterRegion.Y() * heightScale);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -277,7 +277,7 @@ nsSVGFilterInstance::ComputeNeededBoxes()
|
|||
// In the end, we need whatever the final filter primitive will draw that
|
||||
// intersects the destination dirty area.
|
||||
mPrimitives[mPrimitives.Length() - 1].mResultNeededBox.IntersectRect(
|
||||
mPrimitives[mPrimitives.Length() - 1].mResultBoundingBox, mDirtyOutputRect);
|
||||
mPrimitives[mPrimitives.Length() - 1].mResultBoundingBox, mPostFilterDirtyRect);
|
||||
|
||||
for (PRInt32 i = mPrimitives.Length() - 1; i >= 0; --i) {
|
||||
PrimitiveInfo* info = &mPrimitives[i];
|
||||
|
@ -522,9 +522,9 @@ nsSVGFilterInstance::Render(gfxASurface** aOutput)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsSVGFilterInstance::ComputeOutputDirtyRect(nsIntRect* aDirty)
|
||||
nsSVGFilterInstance::ComputePostFilterDirtyRect(nsIntRect* aPostFilterDirtyRect)
|
||||
{
|
||||
*aDirty = nsIntRect();
|
||||
*aPostFilterDirtyRect = nsIntRect();
|
||||
|
||||
nsresult rv = BuildSources();
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -541,12 +541,12 @@ nsSVGFilterInstance::ComputeOutputDirtyRect(nsIntRect* aDirty)
|
|||
|
||||
ComputeResultBoundingBoxes();
|
||||
|
||||
mSourceColorAlpha.mResultChangeBox = mDirtyInputRect;
|
||||
mSourceAlpha.mResultChangeBox = mDirtyInputRect;
|
||||
mSourceColorAlpha.mResultChangeBox = mPreFilterDirtyRect;
|
||||
mSourceAlpha.mResultChangeBox = mPreFilterDirtyRect;
|
||||
ComputeResultChangeBoxes();
|
||||
|
||||
PrimitiveInfo* result = &mPrimitives[mPrimitives.Length() - 1];
|
||||
*aDirty = result->mResultChangeBox;
|
||||
*aPostFilterDirtyRect = result->mResultChangeBox;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,13 @@ class nsSVGFilterPaintCallback;
|
|||
*
|
||||
* Definition of "filter space": filter space is a coordinate system that is
|
||||
* aligned with the user space of the filtered element, with its origin located
|
||||
* at the top left of the filter region (as returned by GetFilterRect,
|
||||
* specifically), and with one unit equal in size to one pixel of the offscreen
|
||||
* surface into which the filter output would/will be painted.
|
||||
* at the top left of the filter region (as specified by our ctor's
|
||||
* aFilterRegion, and returned by our GetFilterRegion, specifically), and with
|
||||
* one unit equal in size to one pixel of the offscreen surface into which the
|
||||
* filter output would/will be painted.
|
||||
*
|
||||
* The definition of "filter region" can be found here:
|
||||
* http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
|
||||
*/
|
||||
class NS_STACK_CLASS nsSVGFilterInstance
|
||||
{
|
||||
|
@ -49,7 +53,7 @@ public:
|
|||
* element.
|
||||
* @param aTargetBBox The filtered element's bbox, in the filtered element's
|
||||
* user space.
|
||||
* @param aFilterRect The "filter region", in the filtered element's user
|
||||
* @param aFilterRegion The "filter region", in the filtered element's user
|
||||
* space. The caller must have already expanded the region out so that its
|
||||
* edges coincide with pixel boundaries in the offscreen surface that
|
||||
* would/will be created to paint the filter output.
|
||||
|
@ -59,36 +63,36 @@ public:
|
|||
* space to outer-<svg> device space.
|
||||
* @param aTargetBounds The pre-filter paint bounds of the filtered element,
|
||||
* in filter space.
|
||||
* @param aDirtyOutputRect [optional] The bounds of the post-filter area that
|
||||
* has to be repainted, in filter space. Only required if you will call
|
||||
* ComputeSourceNeededRect() or Render().
|
||||
* @param aDirtyInputRect [optional] The bounds of the pre-filter area of the
|
||||
* filtered element that changed, in filter space. Only required if you
|
||||
* will call ComputeOutputDirtyRect().
|
||||
* @param aPostFilterDirtyRect [optional] The bounds of the post-filter area
|
||||
* that has to be repainted, in filter space. Only required if you will
|
||||
* call ComputeSourceNeededRect() or Render().
|
||||
* @param aPreFilterDirtyRect [optional] The bounds of the pre-filter area of
|
||||
* the filtered element that changed, in filter space. Only required if you
|
||||
* will call ComputePostFilterDirtyRect().
|
||||
* @param aPrimitiveUnits The value from the 'primitiveUnits' attribute.
|
||||
*/
|
||||
nsSVGFilterInstance(nsIFrame *aTargetFrame,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsSVGFilterElement *aFilterElement,
|
||||
const gfxRect &aTargetBBox,
|
||||
const gfxRect& aFilterRect,
|
||||
const gfxRect& aFilterRegion,
|
||||
const nsIntSize& aFilterSpaceSize,
|
||||
const gfxMatrix &aFilterSpaceToDeviceSpaceTransform,
|
||||
const nsIntRect& aTargetBounds,
|
||||
const nsIntRect& aDirtyOutputRect,
|
||||
const nsIntRect& aDirtyInputRect,
|
||||
const nsIntRect& aPostFilterDirtyRect,
|
||||
const nsIntRect& aPreFilterDirtyRect,
|
||||
PRUint16 aPrimitiveUnits) :
|
||||
mTargetFrame(aTargetFrame),
|
||||
mPaintCallback(aPaintCallback),
|
||||
mFilterElement(aFilterElement),
|
||||
mTargetBBox(aTargetBBox),
|
||||
mFilterSpaceToDeviceSpaceTransform(aFilterSpaceToDeviceSpaceTransform),
|
||||
mFilterRect(aFilterRect),
|
||||
mFilterRegion(aFilterRegion),
|
||||
mFilterSpaceSize(aFilterSpaceSize),
|
||||
mSurfaceRect(nsIntPoint(0, 0), aFilterSpaceSize),
|
||||
mTargetBounds(aTargetBounds),
|
||||
mDirtyOutputRect(aDirtyOutputRect),
|
||||
mDirtyInputRect(aDirtyInputRect),
|
||||
mPostFilterDirtyRect(aPostFilterDirtyRect),
|
||||
mPreFilterDirtyRect(aPreFilterDirtyRect),
|
||||
mPrimitiveUnits(aPrimitiveUnits) {
|
||||
}
|
||||
|
||||
|
@ -98,7 +102,7 @@ public:
|
|||
* coincide with pixel boundaries of the offscreen surface into which the
|
||||
* filtered output would/will be painted.
|
||||
*/
|
||||
gfxRect GetFilterRect() const { return mFilterRect; }
|
||||
gfxRect GetFilterRegion() const { return mFilterRegion; }
|
||||
|
||||
/**
|
||||
* Returns the size of the user specified "filter region", in filter space.
|
||||
|
@ -126,25 +130,25 @@ public:
|
|||
* Allocates a gfxASurface, renders the filtered element into the surface,
|
||||
* and then returns the surface via the aOutput outparam. The area that
|
||||
* needs to be painted must have been specified before calling this method
|
||||
* by passing it as the aDirtyOutputRect argument to the
|
||||
* by passing it as the aPostFilterDirtyRect argument to the
|
||||
* nsSVGFilterInstance constructor.
|
||||
*/
|
||||
nsresult Render(gfxASurface** aOutput);
|
||||
|
||||
/**
|
||||
* Sets the aDirty outparam to the post-filter bounds in filter space of the
|
||||
* area that would be dirtied by mTargetFrame when a given pre-filter area of
|
||||
* mTargetFrame is dirtied. The pre-filter area must have been specified
|
||||
* before calling this method by passing it as the aDirtyInputRect argument
|
||||
* to the nsSVGFilterInstance constructor.
|
||||
* Sets the aPostFilterDirtyRect outparam to the post-filter bounds in filter
|
||||
* space of the area that would be dirtied by mTargetFrame when a given
|
||||
* pre-filter area of mTargetFrame is dirtied. The pre-filter area must have
|
||||
* been specified before calling this method by passing it as the
|
||||
* aPreFilterDirtyRect argument to the nsSVGFilterInstance constructor.
|
||||
*/
|
||||
nsresult ComputeOutputDirtyRect(nsIntRect* aDirty);
|
||||
nsresult ComputePostFilterDirtyRect(nsIntRect* aPostFilterDirtyRect);
|
||||
|
||||
/**
|
||||
* Sets the aDirty outparam to the pre-filter bounds in filter space of the
|
||||
* area of mTargetFrame that is needed in order to paint the filtered output
|
||||
* for a given post-filter dirtied area. The post-filter area must have been
|
||||
* specified before calling this method by passing it as the aDirtyOutputRect
|
||||
* specified before calling this method by passing it as the aPostFilterDirtyRect
|
||||
* argument to the nsSVGFilterInstance constructor.
|
||||
*/
|
||||
nsresult ComputeSourceNeededRect(nsIntRect* aDirty);
|
||||
|
@ -290,14 +294,14 @@ private:
|
|||
|
||||
/**
|
||||
* Computes the filter space bounds of the areas that we actually *need* from
|
||||
* each filter primitive's output, based on the value of mDirtyOutputRect.
|
||||
* each filter primitive's output, based on the value of mPostFilterDirtyRect.
|
||||
* This sets mResultNeededBox on the items in the filter graph.
|
||||
*/
|
||||
void ComputeNeededBoxes();
|
||||
|
||||
/**
|
||||
* Computes the filter space bounds of the area of each filter primitive
|
||||
* that will change, based on the value of mDirtyInputRect.
|
||||
* that will change, based on the value of mPreFilterDirtyRect.
|
||||
* This sets mResultChangeBox on the items in the filter graph.
|
||||
*/
|
||||
void ComputeResultChangeBoxes();
|
||||
|
@ -360,7 +364,7 @@ private:
|
|||
gfxRect mTargetBBox;
|
||||
|
||||
gfxMatrix mFilterSpaceToDeviceSpaceTransform;
|
||||
gfxRect mFilterRect;
|
||||
gfxRect mFilterRegion;
|
||||
nsIntSize mFilterSpaceSize;
|
||||
nsIntRect mSurfaceRect;
|
||||
|
||||
|
@ -375,7 +379,7 @@ private:
|
|||
* bounds of the dirty area that needs to be repainted. (As bounds-of-bounds,
|
||||
* this may be a fair bit bigger than we actually need, unfortunately.)
|
||||
*/
|
||||
nsIntRect mDirtyOutputRect;
|
||||
nsIntRect mPostFilterDirtyRect;
|
||||
|
||||
/**
|
||||
* If set, this is the filter space bounds of the outer-<svg> device bounds
|
||||
|
@ -383,7 +387,7 @@ private:
|
|||
* bounds-of-bounds, this may be a fair bit bigger than we actually need,
|
||||
* unfortunately.)
|
||||
*/
|
||||
nsIntRect mDirtyInputRect;
|
||||
nsIntRect mPreFilterDirtyRect;
|
||||
|
||||
/**
|
||||
* The 'primitiveUnits' attribute value (objectBoundingBox or userSpaceOnUse).
|
||||
|
|
|
@ -100,7 +100,7 @@ nsSVGIntegrationUtils::ComputeFrameEffectsRect(nsIFrame* aFrame,
|
|||
// r is relative to user space
|
||||
PRUint32 appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
nsIntRect p = r.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
p = filterFrame->GetFilterBBox(firstFrame, &p);
|
||||
p = filterFrame->GetPostFilterBounds(firstFrame, &p);
|
||||
r = p.ToAppUnits(appUnitsPerDevPixel);
|
||||
// Make it relative to aFrame again
|
||||
return r + userSpaceRect.TopLeft() - aFrame->GetOffsetTo(firstFrame);
|
||||
|
@ -137,7 +137,7 @@ nsSVGIntegrationUtils::GetInvalidAreaForChangedSource(nsIFrame* aFrame,
|
|||
nsPoint offset = aFrame->GetOffsetTo(firstFrame) - userSpaceRect.TopLeft();
|
||||
nsRect r = aInvalidRect + offset;
|
||||
nsIntRect p = r.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
p = filterFrame->GetInvalidationBBox(firstFrame, p);
|
||||
p = filterFrame->GetPostFilterDirtyArea(firstFrame, p);
|
||||
r = p.ToAppUnits(appUnitsPerDevPixel);
|
||||
return r - offset;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(nsIFrame* aFrame,
|
|||
nsPoint offset = aFrame->GetOffsetTo(firstFrame) - userSpaceRect.TopLeft();
|
||||
nsRect r = aDamageRect + offset;
|
||||
nsIntRect p = r.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
p = filterFrame->GetSourceForInvalidArea(firstFrame, p);
|
||||
p = filterFrame->GetPreFilterNeededArea(firstFrame, p);
|
||||
r = p.ToAppUnits(appUnitsPerDevPixel);
|
||||
return r - offset;
|
||||
}
|
||||
|
@ -279,10 +279,11 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsRenderingContext* aCtx,
|
|||
|
||||
/* Paint the child */
|
||||
if (filterFrame) {
|
||||
RegularFramePaintCallback paint(aBuilder, aInnerList, aEffectsFrame,
|
||||
userSpaceRect.TopLeft());
|
||||
nsIntRect r = (aDirtyRect - userSpaceRect.TopLeft()).ToOutsidePixels(appUnitsPerDevPixel);
|
||||
filterFrame->FilterPaint(aCtx, aEffectsFrame, &paint, &r);
|
||||
RegularFramePaintCallback callback(aBuilder, aInnerList, aEffectsFrame,
|
||||
userSpaceRect.TopLeft());
|
||||
nsIntRect dirtyRect = (aDirtyRect - userSpaceRect.TopLeft())
|
||||
.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
filterFrame->PaintFilteredFrame(aCtx, aEffectsFrame, &callback, &dirtyRect);
|
||||
} else {
|
||||
gfx->SetMatrix(matrixAutoSaveRestore.Matrix());
|
||||
aInnerList->PaintForFrame(aBuilder, aCtx, aEffectsFrame,
|
||||
|
|
|
@ -580,20 +580,20 @@ nsSVGUtils::GetNearestSVGViewport(nsIFrame *aFrame)
|
|||
|
||||
nsRect
|
||||
nsSVGUtils::GetPostFilterVisualOverflowRect(nsIFrame *aFrame,
|
||||
const nsRect &aUnfilteredRect)
|
||||
const nsRect &aPreFilterRect)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT,
|
||||
"Called on invalid frame type");
|
||||
|
||||
nsSVGFilterFrame *filter = nsSVGEffects::GetFilterFrame(aFrame);
|
||||
if (!filter) {
|
||||
return aUnfilteredRect;
|
||||
return aPreFilterRect;
|
||||
}
|
||||
|
||||
PRInt32 appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
nsIntRect unfilteredRect =
|
||||
aUnfilteredRect.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
nsIntRect rect = filter->GetFilterBBox(aFrame, nsnull, &unfilteredRect);
|
||||
nsIntRect preFilterRect =
|
||||
aPreFilterRect.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
nsIntRect rect = filter->GetPostFilterBounds(aFrame, nsnull, &preFilterRect);
|
||||
nsRect r = rect.ToAppUnits(appUnitsPerDevPixel) - aFrame->GetPosition();
|
||||
return r;
|
||||
}
|
||||
|
@ -1240,7 +1240,8 @@ nsSVGUtils::PaintFrameWithEffects(nsRenderingContext *aContext,
|
|||
/* Paint the child */
|
||||
if (filterFrame) {
|
||||
SVGPaintCallback paintCallback;
|
||||
filterFrame->FilterPaint(aContext, aFrame, &paintCallback, aDirtyRect);
|
||||
filterFrame->PaintFilteredFrame(aContext, aFrame, &paintCallback,
|
||||
aDirtyRect);
|
||||
} else {
|
||||
svgChildFrame->PaintSVG(aContext, aDirtyRect);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче