Bug 490003: Take outer <svg> element's border and padding into account, for invalidation and hit-testing. r=roc

This commit is contained in:
Robert Longson 2010-05-12 14:41:47 -07:00
Родитель e60b38ee05
Коммит 560b5f1175
5 изменённых файлов: 84 добавлений и 12 удалений

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

@ -0,0 +1,9 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
style="border: 10px solid lime; padding: 10px; background: lime;">
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=490003 -->
<title>Reference that invalidation takes account of outer-&lt;svg&gt; border/padding</title>
</svg>

После

Ширина:  |  Высота:  |  Размер: 414 B

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

@ -0,0 +1,58 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="reftest-wait"
style="border: 10px solid lime; padding: 10px; background: lime;">
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=490003 -->
<title>Test that invalidation takes account of outer-&lt;svg&gt; border/padding</title>
<desc>
This test checks that SVG implementations take account of border and
padding on outer &lt;svg&gt; when doing invalidation.
</desc>
<filter id="identity">
<feColorMatrix type="saturate" in="SourceGraphic"/>
</filter>
<script type="text/javascript">//<![CDATA[
function hide_red_rects()
{
var background = document.getElementById("background");
document.getElementById('r').setAttribute('opacity','0');
document.getElementById('f').setAttribute('opacity','0');
<!-- top left -->
document.elementFromPoint(121, 121).setAttribute('opacity','0');
<!-- bottom right -->
document.elementFromPoint(269, 169).setAttribute('opacity','0');
<!-- outside top left -->
if (document.elementFromPoint(119, 119) != background) {
background.setAttribute("fill", "red");
}
<!-- outside bottom right -->
if (document.elementFromPoint(271, 171) != background) {
background.setAttribute("fill", "purple");
}
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", hide_red_rects, false);
setTimeout(hide_red_rects, 1000)
//]]>
</script>
<!-- to catch misses-->
<rect id="background" width="100%" height="100%" fill="lime"/>
<rect id="r" width="50" height="50" fill="red"/>
<rect id="f" y="100" width="50" height="50" fill="red"/>
<rect x="100" y="100" width="50" height="50" fill="red"/>
<rect x="200" y="100" width="50" height="50" fill="red"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

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

@ -115,6 +115,7 @@ fails == inline-in-xul-basic-01.xul pass.svg
== opacity-and-gradient-01.svg pass.svg
== opacity-and-gradient-02.svg opacity-and-gradient-02-ref.svg
== opacity-and-pattern-01.svg pass.svg
== outer-svg-border-and-padding-01.svg outer-svg-border-and-padding-01-ref.svg
== polyline-points-invalid-01.svg pass.svg
== path-01.svg path-01-ref.svg
== path-02.svg pass.svg

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

@ -440,16 +440,18 @@ void
nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
{
nsSVGOuterSVGFrame *outerSVGFrame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
nsRect rectAtOrigin = aRect - aBuilder->ToReferenceFrame(mFrame);
nsRect thisRect(nsPoint(0,0), static_cast<nsSVGOuterSVGFrame*>(mFrame)->GetSize());
nsRect thisRect(nsPoint(0,0), outerSVGFrame->GetSize());
if (!thisRect.Intersects(rectAtOrigin))
return;
nsPoint rectCenter(rectAtOrigin.x + rectAtOrigin.width / 2,
rectAtOrigin.y + rectAtOrigin.height / 2);
nsIFrame* frame = nsSVGUtils::HitTestChildren(static_cast<nsSVGOuterSVGFrame*>(mFrame),
rectCenter);
nsIFrame* frame = nsSVGUtils::HitTestChildren(
outerSVGFrame, rectCenter + outerSVGFrame->GetPosition() -
outerSVGFrame->GetContentRect().TopLeft());
if (frame) {
aOutFrames->AppendElement(frame);
}
@ -514,7 +516,8 @@ nsSVGOuterSVGFrame::GetFrameForPoint(const nsPoint& aPoint)
return nsnull;
}
return nsSVGUtils::HitTestChildren(this, aPoint);
return nsSVGUtils::HitTestChildren(
this, aPoint + GetPosition() - GetContentRect().TopLeft());
}
//----------------------------------------------------------------------
@ -538,11 +541,8 @@ nsSVGOuterSVGFrame::Paint(nsIRenderingContext& aRenderingContext,
// initialize Mozilla rendering context
aRenderingContext.PushState();
nsMargin bp = GetUsedBorderAndPadding();
ApplySkipSides(bp);
nsRect viewportRect = GetContentRect();
nsPoint viewportOffset = aPt + nsPoint(bp.left, bp.top);
nsPoint viewportOffset = aPt + viewportRect.TopLeft() - GetPosition();
viewportRect.MoveTo(viewportOffset);
nsRect clipRect;

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

@ -622,9 +622,7 @@ nsSVGUtils::FindFilterInvalidation(nsIFrame *aFrame, const nsRect& aRect)
nsRect r = viewportFrame->GetOverflowRect();
// GetOverflowRect is relative to our border box, but we need it
// relative to our content box.
nsMargin bp = viewportFrame->GetUsedBorderAndPadding();
viewportFrame->ApplySkipSides(bp);
r.MoveBy(-bp.left, -bp.top);
r.MoveBy(viewportFrame->GetPosition() - viewportFrame->GetContentRect().TopLeft());
return r;
}
NS_ASSERTION(viewportFrame->GetType() == nsGkAtoms::svgInnerSVGFrame,
@ -648,7 +646,13 @@ nsSVGUtils::FindFilterInvalidation(nsIFrame *aFrame, const nsRect& aRect)
aFrame = aFrame->GetParent();
}
return rect.ToAppUnits(appUnitsPerDevPixel);
nsRect r = rect.ToAppUnits(appUnitsPerDevPixel);
if (aFrame) {
NS_ASSERTION(aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG,
"outer SVG frame expected");
r.MoveBy(aFrame->GetContentRect().TopLeft() - aFrame->GetPosition());
}
return r;
}
void