author | Markus Stange <mstange@themasta.com> |
Wed, 23 Apr 2014 11:47:31 +0200 | |
changeset 198243 | 77a55da6682761f7d7284b671f56d9ce2ff7499a |
parent 198242 | f8f94f19e05b9cda0f5c81178094c2f2cc581fc5 |
child 198244 | fcd9986a84c58232fdf6a2f8cb6ee994e5be3612 |
push id | 3624 |
push user | asasaki@mozilla.com |
push date | Mon, 09 Jun 2014 21:49:01 +0000 |
treeherder | mozilla-beta@b1a5da15899a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 997735 |
milestone | 31.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
layout/svg/nsSVGIntegrationUtils.cpp | file | annotate | diff | comparison | revisions | |
layout/svg/nsSVGIntegrationUtils.h | file | annotate | diff | comparison | revisions |
--- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -149,18 +149,20 @@ nsSVGIntegrationUtils::UsingEffectsForFr // Even when SVG display lists are disabled, returning true for SVG frames // does not adversely affect any of our callers. Therefore we don't bother // checking the SDL prefs here, since we don't know if we're being called for // painting or hit-testing anyway. const nsStyleSVGReset *style = aFrame->StyleSVGReset(); return (style->HasFilters() || style->mClipPath || style->mMask); } -/* static */ nsPoint -nsSVGIntegrationUtils::GetOffsetToUserSpace(nsIFrame* aFrame) +// For non-SVG frames, this gives the offset to the frame's "user space". +// For SVG frames, this returns a zero offset. +static nsPoint +GetOffsetToBoundingBox(nsIFrame* aFrame) { if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) { // Do NOT call GetAllInFlowRectsUnion for SVG - it will get the // covered region relative to the nsSVGOuterSVGFrame, which is absolutely // not what we want. SVG frames are always in user space, so they have // no offset adjustment to make. return nsPoint(); } @@ -203,26 +205,26 @@ gfxRect nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame) { NS_ASSERTION(!aNonSVGFrame->IsFrameOfType(nsIFrame::eSVG), "SVG frames should not get here"); nsIFrame* firstFrame = nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame); // 'r' is in "user space": nsRect r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(), - GetOffsetToUserSpace(firstFrame)); + GetOffsetToBoundingBox(firstFrame)); return nsLayoutUtils::RectToGfxRect(r, aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel()); } // XXX Since we're called during reflow, this method is broken for frames with // continuations. When we're called for a frame with continuations, we're // called for each continuation in turn as it's reflowed. However, it isn't // until the last continuation is reflowed that this method's -// GetOffsetToUserSpace() and GetPreEffectsVisualOverflowUnion() calls will +// GetOffsetToBoundingBox() and GetPreEffectsVisualOverflowUnion() calls will // obtain valid border boxes for all the continuations. As a result, we'll // end up returning bogus post-filter visual overflow rects for all the prior // continuations. Unfortunately, by the time the last continuation is // reflowed, it's too late to go back and set and propagate the overflow // rects on the previous continuations. // // The reason that we need to pass an override bbox to // GetPreEffectsVisualOverflowUnion rather than just letting it call into our @@ -257,33 +259,33 @@ nsRect nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame); nsSVGEffects::EffectProperties effectProperties = nsSVGEffects::GetEffectProperties(firstFrame); if (!effectProperties.HasValidFilter()) { return aPreEffectsOverflowRect; } // Create an override bbox - see comment above: - nsPoint firstFrameToUserSpace = GetOffsetToUserSpace(firstFrame); + nsPoint firstFrameToBoundingBox = GetOffsetToBoundingBox(firstFrame); // overrideBBox is in "user space", in _CSS_ pixels: // XXX Why are we rounding out to pixel boundaries? We don't do that in // GetSVGBBoxForNonSVGFrame, and it doesn't appear to be necessary. gfxRect overrideBBox = nsLayoutUtils::RectToGfxRect( GetPreEffectsVisualOverflowUnion(firstFrame, aFrame, aPreEffectsOverflowRect, - firstFrameToUserSpace), + firstFrameToBoundingBox), aFrame->PresContext()->AppUnitsPerCSSPixel()); overrideBBox.RoundOut(); nsRect overflowRect = nsFilterInstance::GetPostFilterBounds(firstFrame, &overrideBBox); // Return overflowRect relative to aFrame, rather than "user space": - return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToUserSpace); + return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToBoundingBox); } nsIntRect nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame, const nsPoint& aToReferenceFrame, const nsIntRect& aInvalidRect) { if (aInvalidRect.IsEmpty()) { @@ -305,28 +307,28 @@ nsSVGIntegrationUtils::AdjustInvalidArea // The frame is either not there or not currently available, // perhaps because we're in the middle of tearing stuff down. // Be conservative, return our visual overflow rect relative // to the reference frame. nsRect overflow = aFrame->GetVisualOverflowRect() + aToReferenceFrame; return overflow.ToOutsidePixels(appUnitsPerDevPixel); } - // Convert aInvalidRect into "user space" in app units: - nsPoint toUserSpace = - aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame); + // Convert aInvalidRect into bounding box frame space in app units: + nsPoint toBoundingBox = + aFrame->GetOffsetTo(firstFrame) + GetOffsetToBoundingBox(firstFrame); // The initial rect was relative to the reference frame, so we need to // remove that offset to get a rect relative to the current frame. - toUserSpace -= aToReferenceFrame; - nsRect preEffectsRect = aInvalidRect.ToAppUnits(appUnitsPerDevPixel) + toUserSpace; + toBoundingBox -= aToReferenceFrame; + nsRect preEffectsRect = aInvalidRect.ToAppUnits(appUnitsPerDevPixel) + toBoundingBox; // Adjust the dirty area for effects, and shift it back to being relative to // the reference frame. nsRect result = nsFilterInstance::GetPostFilterDirtyArea(firstFrame, - preEffectsRect) - toUserSpace; + preEffectsRect) - toBoundingBox; // Return the result, in pixels relative to the reference frame. return result.ToOutsidePixels(appUnitsPerDevPixel); } nsRect nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(nsIFrame* aFrame, const nsRect& aDirtyRect) { @@ -336,36 +338,37 @@ nsSVGIntegrationUtils::GetRequiredSource nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame); nsSVGFilterProperty *prop = nsSVGEffects::GetFilterProperty(firstFrame); if (!prop || !prop->ReferencesValidResources()) { return aDirtyRect; } // Convert aDirtyRect into "user space" in app units: nsPoint toUserSpace = - aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame); + aFrame->GetOffsetTo(firstFrame) + GetOffsetToBoundingBox(firstFrame); nsRect postEffectsRect = aDirtyRect + toUserSpace; // Return ther result, relative to aFrame, not in user space: return nsFilterInstance::GetPreFilterNeededArea(firstFrame, postEffectsRect) - toUserSpace; } bool nsSVGIntegrationUtils::HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt) { nsIFrame* firstFrame = nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame); // Convert aPt to user space: nsPoint toUserSpace; if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) { + // XXXmstange Isn't this wrong for svg:use and innerSVG frames? toUserSpace = aFrame->GetPosition(); } else { toUserSpace = - aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame); + aFrame->GetOffsetTo(firstFrame) + GetOffsetToBoundingBox(firstFrame); } nsPoint pt = aPt + toUserSpace; return nsSVGUtils::HitTestClip(firstFrame, pt); } class RegularFramePaintCallback : public nsSVGFilterPaintCallback { public: @@ -455,17 +458,17 @@ nsSVGIntegrationUtils::PaintFramesWithEf return; // Some resource is missing. We shouldn't paint anything. } bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true; gfxContext* gfx = aCtx->ThebesContext(); gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx); - nsPoint firstFrameOffset = GetOffsetToUserSpace(firstFrame); + nsPoint firstFrameOffset = GetOffsetToBoundingBox(firstFrame); nsPoint offset = aBuilder->ToReferenceFrame(firstFrame) - firstFrameOffset; nsPoint offsetWithoutSVGGeomFramePos; if (firstFrame->IsFrameOfType(nsIFrame::eSVG)) { offsetWithoutSVGGeomFramePos = offset; } else { /* Snap the offset if the reference frame is not a SVG frame, * since other frames will be snapped to pixel when rendering. */ offsetWithoutSVGGeomFramePos = nsPoint( @@ -615,17 +618,17 @@ PaintFrameCallback::operator()(gfxContex aContext->Clip(); aContext->Multiply(gfxMatrix(aTransform).Invert()); // nsLayoutUtils::PaintFrame will anchor its painting at mFrame. But we want // to have it anchored at the top left corner of the bounding box of all of // mFrame's continuations. So we add a translation transform. int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); - nsPoint offset = nsSVGIntegrationUtils::GetOffsetToUserSpace(mFrame); + nsPoint offset = GetOffsetToBoundingBox(mFrame); gfxPoint devPxOffset = gfxPoint(offset.x, offset.y) / appUnitsPerDevPixel; aContext->Multiply(gfxMatrix().Translate(devPxOffset)); gfxSize paintServerSize = gfxSize(mPaintServerSize.width, mPaintServerSize.height) / mFrame->PresContext()->AppUnitsPerDevPixel(); // nsLayoutUtils::PaintFrame wants to render with paintServerSize, but we
--- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -38,43 +38,16 @@ class nsSVGIntegrationUtils MOZ_FINAL public: /** * Returns true if SVG effects are currently applied to this frame. */ static bool UsingEffectsForFrame(const nsIFrame* aFrame); /** - * In SVG, an element's "user space" is simply the coordinate system in place - * at the time that it is drawn. For non-SVG frames, we want any SVG effects - * to be applied to the union of the border-box rects of all of a given - * frame's continuations. This means that, when we paint a non-SVG frame with - * effects, we want to offset the effects by the distance from the frame's - * origin (the top left of its border box) to the top left of the union of - * the border-box rects of all its continuations. In other words, we need to - * apply this offset as a suplimental translation to the current coordinate - * system in order to establish the correct user space before calling into - * the SVG effects code. For the purposes of the nsSVGIntegrationUtils code - * we somewhat misappropriate the term "user space" by using it to refer - * specifically to this adjusted coordinate system. - * - * For consistency with nsIFrame::GetOffsetTo, the offset this method returns - * is the offset you need to add to a point that's relative to aFrame's - * origin (the top left of its border box) to convert it to aFrame's user - * space. In other words the value returned is actually the offset from the - * origin of aFrame's user space to aFrame. - * - * Note: This method currently only accepts a frame's first continuation - * since none of our current callers need to be able to pass in other - * continuations. - */ - static nsPoint - GetOffsetToUserSpace(nsIFrame* aFrame); - - /** * Returns the size of the union of the border-box rects of all of * aNonSVGFrame's continuations. */ static nsSize GetContinuationUnionSize(nsIFrame* aNonSVGFrame); /** * When SVG effects need to resolve percentage, userSpaceOnUse lengths, they