Bug 1042860 - Handle animated attribute changes on descendants of SVG <text> elements. r=dholbert

This commit is contained in:
Cameron McCormack 2014-09-08 12:34:20 +10:00
Родитель 5d6dcd5866
Коммит 424406e1b8
10 изменённых файлов: 220 добавлений и 5 удалений

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

@ -18,6 +18,7 @@
#include "RestyleManager.h"
#include "nsDisplayList.h"
#include "mozilla/Likely.h"
#include "SVGTextFrame.h"
#ifdef DEBUG
#undef NOISY_PUSHING
@ -426,6 +427,28 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
}
nsresult
nsInlineFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
{
nsresult rv =
nsInlineFrameBase::AttributeChanged(aNameSpaceID, aAttribute, aModType);
if (NS_FAILED(rv)) {
return rv;
}
if (IsSVGText()) {
SVGTextFrame* f = static_cast<SVGTextFrame*>(
nsLayoutUtils::GetClosestFrameOfType(this, nsGkAtoms::svgTextFrame));
f->HandleAttributeChangeInDescendant(mContent->AsElement(),
aNameSpaceID, aAttribute);
}
return NS_OK;
}
bool
nsInlineFrame::DrainSelfOverflowListInternal(DrainFlags aFlags,
nsIFrame* aLineContainer)

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

@ -85,6 +85,10 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus) MOZ_OVERRIDE;
virtual nsresult AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType) MOZ_OVERRIDE;
virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
virtual void PullOverflowsFromPrevInFlow() MOZ_OVERRIDE;

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

@ -0,0 +1,31 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
style="font: 16px sans-serif">
<title>Reference for modifying attributes on child text content elements</title>
<text x="200" y="20">Test 1</text>
<text x="20" y="60">Test 2</text>
<text x="20" y="80" rotate="10">Test 3</text>
<text>
<tspan x="200" y="100">Test 4</tspan>
</text>
<text>
<tspan x="20" y="140">Test 5</tspan>
</text>
<text>
<tspan x="20" y="160" rotate="30">Test 6</tspan>
</text>
<path id="p" d="M 20,180 h 400"/>
<text>
<textPath xlink:href="#p" startOffset="180">Test 7</textPath>
</text>
<text x="20" y="200" textLength="100" lengthAdjust="spacingAndGlyphs">Test 8</text>
<text>
<tspan x="20" y="220" textLength="100" lengthAdjust="spacingAndGlyphs">Test 9</tspan>
</text>
</svg>

После

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

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

@ -0,0 +1,46 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
style="font: 16px sans-serif">
<title>Testcase for modifying attributes on child text content elements</title>
<text x="20" y="20" data-test="x=200">Test 1</text>
<text x="20" y="40" data-test="y=60">Test 2</text>
<text x="20" y="80" data-test="rotate=10">Test 3</text>
<text>
<tspan x="20" y="100" data-test="x=200">Test 4</tspan>
</text>
<text>
<tspan x="20" y="120" data-test="y=140">Test 5</tspan>
</text>
<text>
<tspan x="20" y="160" data-test="rotate=30">Test 6</tspan>
</text>
<path id="p" d="M 20,180 h 400"/>
<text>
<textPath xlink:href="#p" data-test="startOffset=180">Test 7</textPath>
</text>
<text x="20" y="200" textLength="100" lengthAdjust="spacing" data-test="lengthAdjust=spacingAndGlyphs">Test 8</text>
<!-- We don't support textLength/lengthAdjust on child text content
elements currently (bug 890692), so Test 9 doesn't really test
anything at the moment. But it is the only animatable enumerated
attribute value on text content elements to test. -->
<text>
<tspan x="20" y="220" textLength="100" lengthAdjust="spacing" data-test="lengthAdjust=spacingAndGlyphs">Test 9</tspan>
</text>
<script>
window.addEventListener("MozReftestInvalidate", function() {
[...document.querySelectorAll("[data-test]")].forEach(function(e) {
var [name, value] = e.getAttribute("data-test").split("=");
e.setAttribute(name, value);
});
document.documentElement.removeAttribute("class");
}, false);
</script>
</svg>

После

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

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

@ -115,6 +115,7 @@ random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) fuzzy-if(/^Windows\x20NT\x2
== dynamic-text-06.svg pass.svg
== dynamic-text-07.svg dynamic-text-07-ref.svg
== dynamic-text-08.svg dynamic-text-08-ref.svg
== dynamic-text-attr-01.svg dynamic-text-attr-01-ref.svg
== dynamic-textPath-01.svg dynamic-textPath-01-ref.svg
== dynamic-textPath-02.svg dynamic-textPath-02-ref.svg
== dynamic-textPath-03.svg dynamic-textPath-03-ref.svg

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

@ -0,0 +1,31 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
style="font: 16px sans-serif">
<title>Reference for animating attributes on child text content elements</title>
<text x="200" y="20">Test 1</text>
<text x="20" y="60">Test 2</text>
<text x="20" y="80" rotate="10">Test 3</text>
<text>
<tspan x="200" y="100">Test 4</tspan>
</text>
<text>
<tspan x="20" y="140">Test 5</tspan>
</text>
<text>
<tspan x="20" y="160" rotate="30">Test 6</tspan>
</text>
<path id="p" d="M 20,180 h 400"/>
<text>
<textPath xlink:href="#p" startOffset="180">Test 7</textPath>
</text>
<text x="20" y="200" textLength="100" lengthAdjust="spacingAndGlyphs">Test 8</text>
<text>
<tspan x="20" y="220" textLength="100" lengthAdjust="spacingAndGlyphs">Test 9</tspan>
</text>
</svg>

После

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

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

@ -0,0 +1,61 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
style="font: 16px sans-serif">
<title>Testcase for animating attributes on child text content elements</title>
<text x="20" y="20">Test 1
<set attributeName="x" to="200" begin="indefinite"/>
</text>
<text x="20" y="40">Test 2
<set attributeName="y" to="60" begin="indefinite"/>
</text>
<text x="20" y="80">Test 3
<set attributeName="rotate" to="10" begin="indefinite"/>
</text>
<text>
<tspan x="20" y="100">Test 4
<set attributeName="x" to="200" begin="indefinite"/>
</tspan>
</text>
<text>
<tspan x="20" y="120">Test 5
<set attributeName="y" to="140" begin="indefinite"/>
</tspan>
</text>
<text>
<tspan x="20" y="160">Test 6
<set attributeName="rotate" to="30" begin="indefinite"/>
</tspan>
</text>
<path id="p" d="M 20,180 h 400"/>
<text>
<textPath xlink:href="#p">Test 7
<set attributeName="startOffset" to="180" begin="indefinite"/>
</textPath>
</text>
<text x="20" y="200" textLength="100" lengthAdjust="spacing">Test 8
<set attributeName="lengthAdjust" to="spacingAndGlyphs" begin="indefinite"/>
</text>
<!-- We don't support textLength/lengthAdjust on child text content
elements currently (bug 890692), so Test 9 doesn't really test
anything at the moment. But it is the only animatable enumerated
attribute value on text content elements to test. -->
<text>
<tspan x="20" y="220" textLength="100" lengthAdjust="spacing">Test 9
<set attributeName="lengthAdjust" to="spacingAndGlyphs" begin="indefinite"/>
</tspan>
</text>
<script>
window.addEventListener("MozReftestInvalidate", function() {
[...document.querySelectorAll("set")].forEach((e) => e.beginElement());
document.documentElement.removeAttribute("class");
}, false);
</script>
</svg>

После

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

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

@ -162,6 +162,9 @@ fuzzy-if(Android,4,1) == anim-svg-viewBox-01.svg lime.svg
# animate with some paint server values
== anim-paintserver-1.svg anim-paintserver-1-ref.svg
# animate attributes on text content children
== anim-text-attr-01.svg anim-text-attr-01-ref.svg
# animate where the base value is non-interpolatable but will be replaced anyway
== anim-fill-overpaintserver-1.svg lime.svg
== anim-fill-overpaintserver-2.svg lime.svg

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

@ -3388,30 +3388,37 @@ SVGTextFrame::MutationObserver::AttributeChanged(
return;
}
// Attribute changes on this element are handled in
// Attribute changes on this element will be handled by
// SVGTextFrame::AttributeChanged.
if (aElement == mFrame->GetContent()) {
return;
}
// Attributes changes on descendent elements.
mFrame->HandleAttributeChangeInDescendant(aElement, aNameSpaceID, aAttribute);
}
void
SVGTextFrame::HandleAttributeChangeInDescendant(Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute)
{
if (aElement->Tag() == nsGkAtoms::textPath) {
if (aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::startOffset) {
mFrame->NotifyGlyphMetricsChange();
NotifyGlyphMetricsChange();
} else if (aNameSpaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any
nsIFrame* childElementFrame = aElement->GetPrimaryFrame();
if (childElementFrame) {
childElementFrame->Properties().Delete(nsSVGEffects::HrefProperty());
mFrame->NotifyGlyphMetricsChange();
NotifyGlyphMetricsChange();
}
}
} else {
if (aNameSpaceID == kNameSpaceID_None &&
IsGlyphPositioningAttribute(aAttribute)) {
mFrame->NotifyGlyphMetricsChange();
NotifyGlyphMetricsChange();
}
}
}

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

@ -349,6 +349,14 @@ public:
// SVGTextFrame methods:
/**
* Handles a base or animated attribute value change to a descendant
* text content element.
*/
void HandleAttributeChangeInDescendant(mozilla::dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute);
/**
* Schedules mPositions to be recomputed and the covered region to be
* updated.