Diff
Modified: trunk/LayoutTests/ChangeLog (159029 => 159030)
--- trunk/LayoutTests/ChangeLog 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/LayoutTests/ChangeLog 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,3 +1,31 @@
+2013-11-10 Antti Koivisto <[email protected]>
+
+ Implement white-space property on simple line layout path
+ https://bugs.webkit.org/show_bug.cgi?id=124122
+
+ Reviewed by Andreas Kling.
+
+ The simple line layout produces slightly different runs in some pre-wrap cases compared
+ to the line box path (with less unnecessary boxes). To keep the test coverage this patch forces the
+ existing render tree dump based tests to use line boxes. It also adds new ref tests for
+ the same cases where the test uses the simple line path and the ref is forced on the line box path.
+ This ensures that the paths produce pixel-identical results.
+
+ * fast/forms/basic-textareas-simple-lines-expected.html: Added.
+ * fast/forms/basic-textareas-simple-lines.html: Added.
+ * fast/forms/basic-textareas.html:
+ * fast/text/embed-at-end-of-pre-wrap-line-simple-lines-expected.html: Added.
+ * fast/text/embed-at-end-of-pre-wrap-line-simple-lines.html: Added.
+ * fast/text/embed-at-end-of-pre-wrap-line.html:
+ * fast/text/whitespace/pre-wrap-line-test-simple-lines-expected.html: Added.
+ * fast/text/whitespace/pre-wrap-line-test-simple-lines.html: Added.
+ * fast/text/whitespace/pre-wrap-line-test.html:
+ * fast/text/whitespace/pre-wrap-long-word-simple-lines-expected.html: Added.
+ * fast/text/whitespace/pre-wrap-long-word-simple-lines.html: Added. New simple test for overflowing lines which was only covered by the very large basic-textareas.html.
+ * fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines-expected.html: Added.
+ * fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines.html: Added.
+ * fast/text/whitespace/pre-wrap-spaces-after-newline.html:
+
2013-11-10 Andreas Kling <[email protected]>
Optimize baselines: svg/*
Added: trunk/LayoutTests/fast/forms/basic-textareas-simple-lines-expected.html (0 => 159030)
--- trunk/LayoutTests/fast/forms/basic-textareas-simple-lines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/forms/basic-textareas-simple-lines-expected.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,104 @@
+<html>
+<body>
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+var docToAppendTo;
+function addTextarea(properties, opt_innerHTML) {
+ var title = docToAppendTo.createTextNode();
+ title.nodeValue = '';
+ var wrapper = docToAppendTo.createElement('div');
+ wrapper.style.cssText = 'display:inline-block;border:1px solid blue;font-size:12px;';
+ var textarea = docToAppendTo.createElement('textarea');
+ for (property in properties) {
+ var value = properties[property];
+ title.nodeValue += property + ': "' + value + '", ';
+ if (property == 'wrap')
+ textarea.setAttribute(property, value);
+ else if (property == 'style')
+ textarea.style.cssText = value;
+ else
+ textarea[property] = value;
+ }
+ textarea.innerHTML = opt_innerHTML ||
+ "Lorem ipsum dolor ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuv";
+
+ var span = document.createElement('span');
+ span.style.cssText = 'display:inline-block;width:80px;';
+ span.appendChild(title);
+ wrapper.appendChild(span);
+ wrapper.appendChild(document.createElement('br'));
+ wrapper.appendChild(textarea)
+ docToAppendTo.body.appendChild(wrapper);
+}
+
+function addAllTextareas(iframe, compatMode) {
+ iframe.style.cssText = 'width:100%;border:0;'
+ docToAppendTo = iframe.contentWindow.document;
+
+ docToAppendTo.body.style.cssText = 'margin:0';
+
+ if (docToAppendTo.compatMode != compatMode)
+ testFailed('This document should be in ' + compatMode + ' mode.');
+
+ var compatModeTitle = docToAppendTo.createElement('div');
+ compatModeTitle.innerHTML = 'CompatMode: ' + docToAppendTo.compatMode;
+ compatModeTitle.style.cssText = 'margin:5px 0;font-weight:bold;';
+ docToAppendTo.body.appendChild(compatModeTitle);
+
+ addTextarea({}, 'Lorem ipsum dolor');
+ addTextarea({disabled: 'true'});
+ addTextarea({style: 'padding:10px'});
+ addTextarea({style: 'padding:0px'});
+ addTextarea({style: 'margin:10px'});
+ addTextarea({style: 'margin:0px'});
+ addTextarea({style: 'width:60px'});
+ addTextarea({style: 'width:60px; padding:20px'});
+ addTextarea({style: 'width:60px; padding:0'});
+ addTextarea({style: 'height:60px'});
+ addTextarea({style: 'width:60px; height:60px'});
+ addTextarea({style: 'overflow:hidden'});
+ addTextarea({style: 'overflow:scroll'});
+ addTextarea({style: 'overflow:hidden; width:60px; height:60px'});
+ addTextarea({style: 'overflow:scroll; width:60px; height:60px'});
+ addTextarea({cols: 5, style: 'width:60px; height:60px'});
+ addTextarea({rows: 4, style: 'width:60px; height:60px'});
+ addTextarea({cols: 5, rows: 4, style: 'width:60px; height:60px'});
+ addTextarea({cols: 3});
+ addTextarea({rows: 3});
+ addTextarea({cols: 7});
+ addTextarea({rows: 7});
+ addTextarea({cols: 5, rows: 4});
+ addTextarea({wrap: 'off'});
+ addTextarea({wrap: 'hard'});
+ addTextarea({wrap: 'soft'});
+ addTextarea({style: 'white-space:normal'});
+ addTextarea({style: 'white-space:pre'});
+ addTextarea({style: 'white-space:prewrap'});
+ addTextarea({style: 'white-space:nowrap'});
+ addTextarea({style: 'white-space:pre-line'});
+ addTextarea({style: 'word-wrap:normal'});
+ addTextarea({wrap: 'off', style: 'white-space:pre-wrap'});
+
+ iframe.style.height = docToAppendTo.body.offsetHeight + 5 + 'px';
+}
+
+document.body.style.margin = 0;
+
+var standardsIframe = document.createElement('iframe');
+// Reference a page with a doctype so it's standards mode.
+standardsIframe.src = '';
+standardsIframe._onload_ = function(e) {
+ addAllTextareas(e.target, 'CSS1Compat');
+}
+document.body.appendChild(standardsIframe);
+
+var quirksIframe = document.createElement('iframe');
+quirksIframe._onload_ = function(e) {
+ addAllTextareas(e.target, 'BackCompat');
+}
+document.body.appendChild(quirksIframe);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/forms/basic-textareas-simple-lines.html (0 => 159030)
--- trunk/LayoutTests/fast/forms/basic-textareas-simple-lines.html (rev 0)
+++ trunk/LayoutTests/fast/forms/basic-textareas-simple-lines.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,101 @@
+<html>
+<body>
+<script>
+var docToAppendTo;
+function addTextarea(properties, opt_innerHTML) {
+ var title = docToAppendTo.createTextNode();
+ title.nodeValue = '';
+ var wrapper = docToAppendTo.createElement('div');
+ wrapper.style.cssText = 'display:inline-block;border:1px solid blue;font-size:12px;';
+ var textarea = docToAppendTo.createElement('textarea');
+ for (property in properties) {
+ var value = properties[property];
+ title.nodeValue += property + ': "' + value + '", ';
+ if (property == 'wrap')
+ textarea.setAttribute(property, value);
+ else if (property == 'style')
+ textarea.style.cssText = value;
+ else
+ textarea[property] = value;
+ }
+ textarea.innerHTML = opt_innerHTML ||
+ "Lorem ipsum dolor ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuv";
+
+ var span = document.createElement('span');
+ span.style.cssText = 'display:inline-block;width:80px;';
+ span.appendChild(title);
+ wrapper.appendChild(span);
+ wrapper.appendChild(document.createElement('br'));
+ wrapper.appendChild(textarea)
+ docToAppendTo.body.appendChild(wrapper);
+}
+
+function addAllTextareas(iframe, compatMode) {
+ iframe.style.cssText = 'width:100%;border:0;'
+ docToAppendTo = iframe.contentWindow.document;
+
+ docToAppendTo.body.style.cssText = 'margin:0';
+
+ if (docToAppendTo.compatMode != compatMode)
+ testFailed('This document should be in ' + compatMode + ' mode.');
+
+ var compatModeTitle = docToAppendTo.createElement('div');
+ compatModeTitle.innerHTML = 'CompatMode: ' + docToAppendTo.compatMode;
+ compatModeTitle.style.cssText = 'margin:5px 0;font-weight:bold;';
+ docToAppendTo.body.appendChild(compatModeTitle);
+
+ addTextarea({}, 'Lorem ipsum dolor');
+ addTextarea({disabled: 'true'});
+ addTextarea({style: 'padding:10px'});
+ addTextarea({style: 'padding:0px'});
+ addTextarea({style: 'margin:10px'});
+ addTextarea({style: 'margin:0px'});
+ addTextarea({style: 'width:60px'});
+ addTextarea({style: 'width:60px; padding:20px'});
+ addTextarea({style: 'width:60px; padding:0'});
+ addTextarea({style: 'height:60px'});
+ addTextarea({style: 'width:60px; height:60px'});
+ addTextarea({style: 'overflow:hidden'});
+ addTextarea({style: 'overflow:scroll'});
+ addTextarea({style: 'overflow:hidden; width:60px; height:60px'});
+ addTextarea({style: 'overflow:scroll; width:60px; height:60px'});
+ addTextarea({cols: 5, style: 'width:60px; height:60px'});
+ addTextarea({rows: 4, style: 'width:60px; height:60px'});
+ addTextarea({cols: 5, rows: 4, style: 'width:60px; height:60px'});
+ addTextarea({cols: 3});
+ addTextarea({rows: 3});
+ addTextarea({cols: 7});
+ addTextarea({rows: 7});
+ addTextarea({cols: 5, rows: 4});
+ addTextarea({wrap: 'off'});
+ addTextarea({wrap: 'hard'});
+ addTextarea({wrap: 'soft'});
+ addTextarea({style: 'white-space:normal'});
+ addTextarea({style: 'white-space:pre'});
+ addTextarea({style: 'white-space:prewrap'});
+ addTextarea({style: 'white-space:nowrap'});
+ addTextarea({style: 'white-space:pre-line'});
+ addTextarea({style: 'word-wrap:normal'});
+ addTextarea({wrap: 'off', style: 'white-space:pre-wrap'});
+
+ iframe.style.height = docToAppendTo.body.offsetHeight + 5 + 'px';
+}
+
+document.body.style.margin = 0;
+
+var standardsIframe = document.createElement('iframe');
+// Reference a page with a doctype so it's standards mode.
+standardsIframe.src = '';
+standardsIframe._onload_ = function(e) {
+ addAllTextareas(e.target, 'CSS1Compat');
+}
+document.body.appendChild(standardsIframe);
+
+var quirksIframe = document.createElement('iframe');
+quirksIframe._onload_ = function(e) {
+ addAllTextareas(e.target, 'BackCompat');
+}
+document.body.appendChild(quirksIframe);
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/fast/forms/basic-textareas.html (159029 => 159030)
--- trunk/LayoutTests/fast/forms/basic-textareas.html 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/LayoutTests/fast/forms/basic-textareas.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,6 +1,9 @@
<html>
<body>
<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
var docToAppendTo;
function addTextarea(properties, opt_innerHTML) {
var title = docToAppendTo.createTextNode();
Added: trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line-simple-lines-expected.html (0 => 159030)
--- trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line-simple-lines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line-simple-lines-expected.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,15 @@
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+<style>
+ div { white-space: pre-wrap; border: 1px solid; padding: 4px; width: 70px; margin: 8px 0; }
+</style>
+<p>
+ The following boxes should be identical.
+</p>
+<div>Lorem....... <span style="direction: rtl; unicode-bidi: bidi-override;">muspi</span>
+</div>
+<div>Lorem....... ipsum
+</div>
Added: trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line-simple-lines.html (0 => 159030)
--- trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line-simple-lines.html (rev 0)
+++ trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line-simple-lines.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,10 @@
+<style>
+ div { white-space: pre-wrap; border: 1px solid; padding: 4px; width: 70px; margin: 8px 0; }
+</style>
+<p>
+ The following boxes should be identical.
+</p>
+<div>Lorem....... <span style="direction: rtl; unicode-bidi: bidi-override;">muspi</span>
+</div>
+<div>Lorem....... ipsum
+</div>
Modified: trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line.html (159029 => 159030)
--- trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line.html 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/LayoutTests/fast/text/embed-at-end-of-pre-wrap-line.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,3 +1,8 @@
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
<style>
div { white-space: pre-wrap; border: 1px solid; padding: 4px; width: 70px; margin: 8px 0; }
</style>
Added: trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test-simple-lines-expected.html (0 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test-simple-lines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test-simple-lines-expected.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,6 @@
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+<table><tr><td><div style="white-space:pre-wrap">Three cheers for OldVet and the letter he wrote to Senator Dodd (see above Comment). We all need to be proactive and contact our senators and representatives to let them know our strong feelings on this subject. I would lose what little faith I have left in our government if they engineered a tax payer bailout.
Added: trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test-simple-lines.html (0 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test-simple-lines.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test-simple-lines.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,2 @@
+
+<table><tr><td><div style="white-space:pre-wrap">Three cheers for OldVet and the letter he wrote to Senator Dodd (see above Comment). We all need to be proactive and contact our senators and representatives to let them know our strong feelings on this subject. I would lose what little faith I have left in our government if they engineered a tax payer bailout.
Modified: trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test.html (159029 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test.html 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-line-test.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,2 +1,6 @@
-
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
<table><tr><td><div style="white-space:pre-wrap">Three cheers for OldVet and the letter he wrote to Senator Dodd (see above Comment). We all need to be proactive and contact our senators and representatives to let them know our strong feelings on this subject. I would lose what little faith I have left in our government if they engineered a tax payer bailout.
Added: trunk/LayoutTests/fast/text/whitespace/pre-wrap-long-word-simple-lines-expected.html (0 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-long-word-simple-lines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-long-word-simple-lines-expected.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,8 @@
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+<div style="position:relative; white-space:pre-wrap; width:180px; border:1px solid blue">
+ Lorem ipsum dolor ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuv
+</div>
Added: trunk/LayoutTests/fast/text/whitespace/pre-wrap-long-word-simple-lines.html (0 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-long-word-simple-lines.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-long-word-simple-lines.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,3 @@
+<div style="position:relative; white-space:pre-wrap; width:180px; border:1px solid blue">
+ Lorem ipsum dolor ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuv
+</div>
Added: trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines-expected.html (0 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines-expected.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,34 @@
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+<style>
+ pre { white-space: pre-wrap; background: silver; width: 7ex; }
+</style>
+<p>
+ Test for
+ <i><a href=""
+ white-space: pre-wrap collapses leading whitespace following a newline</i>.
+</p>
+<hr>
+<p>Here <code>bar</code> should be right under <code>foo</code>:</p>
+<pre>foo bar</pre>
+<p>Here <code>bar</code> should be on the right hand side of the second line:</p>
+<pre>foo<br> bar</pre>
+<pre>foo <br> bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<p>Here <code>bar</code> should be on the right hand side of the third line:</p>
+<pre>foo<br>
+ bar</pre>
+<pre>foo baz
+ bar</pre>
Added: trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines.html (0 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines.html (rev 0)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -0,0 +1,29 @@
+<style>
+ pre { white-space: pre-wrap; background: silver; width: 7ex; }
+</style>
+<p>
+ Test for
+ <i><a href=""
+ white-space: pre-wrap collapses leading whitespace following a newline</i>.
+</p>
+<hr>
+<p>Here <code>bar</code> should be right under <code>foo</code>:</p>
+<pre>foo bar</pre>
+<p>Here <code>bar</code> should be on the right hand side of the second line:</p>
+<pre>foo<br> bar</pre>
+<pre>foo <br> bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<pre>foo
+ bar</pre>
+<p>Here <code>bar</code> should be on the right hand side of the third line:</p>
+<pre>foo<br>
+ bar</pre>
+<pre>foo baz
+ bar</pre>
Modified: trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline.html (159029 => 159030)
--- trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline.html 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/LayoutTests/fast/text/whitespace/pre-wrap-spaces-after-newline.html 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,3 +1,8 @@
+<script>
+// Force line box path.
+if (window.internals)
+ internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
<style>
pre { white-space: pre-wrap; background: silver; width: 7ex; }
</style>
Modified: trunk/LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt (159029 => 159030)
--- trunk/LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/LayoutTests/platform/mac/compositing/repaint/invalidations-on-composited-layers-expected.txt 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,5 +1,6 @@
(repaint rects
(rect 8 13 784 15)
+ (rect 8 13 784 15)
(rect 8 413 784 28)
(rect 0 421 800 28)
)
Modified: trunk/Source/WebCore/ChangeLog (159029 => 159030)
--- trunk/Source/WebCore/ChangeLog 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/Source/WebCore/ChangeLog 2013-11-10 22:17:32 UTC (rev 159030)
@@ -1,3 +1,29 @@
+2013-11-10 Antti Koivisto <[email protected]>
+
+ Implement white-space property on simple line layout path
+ https://bugs.webkit.org/show_bug.cgi?id=124122
+
+ Reviewed by Andreas Kling.
+
+ Support all values of the white-space property and the tab-size property.
+
+ Tests: fast/forms/basic-textareas-simple-lines.html
+ fast/text/embed-at-end-of-pre-wrap-line-simple-lines.html
+ fast/text/whitespace/pre-wrap-line-test-simple-lines.html
+ fast/text/whitespace/pre-wrap-long-word-simple-lines.html
+ fast/text/whitespace/pre-wrap-spaces-after-newline-simple-lines.html
+
+ * rendering/SimpleLineLayout.cpp:
+ (WebCore::SimpleLineLayout::canUseFor):
+ (WebCore::SimpleLineLayout::isWhitespace):
+ (WebCore::SimpleLineLayout::skipWhitespaces):
+ (WebCore::SimpleLineLayout::textWidth):
+ (WebCore::SimpleLineLayout::measureWord):
+ (WebCore::SimpleLineLayout::createTextRuns):
+ * rendering/SimpleLineLayoutFunctions.cpp:
+ (WebCore::SimpleLineLayout::paintDebugBorders):
+ (WebCore::SimpleLineLayout::paintFlow):
+
2013-11-10 Sergio Correia <[email protected]>
Fix EFL build after r159027
Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (159029 => 159030)
--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp 2013-11-10 22:17:32 UTC (rev 159030)
@@ -130,9 +130,6 @@
// Non-visible overflow should be pretty easy to support.
if (style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE)
return false;
- // Pre/no-wrap would be very helpful to support.
- if (style.whiteSpace() != NORMAL)
- return false;
if (!style.textIndent().isZero())
return false;
if (style.wordSpacing() || style.letterSpacing())
@@ -197,35 +194,51 @@
return true;
}
-static inline bool isWhitespace(UChar character)
+static inline bool isWhitespace(UChar character, bool preserveNewline)
{
- return character == ' ' || character == '\t' || character == '\n';
+ return character == ' ' || character == '\t' || (!preserveNewline && character == '\n');
}
template <typename CharacterType>
-static inline unsigned skipWhitespaces(const CharacterType* text, unsigned offset, unsigned length)
+static inline unsigned skipWhitespaces(const CharacterType* text, unsigned offset, unsigned length, bool preserveNewline)
{
for (; offset < length; ++offset) {
- if (!isWhitespace(text[offset]))
+ if (!isWhitespace(text[offset], preserveNewline))
return offset;
}
return length;
}
template <typename CharacterType>
-static float textWidth(const RenderText& renderText, const CharacterType* text, unsigned textLength, unsigned from, unsigned to, float xPosition, const RenderStyle& style)
+static float textWidth(const RenderText& renderText, const CharacterType* text, unsigned textLength, unsigned from, unsigned to, float xPosition, const Font& font, float tabWidth)
{
- if (style.font().isFixedPitch() || (!from && to == textLength))
- return renderText.width(from, to - from, style.font(), xPosition, nullptr, nullptr);
- // FIXME: Add templated UChar/LChar paths.
+ if (font.isFixedPitch() || (!from && to == textLength))
+ return renderText.width(from, to - from, font, xPosition, nullptr, nullptr);
+
TextRun run(text + from, to - from);
run.setXPos(xPosition);
run.setCharactersLength(textLength - from);
+ run.setTabSize(!!tabWidth, tabWidth);
+
ASSERT(run.charactersLength() >= run.length());
- return style.font().width(run);
+ return font.width(run);
}
+template <typename CharacterType>
+static float measureWord(const RenderText& textRenderer, const CharacterType* text, unsigned textLength, unsigned start, unsigned end, float lineWidth, bool collapseWhitespace, const Font& font, float tabWidth, float spaceWidth)
+{
+ if (text[start] == ' ' && end == start + 1)
+ return spaceWidth;
+
+ bool measureWithEndSpace = collapseWhitespace && end < textLength && text[end] == ' ';
+ if (measureWithEndSpace)
+ ++end;
+ float width = textWidth(textRenderer, text, textLength, start, end, lineWidth, font, collapseWhitespace ? 0 : tabWidth);
+
+ return measureWithEndSpace ? width - spaceWidth : width;
+}
+
static float computeLineLeft(ETextAlign textAlign, float remainingWidth)
{
switch (textAlign) {
@@ -261,17 +274,24 @@
{
const RenderStyle& style = flow.style();
- ETextAlign textAlign = style.textAlign();
- float wordTrailingSpaceWidth = style.font().width(TextRun(&space, 1));
+ // These properties are supported.
+ const Font& font = style.font();
+ unsigned tabWidth = style.tabSize();
+ ETextAlign textAlign = style.textAlign(); // Not 'justify'.
+ bool collapseWhitespace = style.collapseWhiteSpace();
+ bool preserveNewline = style.preserveNewline();
+ bool wrapLines = style.autoWrap();
const CharacterType* text = textRenderer.text()->getCharacters<CharacterType>();
const unsigned textLength = textRenderer.textLength();
+ float spaceWidth = font.width(TextRun(&space, 1));
LazyLineBreakIterator lineBreakIterator(textRenderer.text(), style.locale());
unsigned lineEnd = 0;
while (lineEnd < textLength) {
- lineEnd = skipWhitespaces(text, lineEnd, textLength);
+ if (collapseWhitespace)
+ lineEnd = skipWhitespaces(text, lineEnd, textLength, preserveNewline);
unsigned lineStart = lineEnd;
unsigned wordEnd = lineEnd;
LineWidth lineWidth(flow, false, DoNotIndentText);
@@ -280,33 +300,63 @@
lineRuns.uncheckedAppend(Run(lineStart, 0));
while (wordEnd < textLength) {
- ASSERT(!isWhitespace(text[wordEnd]));
+ ASSERT(!collapseWhitespace || !isWhitespace(text[wordEnd], preserveNewline));
- bool wordIsPrecededByWhitespace = wordEnd > lineStart && isWhitespace(text[wordEnd - 1]);
- unsigned wordStart = wordIsPrecededByWhitespace ? wordEnd - 1 : wordEnd;
+ unsigned wordStart = wordEnd;
- wordEnd = nextBreakablePosition<CharacterType, false>(lineBreakIterator, text, textLength, wordEnd + 1);
+ if (preserveNewline && text[wordStart] == '\n') {
+ ++wordEnd;
+ // FIXME: This creates a dedicated run for newline. This is wasteful and unnecessary but it keeps test results unchanged.
+ if (wordStart > lineStart)
+ lineRuns.append(Run(lineEnd, lineRuns.last().right));
+ lineRuns.last().right = lineRuns.last().left;
+ lineRuns.last().textLength = 1;
+ lineEnd = wordEnd;
+ break;
+ }
- bool measureWithEndSpace = wordEnd < textLength && text[wordEnd] == ' ';
- unsigned wordMeasureEnd = measureWithEndSpace ? wordEnd + 1 : wordEnd;
+ if (!collapseWhitespace && isWhitespace(text[wordStart], preserveNewline))
+ wordEnd = wordStart + 1;
+ else
+ wordEnd = nextBreakablePosition<CharacterType, false>(lineBreakIterator, text, textLength, wordStart + 1);
- float wordWidth = textWidth(textRenderer, text, textLength, wordStart, wordMeasureEnd, lineWidth.committedWidth(), style);
+ bool wordIsPrecededByWhitespace = collapseWhitespace && wordStart > lineStart && isWhitespace(text[wordStart - 1], preserveNewline);
+ if (wordIsPrecededByWhitespace)
+ --wordStart;
- if (measureWithEndSpace)
- wordWidth -= wordTrailingSpaceWidth;
+ float wordWidth = measureWord(textRenderer, text, textLength, wordStart, wordEnd, lineWidth.committedWidth(), collapseWhitespace, font, tabWidth, spaceWidth);
lineWidth.addUncommittedWidth(wordWidth);
- // Move to the next line if the current one is full and we have something on it.
- if (!lineWidth.fitsOnLine() && lineWidth.committedWidth())
- break;
+ if (wrapLines) {
+ // Move to the next line if the current one is full and we have something on it.
+ if (!lineWidth.fitsOnLine() && lineWidth.committedWidth())
+ break;
+ // This is for white-space: pre-wrap which requires special handling for end line whitespace.
+ if (!collapseWhitespace && lineWidth.fitsOnLine() && wordEnd < textLength && isWhitespace(text[wordEnd], preserveNewline)) {
+ // Look ahead to see if the next whitespace would fit.
+ float whitespaceWidth = textWidth(textRenderer, text, textLength, wordEnd, wordEnd + 1, lineWidth.committedWidth(), font, tabWidth);
+ if (!lineWidth.fitsOnLineIncludingExtraWidth(whitespaceWidth)) {
+ // If not eat away the rest of the whitespace on the line.
+ unsigned whitespaceEnd = skipWhitespaces(text, wordEnd, textLength, preserveNewline);
+ // Include newline to this run too.
+ if (whitespaceEnd < textLength && text[whitespaceEnd] == '\n')
+ ++whitespaceEnd;
+ lineRuns.last().textLength = whitespaceEnd - lineRuns.last().textOffset;
+ lineRuns.last().right = lineWidth.availableWidth();
+ lineEnd = whitespaceEnd;
+ break;
+ }
+ }
+ }
+
if (wordStart > lineEnd) {
// There were more than one consecutive whitespace.
ASSERT(wordIsPrecededByWhitespace);
// Include space to the end of the previous run.
lineRuns.last().textLength++;
- lineRuns.last().right += wordTrailingSpaceWidth;
+ lineRuns.last().right += spaceWidth;
// Start a new run on the same line.
lineRuns.append(Run(wordStart + 1, lineRuns.last().right));
}
@@ -317,9 +367,10 @@
lineRuns.last().textLength = wordEnd - lineRuns.last().textOffset;
lineEnd = wordEnd;
- wordEnd = skipWhitespaces(text, wordEnd, textLength);
+ if (collapseWhitespace)
+ wordEnd = skipWhitespaces(text, wordEnd, textLength, preserveNewline);
- if (!lineWidth.fitsOnLine()) {
+ if (wrapLines && !lineWidth.fitsOnLine()) {
// The first run on the line overflows.
ASSERT(lineRuns.size() == 1);
break;
@@ -328,12 +379,13 @@
if (lineStart == lineEnd)
continue;
+ lineRuns.last().isEndOfLine = true;
+
adjustRunOffsets(lineRuns, textAlign, lineWidth.committedWidth(), lineWidth.availableWidth());
for (unsigned i = 0; i < lineRuns.size(); ++i)
runs.append(lineRuns[i]);
- runs.last().isEndOfLine = true;
++lineCount;
}
}
Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (159029 => 159030)
--- trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp 2013-11-10 20:59:09 UTC (rev 159029)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp 2013-11-10 22:17:32 UTC (rev 159030)
@@ -50,6 +50,8 @@
static void paintDebugBorders(GraphicsContext& context, const LayoutRect& borderRect, const LayoutPoint& paintOffset)
{
+ if (borderRect.isEmpty())
+ return;
GraphicsContextStateSaver stateSaver(context);
context.setStrokeColor(Color(0, 255, 0), ColorSpaceDeviceRGB);
context.setFillColor(Color::transparent, ColorSpaceDeviceRGB);
@@ -80,7 +82,9 @@
auto resolver = runResolver(flow, layout);
for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) {
auto run = *it;
- context.drawText(font, TextRun(run.text()), run.baseline() + paintOffset);
+ TextRun textRun(run.text());
+ textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
+ context.drawText(font, textRun, run.baseline() + paintOffset);
if (debugBordersEnabled)
paintDebugBorders(context, run.rect(), paintOffset);
}