https://bugs.webkit.org/show_bug.cgi?id=75091
Patch by Philip Rogers <pdr@google.com> on 2012-02-23
Reviewed by Nikolas Zimmermann.
Source/WebCore:
SVG text metrics depend on the transform from renderer to the svg root
which requires that we propagate transform changes down to text.
This change adds a boolean for tracking transform changes to
SVGViewportContainers and SVGTransformableContainers, and updates
RenderSVGText::layout() to recalculate text metrics if the transform
of an ancestor has changed.
Tests: platform/mac/svg/text/text-rescale.html
platform/mac/svg/text/text-viewbox-rescale.html
svg/text/text-rescale.html
svg/text/text-viewbox-rescale.html
* rendering/RenderObject.h:
(WebCore::RenderObject::isSVGTransformableContainer):
(WebCore::RenderObject::isSVGViewportContainer):
* rendering/svg/RenderSVGContainer.h:
(WebCore::RenderSVGContainer::didTransformToRootUpdate):
* rendering/svg/RenderSVGInlineText.cpp:
(WebCore::RenderSVGInlineText::computeNewScaledFontForStyle):
* rendering/svg/RenderSVGText.cpp:
(WebCore::RenderSVGText::RenderSVGText):
(WebCore::RenderSVGText::layout):
* rendering/svg/RenderSVGText.h:
(WebCore::RenderSVGText::setNeedsTextMetricsUpdate):
(RenderSVGText):
* rendering/svg/RenderSVGTransformableContainer.cpp:
(WebCore::RenderSVGTransformableContainer::RenderSVGTransformableContainer):
(WebCore::RenderSVGTransformableContainer::calculateLocalTransform):
* rendering/svg/RenderSVGTransformableContainer.h:
(WebCore::RenderSVGTransformableContainer::isSVGTransformableContainer):
(WebCore::RenderSVGTransformableContainer::didTransformToRootUpdate):
(RenderSVGTransformableContainer):
* rendering/svg/RenderSVGViewportContainer.cpp:
(WebCore::RenderSVGViewportContainer::RenderSVGViewportContainer):
(WebCore::RenderSVGViewportContainer::calcViewport):
* rendering/svg/RenderSVGViewportContainer.h:
(WebCore::RenderSVGViewportContainer::didTransformToRootUpdate):
(RenderSVGViewportContainer):
* rendering/svg/SVGRenderSupport.cpp:
(WebCore::SVGRenderSupport::transformToRootChanged):
(WebCore):
(WebCore::SVGRenderSupport::layoutChildren):
* rendering/svg/SVGRenderSupport.h:
(SVGRenderSupport):
LayoutTests:
* platform/chromium-linux/svg/text/text-rescale-expected.png: Added.
* platform/chromium-linux/svg/text/text-rescale-expected.txt: Added.
* platform/chromium-linux/svg/text/text-viewbox-rescale-expected.png: Added.
* platform/chromium-linux/svg/text/text-viewbox-rescale-expected.txt: Added.
* platform/chromium/test_expectations.txt:
* platform/mac/svg/text/text-rescale-expected.png: Added.
* platform/mac/svg/text/text-rescale-expected.txt: Added.
* platform/mac/svg/text/text-rescale.html: Added.
* platform/mac/svg/text/text-viewbox-rescale-expected.png: Added.
* platform/mac/svg/text/text-viewbox-rescale-expected.txt: Added.
* platform/mac/svg/text/text-viewbox-rescale.html: Added.
* svg/text/text-rescale-expected.png: Added.
* svg/text/text-rescale-expected.txt: Added.
* svg/text/text-rescale.html: Added.
* svg/text/text-viewbox-rescale-expected.png: Added.
* svg/text/text-viewbox-rescale-expected.txt: Added.
* svg/text/text-viewbox-rescale.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@108699
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-02-23 Philip Rogers <pdr@google.com>
+
+ Recompute font metrics on scale changes
+ https://bugs.webkit.org/show_bug.cgi?id=75091
+
+ Reviewed by Nikolas Zimmermann.
+
+ * platform/chromium-linux/svg/text/text-rescale-expected.png: Added.
+ * platform/chromium-linux/svg/text/text-rescale-expected.txt: Added.
+ * platform/chromium-linux/svg/text/text-viewbox-rescale-expected.png: Added.
+ * platform/chromium-linux/svg/text/text-viewbox-rescale-expected.txt: Added.
+ * platform/chromium/test_expectations.txt:
+ * platform/mac/svg/text/text-rescale-expected.png: Added.
+ * platform/mac/svg/text/text-rescale-expected.txt: Added.
+ * platform/mac/svg/text/text-rescale.html: Added.
+ * platform/mac/svg/text/text-viewbox-rescale-expected.png: Added.
+ * platform/mac/svg/text/text-viewbox-rescale-expected.txt: Added.
+ * platform/mac/svg/text/text-viewbox-rescale.html: Added.
+ * svg/text/text-rescale-expected.png: Added.
+ * svg/text/text-rescale-expected.txt: Added.
+ * svg/text/text-rescale.html: Added.
+ * svg/text/text-viewbox-rescale-expected.png: Added.
+ * svg/text/text-viewbox-rescale-expected.txt: Added.
+ * svg/text/text-viewbox-rescale.html: Added.
+
2012-02-23 Adrienne Walker <enne@google.com>
[chromium] Unreviewed gardening. Re-enable a handful of tests.
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+layer at (0,0) size 500x200
+ RenderSVGRoot {svg} at (0,13) size 405x187
+ RenderSVGContainer {g} at (0,13) size 405x100
+ RenderSVGText {text} at (0,14) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,50.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,50.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,13) size 100x100
+ RenderBlock {P} at (0,0) size 100x48 [color=#008800]
+ RenderText {#text} at (0,1) size 95x46
+ text run at (0,1) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,14) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGContainer {g} at (0,63) size 405x100
+ RenderSVGText {text} at (0,64) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,100.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,100.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,63) size 100x100
+ RenderBlock {P} at (0,0) size 100x48 [color=#008800]
+ RenderText {#text} at (0,1) size 95x46
+ text run at (0,1) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,64) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGContainer {g} at (0,113) size 405x87
+ RenderSVGText {text} at (0,114) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,150.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,150.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,113) size 100x100
+ RenderBlock {P} at (0,0) size 100x48 [color=#008800]
+ RenderText {#text} at (0,1) size 95x46
+ text run at (0,1) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,114) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+layer at (0,0) size 200x200
+ RenderSVGRoot {svg} at (0,0) size 200x200
+ RenderSVGViewportContainer {svg} at (0,0) size 200x200
+ RenderSVGText {text} at (0,0) size 1x1 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.30,0.30) startOffset 0 endOffset 5 width 0.26: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 1x1
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.56,0.30) startOffset 0 endOffset 4 width 0.24: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGViewportContainer {svg} at (0,100) size 200x100
+ RenderSVGText {text} at (0,0) size 1x1 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.30,0.30) startOffset 0 endOffset 5 width 0.26: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 1x1
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.56,0.30) startOffset 0 endOffset 4 width 0.24: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
// Failing after test was updated in r108387, media engine sending incorrect referrer?
BUGWK79239 : http/tests/media/video-referer.html = FAIL
+// Need rebaselining after bug 75091
+BUGWK75091 SKIP : svg/carto.net/tabgroup.svg = FAIL
+BUGWK75091 SKIP : svg/carto.net/window.svg = FAIL
+BUGWK75091 SKIP : svg/custom/js-late-clipPath-and-object-creation.svg = FAIL
+BUGWK75091 SKIP : svg/custom/js-late-gradient-and-object-creation.svg = FAIL
+BUGWK75091 SKIP : svg/custom/js-late-pattern-and-object-creation.svg = FAIL
+BUGWK75091 SKIP : svg/custom/text-ctm.svg = FAIL
+BUGWK75091 SKIP : svg/custom/use-detach.svg = FAIL
+BUGWK75091 SKIP : svg/hixie/perf/003.xml = FAIL
+
// Asserting in debug builds since r108506
BUGWK79229 WIN LINUX DEBUG : http/tests/inspector/console-xhr-logging-async.html = CRASH
BUGWK79229 MAC DEBUG : http/tests/inspector/console-xhr-logging-async.html = TIMEOUT
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+layer at (0,0) size 500x200
+ RenderSVGRoot {svg} at (0,13) size 405x187
+ RenderSVGContainer {g} at (0,13) size 405x100
+ RenderSVGText {text} at (0,14) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,50.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,50.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,13) size 100x100
+ RenderBlock {P} at (0,0) size 100x46 [color=#008800]
+ RenderText {#text} at (0,0) size 95x46
+ text run at (0,0) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,14) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGContainer {g} at (0,63) size 405x100
+ RenderSVGText {text} at (0,64) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,100.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,100.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,63) size 100x100
+ RenderBlock {P} at (0,0) size 100x46 [color=#008800]
+ RenderText {#text} at (0,0) size 95x46
+ text run at (0,0) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,64) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGContainer {g} at (0,113) size 405x87
+ RenderSVGText {text} at (0,114) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,150.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,150.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,113) size 100x100
+ RenderBlock {P} at (0,0) size 100x46 [color=#008800]
+ RenderText {#text} at (0,0) size 95x46
+ text run at (0,0) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,114) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
--- /dev/null
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- Test that a script can change the scale of text from very small to something visible -->
+<!-- see: https://bugs.webkit.org/show_bug.cgi?id=75091 -->
+<!-- If this test passes there should be 3 rows and 4 columns of "PASS" -->
+<script src="../../fast/repaint/resources/repaint.js"></script>
+</head>
+<body onload="runRepaintTest()">
+<svg style="position: absolute; top: 0px; left: 0px; width: 500px; height: 200px">
+ <g id="text1g" transform="scale(0.001)">
+ <text x="0" y="50" font-size="40" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ <foreignObject x="210" y="13" width="100" height="100">
+ <body><p style="font-size: 40px; color: #080;">PASS</p></body>
+ </foreignObject>
+ <svg x="310" y="13" width="100" height="100">
+ <text x="0" y="37" font-size="40" fill="#080">PASS</text>
+ </svg>
+ </g>
+ <g id="text2g" transform="scale(1)">
+ <text x="0" y="100" font-size="40" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ <foreignObject x="210" y="63" width="100" height="100">
+ <body><p style="font-size: 40px; color: #080;">PASS</p></body>
+ </foreignObject>
+ <svg x="310" y="63" width="100" height="100">
+ <text x="0" y="37" font-size="40" fill="#080">PASS</text>
+ </svg>
+ </g>
+ <g id="text3g" transform="scale(0.03)">
+ <text x="0" y="150" font-size="40" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ <foreignObject x="210" y="113" width="100" height="100">
+ <body><p style="font-size: 40px; color: #080;">PASS</p></body>
+ </foreignObject>
+ <svg x="310" y="113" width="100" height="100">
+ <text x="0" y="37" font-size="40" fill="#080">PASS</text>
+ </svg>
+ </g>
+</svg>
+<script>
+ function repaintTest() {
+ document.getElementById("text1g").setAttribute('transform', 'scale(1)');
+ document.getElementById("text2g").setAttribute('transform', 'scale(1)');
+ document.getElementById("text3g").setAttribute('transform', 'scale(1)');
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+layer at (0,0) size 200x200
+ RenderSVGRoot {svg} at (0,0) size 200x200
+ RenderSVGViewportContainer {svg} at (0,0) size 200x200
+ RenderSVGText {text} at (0,0) size 1x1 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.30,0.30) startOffset 0 endOffset 5 width 0.26: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 1x1
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.56,0.30) startOffset 0 endOffset 4 width 0.24: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGViewportContainer {svg} at (0,100) size 200x100
+ RenderSVGText {text} at (0,0) size 1x1 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.30,0.30) startOffset 0 endOffset 5 width 0.26: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 1x1
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.56,0.30) startOffset 0 endOffset 4 width 0.24: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
--- /dev/null
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- Test that a script can change the scale of an svg viewbox and text will be rescaled properly -->
+<!-- see: https://bugs.webkit.org/show_bug.cgi?id=75091 -->
+<!-- If this test passes there should be 2 rows and 2 columns "PASS" -->
+<script src="../../fast/repaint/resources/repaint.js"></script>
+</head>
+<body onload="runRepaintTest()">
+<svg style="position: absolute; top: 0px; left: 0px; width: 200px; height: 200px">
+ <svg id="inner1" viewbox="0 0 100 100">
+ <text x="0.3" y="0.3" font-size="0.1" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ </svg>
+ <svg id="inner2" y="100" viewbox="0 0 1 1">
+ <text x="0.3" y="0.3" font-size="0.1" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ </svg>
+</svg>
+<script>
+ function repaintTest() {
+ document.getElementById("inner1").setAttribute('viewBox', '0 0 1 1');
+ document.getElementById("inner2").setAttribute('viewBox', '0 0 1 1');
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+layer at (0,0) size 500x200
+ RenderSVGRoot {svg} at (0,13) size 405x187
+ RenderSVGContainer {g} at (0,13) size 405x100
+ RenderSVGText {text} at (0,14) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,50.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,50.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,13) size 100x100
+ RenderBlock {P} at (0,0) size 100x48 [color=#008800]
+ RenderText {#text} at (0,1) size 95x46
+ text run at (0,1) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,14) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGContainer {g} at (0,63) size 405x100
+ RenderSVGText {text} at (0,64) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,100.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,100.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,63) size 100x100
+ RenderBlock {P} at (0,0) size 100x48 [color=#008800]
+ RenderText {#text} at (0,1) size 95x46
+ text run at (0,1) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,64) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGContainer {g} at (0,113) size 405x87
+ RenderSVGText {text} at (0,114) size 200x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 105x46
+ chunk 1 text run 1 at (0.00,150.00) startOffset 0 endOffset 5 width 105.00: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 95x46
+ RenderSVGInlineText {#text} at (105,0) size 95x46
+ chunk 1 text run 1 at (105.00,150.00) startOffset 0 endOffset 4 width 95.00: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGForeignObject {foreignObject} at (210,113) size 100x100
+ RenderBlock {P} at (0,0) size 100x48 [color=#008800]
+ RenderText {#text} at (0,1) size 95x46
+ text run at (0,1) width 95: "PASS"
+ RenderSVGViewportContainer {svg} at (310,114) size 95x46
+ RenderSVGText {text} at (0,1) size 95x46 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 95x46
+ chunk 1 text run 1 at (0.00,37.00) startOffset 0 endOffset 4 width 95.00: "PASS"
--- /dev/null
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- Test that a script can change the scale of text from very small to something visible -->
+<!-- see: https://bugs.webkit.org/show_bug.cgi?id=75091 -->
+<!-- If this test passes there should be 3 rows and 4 columns of "PASS" -->
+<script src="../../fast/repaint/resources/repaint.js"></script>
+</head>
+<body onload="runRepaintTest()">
+<svg style="position: absolute; top: 0px; left: 0px; width: 500px; height: 200px">
+ <g id="text1g" transform="scale(0.001)">
+ <text x="0" y="50" font-size="40" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ <foreignObject x="210" y="13" width="100" height="100">
+ <body><p style="font-size: 40px; color: #080;">PASS</p></body>
+ </foreignObject>
+ <svg x="310" y="13" width="100" height="100">
+ <text x="0" y="37" font-size="40" fill="#080">PASS</text>
+ </svg>
+ </g>
+ <g id="text2g" transform="scale(1)">
+ <text x="0" y="100" font-size="40" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ <foreignObject x="210" y="63" width="100" height="100">
+ <body><p style="font-size: 40px; color: #080;">PASS</p></body>
+ </foreignObject>
+ <svg x="310" y="63" width="100" height="100">
+ <text x="0" y="37" font-size="40" fill="#080">PASS</text>
+ </svg>
+ </g>
+ <g id="text3g" transform="scale(0.03)">
+ <text x="0" y="150" font-size="40" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ <foreignObject x="210" y="113" width="100" height="100">
+ <body><p style="font-size: 40px; color: #080;">PASS</p></body>
+ </foreignObject>
+ <svg x="310" y="113" width="100" height="100">
+ <text x="0" y="37" font-size="40" fill="#080">PASS</text>
+ </svg>
+ </g>
+</svg>
+<script>
+ function repaintTest() {
+ document.getElementById("text1g").setAttribute('transform', 'scale(1)');
+ document.getElementById("text2g").setAttribute('transform', 'scale(1)');
+ document.getElementById("text3g").setAttribute('transform', 'scale(1)');
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+layer at (0,0) size 200x200
+ RenderSVGRoot {svg} at (0,0) size 200x200
+ RenderSVGViewportContainer {svg} at (0,0) size 200x200
+ RenderSVGText {text} at (0,0) size 1x1 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.30,0.30) startOffset 0 endOffset 5 width 0.26: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 1x1
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.56,0.30) startOffset 0 endOffset 4 width 0.24: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
+ RenderSVGViewportContainer {svg} at (0,100) size 200x100
+ RenderSVGText {text} at (0,0) size 1x1 contains 1 chunk(s)
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.30,0.30) startOffset 0 endOffset 5 width 0.26: "PASS "
+ RenderSVGTSpan {tspan} at (0,0) size 1x1
+ RenderSVGInlineText {#text} at (0,0) size 1x1
+ chunk 1 text run 1 at (0.56,0.30) startOffset 0 endOffset 4 width 0.24: "PASS"
+ RenderSVGInlineText {#text} at (0,0) size 0x0
--- /dev/null
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- Test that a script can change the scale of an svg viewbox and text will be rescaled properly -->
+<!-- see: https://bugs.webkit.org/show_bug.cgi?id=75091 -->
+<!-- If this test passes there should be 2 rows and 2 columns "PASS" -->
+<script src="../../fast/repaint/resources/repaint.js"></script>
+</head>
+<body onload="runRepaintTest()">
+<svg style="position: absolute; top: 0px; left: 0px; width: 200px; height: 200px">
+ <svg id="inner1" viewbox="0 0 100 100">
+ <text x="0.3" y="0.3" font-size="0.1" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ </svg>
+ <svg id="inner2" y="100" viewbox="0 0 1 1">
+ <text x="0.3" y="0.3" font-size="0.1" fill="#080">
+ PASS
+ <tspan fill="#080"> PASS</tspan>
+ </text>
+ </svg>
+</svg>
+<script>
+ function repaintTest() {
+ document.getElementById("inner1").setAttribute('viewBox', '0 0 1 1');
+ document.getElementById("inner2").setAttribute('viewBox', '0 0 1 1');
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
+2012-02-23 Philip Rogers <pdr@google.com>
+
+ Recompute font metrics on scale changes
+ https://bugs.webkit.org/show_bug.cgi?id=75091
+
+ Reviewed by Nikolas Zimmermann.
+
+ SVG text metrics depend on the transform from renderer to the svg root
+ which requires that we propagate transform changes down to text.
+ This change adds a boolean for tracking transform changes to
+ SVGViewportContainers and SVGTransformableContainers, and updates
+ RenderSVGText::layout() to recalculate text metrics if the transform
+ of an ancestor has changed.
+
+ Tests: platform/mac/svg/text/text-rescale.html
+ platform/mac/svg/text/text-viewbox-rescale.html
+ svg/text/text-rescale.html
+ svg/text/text-viewbox-rescale.html
+
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isSVGTransformableContainer):
+ (WebCore::RenderObject::isSVGViewportContainer):
+ * rendering/svg/RenderSVGContainer.h:
+ (WebCore::RenderSVGContainer::didTransformToRootUpdate):
+ * rendering/svg/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::computeNewScaledFontForStyle):
+ * rendering/svg/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::RenderSVGText):
+ (WebCore::RenderSVGText::layout):
+ * rendering/svg/RenderSVGText.h:
+ (WebCore::RenderSVGText::setNeedsTextMetricsUpdate):
+ (RenderSVGText):
+ * rendering/svg/RenderSVGTransformableContainer.cpp:
+ (WebCore::RenderSVGTransformableContainer::RenderSVGTransformableContainer):
+ (WebCore::RenderSVGTransformableContainer::calculateLocalTransform):
+ * rendering/svg/RenderSVGTransformableContainer.h:
+ (WebCore::RenderSVGTransformableContainer::isSVGTransformableContainer):
+ (WebCore::RenderSVGTransformableContainer::didTransformToRootUpdate):
+ (RenderSVGTransformableContainer):
+ * rendering/svg/RenderSVGViewportContainer.cpp:
+ (WebCore::RenderSVGViewportContainer::RenderSVGViewportContainer):
+ (WebCore::RenderSVGViewportContainer::calcViewport):
+ * rendering/svg/RenderSVGViewportContainer.h:
+ (WebCore::RenderSVGViewportContainer::didTransformToRootUpdate):
+ (RenderSVGViewportContainer):
+ * rendering/svg/SVGRenderSupport.cpp:
+ (WebCore::SVGRenderSupport::transformToRootChanged):
+ (WebCore):
+ (WebCore::SVGRenderSupport::layoutChildren):
+ * rendering/svg/SVGRenderSupport.h:
+ (SVGRenderSupport):
+
2012-02-21 James Robinson <jamesr@chromium.org>
[chromium] Notify compositor of wheel event registration via ScrollingCoordinator
// to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
virtual bool isSVGRoot() const { return false; }
virtual bool isSVGContainer() const { return false; }
- virtual bool isSVGViewportContainer() const { return false; }
+ virtual bool isSVGTransformableContainer() const { return false; }
+ virtual bool isSVGViewportContainer() const { return false; }
virtual bool isSVGGradientStop() const { return false; }
virtual bool isSVGHiddenContainer() const { return false; }
virtual bool isSVGPath() const { return false; }
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+ virtual bool didTransformToRootUpdate() { return false; }
protected:
virtual RenderObjectChildList* virtualChildren() { return children(); }
}
FontDescription fontDescription(style->fontDescription());
+
+ // FIXME: We need to better handle the case when we compute very small fonts below (below 1pt).
fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, scalingFactor, fontDescription.isAbsoluteSize(), fontDescription.computedSize(), DoNotUseSmartMinimumForFontSize));
scaledFont = Font(fontDescription, 0, 0);
, m_needsReordering(false)
, m_needsPositioningValuesUpdate(true)
, m_needsTransformUpdate(true)
+ , m_needsTextMetricsUpdate(true)
{
}
updateCachedBoundariesInParents = true;
}
- // If the root layout size changed (eg. window size changes) or the positioning values change, recompute the on-screen font size.
- if (SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
+ // If the root layout size changed (eg. window size changes) or the positioning values change
+ // or the transform to the root context has changed then recompute the on-screen font size.
+ if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
recursiveUpdateScaledFont(this);
rebuildLayoutAttributes(true);
updateCachedBoundariesInParents = true;
+ m_needsTextMetricsUpdate = false;
}
if (m_needsPositioningValuesUpdate) {
void setNeedsPositioningValuesUpdate() { m_needsPositioningValuesUpdate = true; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
virtual FloatRect repaintRectInLocalCoordinates() const;
static RenderSVGText* locateRenderSVGTextAncestor(RenderObject*);
bool m_needsReordering : 1;
bool m_needsPositioningValuesUpdate : 1;
bool m_needsTransformUpdate : 1;
+ bool m_needsTextMetricsUpdate : 1;
AffineTransform m_localTransform;
SVGTextLayoutAttributesBuilder m_layoutAttributesBuilder;
Vector<SVGTextLayoutAttributes*> m_layoutAttributes;
#include "RenderSVGTransformableContainer.h"
#include "SVGNames.h"
+#include "SVGRenderSupport.h"
#include "SVGShadowTreeElements.h"
#include "SVGStyledTransformableElement.h"
RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransformableElement* node)
: RenderSVGContainer(node)
, m_needsTransformUpdate(true)
+ , m_didTransformToRootUpdate(false)
{
}
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
bool needsUpdate = m_needsTransformUpdate;
+ m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent());
if (needsUpdate) {
m_localTransform = element->animatedLocalTransform();
m_needsTransformUpdate = false;
public:
explicit RenderSVGTransformableContainer(SVGStyledTransformableElement*);
+ virtual bool isSVGTransformableContainer() const { return true; }
virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
private:
virtual bool calculateLocalTransform();
virtual AffineTransform localTransform() const { return m_localTransform; }
bool m_needsTransformUpdate : 1;
+ bool m_didTransformToRootUpdate : 1;
AffineTransform m_localTransform;
};
}
RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
: RenderSVGContainer(node)
+ , m_didTransformToRootUpdate(false)
, m_isLayoutSizeChanged(false)
, m_needsTransformUpdate(true)
{
m_viewport = FloatRect(svg->x().value(lengthContext), svg->y().value(lengthContext), svg->width().value(lengthContext), svg->height().value(lengthContext));
if (oldViewport != m_viewport) {
+ m_didTransformToRootUpdate = true;
setNeedsBoundariesUpdate();
setNeedsTransformUpdate();
}
FloatRect viewport() const { return m_viewport; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
+ virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
virtual void determineIfLayoutSizeChanged();
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
FloatRect m_viewport;
mutable AffineTransform m_localToParentTransform;
+ bool m_didTransformToRootUpdate : 1;
bool m_isLayoutSizeChanged : 1;
bool m_needsTransformUpdate : 1;
};
return toRenderSVGRoot(start)->isLayoutSizeChanged();
}
+bool SVGRenderSupport::transformToRootChanged(RenderObject* ancestor)
+{
+ while (ancestor && !ancestor->isSVGRoot()) {
+ if (ancestor->isSVGTransformableContainer())
+ return toRenderSVGContainer(ancestor)->didTransformToRootUpdate();
+ if (ancestor->isSVGViewportContainer())
+ return toRenderSVGViewportContainer(ancestor)->didTransformToRootUpdate();
+ ancestor = ancestor->parent();
+ }
+
+ return false;
+}
+
void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
{
bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
+ bool transformChanged = transformToRootChanged(start);
HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
+ if (transformChanged) {
+ // If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true).
+ if (child->isSVGText())
+ toRenderSVGText(child)->setNeedsTextMetricsUpdate();
+ needsLayout = true;
+ }
+
if (layoutSizeChanged) {
// When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) {
// Shared between SVG renderers and resources.
static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
+ // Determines if any ancestor's transform has changed.
+ static bool transformToRootChanged(RenderObject*);
+
// FIXME: These methods do not belong here.
static const RenderSVGRoot* findTreeRootObject(const RenderObject*);