Title: [211108] trunk
Revision
211108
Author
[email protected]
Date
2017-01-24 13:38:20 -0800 (Tue, 24 Jan 2017)

Log Message

Simple line layout: Add support for hyphen: auto.
https://bugs.webkit.org/show_bug.cgi?id=167297
<rdar://problem/30119463>

Reviewed by Antti Koivisto.

Source/WebCore:

Implement hyphen: auto for simple line layout.

Tests: fast/text/simple-line-hyphens-with-text-align.html
       fast/text/simple-line-hyphens-with-word-letter-spacing.html

* platform/text/Hyphenation.h:
(WebCore::enoughWidthForHyphenation):
* rendering/RenderTreeAsText.cpp:
(WebCore::writeSimpleLine):
(WebCore::write):
* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseForStyle):
(WebCore::SimpleLineLayout::LineState::appendFragmentAndCreateRunIfNeeded): Inherit the hyphen attribute from the
run-to-be-appended. Ensure that we don't append additional runs when the last run has hyphen.
(WebCore::SimpleLineLayout::splitFragmentToFitLine): Before calling into the lastHyphenPosition() we need to
ensure that the hyphen would surely fit (even on the splitting position).
(WebCore::SimpleLineLayout::createLineRuns): Probe hypenation for overhanging non-whitespace runs.
(WebCore::SimpleLineLayout::printReason):
* rendering/SimpleLineLayout.h:
(WebCore::SimpleLineLayout::Run::Run):
* rendering/SimpleLineLayoutFlowContents.h:
(WebCore::SimpleLineLayout::FlowContents::Segment::toSegmentPosition):
(WebCore::SimpleLineLayout::FlowContents::Segment::toRenderPosition):
* rendering/SimpleLineLayoutResolver.cpp:
(WebCore::SimpleLineLayout::RunResolver::Run::Run):
(WebCore::SimpleLineLayout::RunResolver::Run::constructStringForHyphenIfNeeded):
(WebCore::SimpleLineLayout::RunResolver::Run::text):
* rendering/SimpleLineLayoutResolver.h:
(WebCore::SimpleLineLayout::RunResolver::Run::hasHyphen):
* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
(WebCore::SimpleLineLayout::TextFragmentIterator::nextBreakablePosition):
(WebCore::SimpleLineLayout::TextFragmentIterator::nextNonWhitespacePosition):
(WebCore::SimpleLineLayout::TextFragmentIterator::textWidth):
(WebCore::SimpleLineLayout::TextFragmentIterator::lastHyphenPosition): We only check the actual run for hyphenation ignoring
the neighboring runs. This might need to be changed in the future.
(WebCore::SimpleLineLayout::TextFragmentIterator::runWidth):
* rendering/SimpleLineLayoutTextFragmentIterator.h:
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::TextFragment):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::hasHyphen):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::operator==):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::split):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::splitWithHyphen):
* rendering/line/BreakingContext.h:
(WebCore::tryHyphenating):

LayoutTests:

* fast/text/simple-line-hyphens-with-text-align-expected.html: Added.
* fast/text/simple-line-hyphens-with-text-align.html: Added.
* fast/text/simple-line-hyphens-with-word-letter-spacing-expected.html: Added.
* fast/text/simple-line-hyphens-with-word-letter-spacing.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (211107 => 211108)


--- trunk/LayoutTests/ChangeLog	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/LayoutTests/ChangeLog	2017-01-24 21:38:20 UTC (rev 211108)
@@ -1,3 +1,16 @@
+2017-01-24  Zalan Bujtas  <[email protected]>
+
+        Simple line layout: Add support for hyphen: auto.
+        https://bugs.webkit.org/show_bug.cgi?id=167297
+        <rdar://problem/30119463>
+
+        Reviewed by Antti Koivisto.
+
+        * fast/text/simple-line-hyphens-with-text-align-expected.html: Added.
+        * fast/text/simple-line-hyphens-with-text-align.html: Added.
+        * fast/text/simple-line-hyphens-with-word-letter-spacing-expected.html: Added.
+        * fast/text/simple-line-hyphens-with-word-letter-spacing.html: Added.
+
 2017-01-24  Ryan Haddad  <[email protected]>
 
         More modern-media-controls LayoutTest gardening.

Added: trunk/LayoutTests/fast/text/simple-line-hyphens-with-text-align-expected.html (0 => 211108)


--- trunk/LayoutTests/fast/text/simple-line-hyphens-with-text-align-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-hyphens-with-text-align-expected.html	2017-01-24 21:38:20 UTC (rev 211108)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphens</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto; 
+  width: 200px;
+  border: 1px solid green;
+}
+</style>
+<script>
+if (internal.settings)
+    internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+</head>
+<body>
+<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egestas est. Nullam et libero sit amet lect
 us tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendrerit, consequat vel neque. Vestibulum eni
 m nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, blandit a rutrum at, dignissim et lectu
 s. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+<div style="text-align: justify">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egest
 as est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendreri
 t, consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, b
 landit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+<div style="text-align: right">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egestas
  est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendrerit,
  consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, bla
 ndit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/simple-line-hyphens-with-text-align.html (0 => 211108)


--- trunk/LayoutTests/fast/text/simple-line-hyphens-with-text-align.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-hyphens-with-text-align.html	2017-01-24 21:38:20 UTC (rev 211108)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphens</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto; 
+  width: 200px;
+  border: 1px solid green;
+}
+</style>
+</head>
+<body>
+<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egestas est. Nullam et libero sit amet lect
 us tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendrerit, consequat vel neque. Vestibulum eni
 m nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, blandit a rutrum at, dignissim et lectu
 s. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+<div style="text-align: justify">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egest
 as est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendreri
 t, consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, b
 landit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+<div style="text-align: right">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egestas
  est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendrerit,
  consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, bla
 ndit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/simple-line-hyphens-with-word-letter-spacing-expected.html (0 => 211108)


--- trunk/LayoutTests/fast/text/simple-line-hyphens-with-word-letter-spacing-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-hyphens-with-word-letter-spacing-expected.html	2017-01-24 21:38:20 UTC (rev 211108)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphens</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto; 
+  width: 200px;
+  border: 1px solid green;
+}
+</style>
+<script>
+if (internal.settings)
+    internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+</head>
+<body>
+<div style="word-spacing: 30px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egesta
 s est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendrerit
 , consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, bl
 andit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+<div style="letter-spacing: 3px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egest
 as est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendreri
 t, consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, b
 landit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/simple-line-hyphens-with-word-letter-spacing.html (0 => 211108)


--- trunk/LayoutTests/fast/text/simple-line-hyphens-with-word-letter-spacing.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/simple-line-hyphens-with-word-letter-spacing.html	2017-01-24 21:38:20 UTC (rev 211108)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphens</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto; 
+  width: 200px;
+  border: 1px solid green;
+}
+</style>
+</head>
+<body>
+<div style="word-spacing: 30px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egesta
 s est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendrerit
 , consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, bl
 andit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+<div style="letter-spacing: 3px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec consequat rhoncus erat, id pellentesque ligula aliquet et. Nam aliquam pellentesque risus. Mauris lorem nunc, sodales pellentesque porttitor ut, pellentesque at felis. Nullam et accumsan leo, in scelerisque massa. Fusce luctus laoreet pretium. Nulla sollicitudin volutpat neque in mattis. Vestibulum non placerat velit. Aenean dui nunc, tincidunt nec tempus et, venenatis vel magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin pretium nisl sit amet lacus varius consequat. Donec congue molestie mauris, a vehicula velit. Nam pellentesque sed arcu congue rutrum. Maecenas pulvinar ex at diam dapibus consectetur ut non nisl. Sed tempus bibendum sodales. Donec nec arcu ligula. Vivamus sit amet aliquet neque, vel volutpat nibh. In purus sem, tincidunt vulputate neque eu, scelerisque hendrerit ex. Donec eu porta lectus, at malesuada magna. Duis ut egest
 as est. Nullam et libero sit amet lectus tempus pharetra ac id mauris. Ut diam orci, interdum nec suscipit ut, semper nec orci. Fusce sed risus elementum, posuere orci id, aliquam urna. Donec arcu turpis, scelerisque a mauris vel, vehicula convallis ipsum. Phasellus facilisis, magna ut dapibus pretium, sapien mauris viverra enim, ut hendrerit urna dui eu ligula. Nulla vestibulum et nibh quis laoreet. Quisque feugiat arcu ipsum, id mollis quam sagittis at. Morbi tempus, risus molestie ultricies viverra, justo augue facilisis orci, a semper risus dui pellentesque purus. Curabitur facilisis arcu quam, id facilisis turpis aliquam ac. Maecenas efficitur risus pellentesque sem maximus euismod. Proin aliquet justo ac dolor faucibus porttitor. Fusce orci lectus, eleifend at lectus sit amet, pretium ornare felis. Nullam nec ipsum maximus, molestie arcu in, finibus urna. Suspendisse tincidunt feugiat est, in viverra lectus tincidunt quis. Ut eros tortor, tincidunt vel commodo hendreri
 t, consequat vel neque. Vestibulum enim nibh, accumsan quis viverra ut, iaculis sit amet est. Morbi non lacus at dolor euismod molestie. Integer pulvinar, nibh in volutpat tincidunt, urna odio interdum magna, vitae faucibus felis quam nec est. Proin tellus quam, auctor nec dictum sed, rhoncus nec massa. Mauris ac arcu ac augue porta viverra. Quisque semper eget nisi quis viverra. Donec vitae mauris ipsum. Duis tempor pulvinar viverra. Nam dignissim iaculis felis, eget vestibulum eros. Nulla eget faucibus massa. Integer sollicitudin pretium erat, vel commodo nunc congue non. Nulla in nunc auctor dui efficitur euismod. Sed pharetra sapien erat, a blandit neque porttitor sit amet. Mauris pharetra sodales maximus. Nulla volutpat auctor quam, a elementum risus tristique eu. In ac sodales nibh. Maecenas pharetra orci sem, eu laoreet quam tincidunt non. Mauris in interdum dui. Vivamus et interdum erat. Aliquam nec ante tincidunt, elementum risus in, mattis orci. Sed massa turpis, b
 landit a rutrum at, dignissim et lectus. Nunc tincidunt orci nibh, id ullamcorper nisl vestibulum vel.</div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (211107 => 211108)


--- trunk/Source/WebCore/ChangeLog	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/ChangeLog	2017-01-24 21:38:20 UTC (rev 211108)
@@ -1,3 +1,57 @@
+2017-01-24  Zalan Bujtas  <[email protected]>
+
+        Simple line layout: Add support for hyphen: auto.
+        https://bugs.webkit.org/show_bug.cgi?id=167297
+        <rdar://problem/30119463>
+
+        Reviewed by Antti Koivisto.
+
+        Implement hyphen: auto for simple line layout. 
+
+        Tests: fast/text/simple-line-hyphens-with-text-align.html
+               fast/text/simple-line-hyphens-with-word-letter-spacing.html
+
+        * platform/text/Hyphenation.h:
+        (WebCore::enoughWidthForHyphenation):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::writeSimpleLine):
+        (WebCore::write):
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::canUseForStyle):
+        (WebCore::SimpleLineLayout::LineState::appendFragmentAndCreateRunIfNeeded): Inherit the hyphen attribute from the
+        run-to-be-appended. Ensure that we don't append additional runs when the last run has hyphen.
+        (WebCore::SimpleLineLayout::splitFragmentToFitLine): Before calling into the lastHyphenPosition() we need to
+        ensure that the hyphen would surely fit (even on the splitting position).
+        (WebCore::SimpleLineLayout::createLineRuns): Probe hypenation for overhanging non-whitespace runs. 
+        (WebCore::SimpleLineLayout::printReason):
+        * rendering/SimpleLineLayout.h:
+        (WebCore::SimpleLineLayout::Run::Run):
+        * rendering/SimpleLineLayoutFlowContents.h:
+        (WebCore::SimpleLineLayout::FlowContents::Segment::toSegmentPosition):
+        (WebCore::SimpleLineLayout::FlowContents::Segment::toRenderPosition):
+        * rendering/SimpleLineLayoutResolver.cpp:
+        (WebCore::SimpleLineLayout::RunResolver::Run::Run):
+        (WebCore::SimpleLineLayout::RunResolver::Run::constructStringForHyphenIfNeeded):
+        (WebCore::SimpleLineLayout::RunResolver::Run::text):
+        * rendering/SimpleLineLayoutResolver.h:
+        (WebCore::SimpleLineLayout::RunResolver::Run::hasHyphen):
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::nextBreakablePosition):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::nextNonWhitespacePosition):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::textWidth):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::lastHyphenPosition): We only check the actual run for hyphenation ignoring
+        the neighboring runs. This might need to be changed in the future.
+        (WebCore::SimpleLineLayout::TextFragmentIterator::runWidth):
+        * rendering/SimpleLineLayoutTextFragmentIterator.h:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::TextFragment):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::hasHyphen):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::operator==):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::split):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::splitWithHyphen):
+        * rendering/line/BreakingContext.h:
+        (WebCore::tryHyphenating):
+
 2017-01-24  Matt Rajca  <[email protected]>
 
         Pass down website autoplay policies to media elements

Modified: trunk/Source/WebCore/platform/text/Hyphenation.h (211107 => 211108)


--- trunk/Source/WebCore/platform/text/Hyphenation.h	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/platform/text/Hyphenation.h	2017-01-24 21:38:20 UTC (rev 211108)
@@ -31,6 +31,13 @@
 
 namespace WebCore {
 
+inline static bool enoughWidthForHyphenation(float availableWidth, float fontPixelSize)
+{
+    // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
+    // that an hyphenation opportunity exists, so do not bother to look for it.
+    return availableWidth > fontPixelSize * 5 / 4;
+
+}
 bool canHyphenate(const AtomicString& localeIdentifier);
 size_t lastHyphenLocation(StringView, size_t beforeIndex, const AtomicString& localeIdentifier);
 

Modified: trunk/Source/WebCore/rendering/RenderTreeAsText.cpp (211107 => 211108)


--- trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2017-01-24 21:38:20 UTC (rev 211108)
@@ -493,18 +493,23 @@
     ts << "\n";
 }
 
-static void writeSimpleLine(TextStream& ts, const RenderText& o, const FloatRect& rect, StringView text)
+static void writeSimpleLine(TextStream& ts, const RenderText& renderText, const SimpleLineLayout::RunResolver::Run& run)
 {
+    auto rect = run.rect();
     int x = rect.x();
     int y = rect.y();
     int logicalWidth = ceilf(rect.x() + rect.width()) - x;
 
-    if (is<RenderTableCell>(*o.containingBlock()))
-        y -= floorToInt(downcast<RenderTableCell>(*o.containingBlock()).intrinsicPaddingBefore());
-        
+    if (is<RenderTableCell>(*renderText.containingBlock()))
+        y -= floorToInt(downcast<RenderTableCell>(*renderText.containingBlock()).intrinsicPaddingBefore());
+
     ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
-    ts << ": "
-        << quoteAndEscapeNonPrintables(text);
+    if (run.hasHyphen()) {
+        ts << ": " << quoteAndEscapeNonPrintables(run.text().substring(0, run.text().length() - 1));
+        ts << " + hyphen string " << quoteAndEscapeNonPrintables(renderText.style().hyphenString().string());
+    } else
+        ts << ": " << quoteAndEscapeNonPrintables(run.text());
+
     ts << "\n";
 }
 
@@ -555,7 +560,7 @@
             auto resolver = runResolver(downcast<RenderBlockFlow>(*text.parent()), *layout);
             for (const auto& run : resolver.rangeForRenderer(text)) {
                 writeIndent(ts, indent + 1);
-                writeSimpleLine(ts, text, run.rect(), run.text());
+                writeSimpleLine(ts, text, run);
             }
         } else {
             for (auto* box = text.firstTextBox(); box; box = box->nextTextBox()) {

Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.cpp (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayout.cpp	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.cpp	2017-01-24 21:38:20 UTC (rev 211108)
@@ -33,6 +33,7 @@
 #include "HitTestLocation.h"
 #include "HitTestRequest.h"
 #include "HitTestResult.h"
+#include "Hyphenation.h"
 #include "InlineTextBox.h"
 #include "LineWidth.h"
 #include "Logging.h"
@@ -85,7 +86,7 @@
     FlowHasRTLOrdering                    = 1LLU  << 20,
     FlowHasLineAlignEdges                 = 1LLU  << 21,
     FlowHasLineSnap                       = 1LLU  << 22,
-    FlowHasHypensAuto                     = 1LLU  << 23,
+    FlowHasHypensLimit                    = 1LLU  << 23,
     FlowHasTextEmphasisFillOrMark         = 1LLU  << 24,
     FlowHasTextShadow                     = 1LLU  << 25,
     FlowHasPseudoFirstLine                = 1LLU  << 26,
@@ -236,8 +237,10 @@
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineAlignEdges, reasons, includeReasons);
     if (style.lineSnap() != LineSnapNone)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineSnap, reasons, includeReasons);
-    if (style.hyphens() == HyphensAuto)
-        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasHypensAuto, reasons, includeReasons);
+    if (style.hyphenationLimitBefore() != RenderStyle::initialHyphenationLimitBefore()
+        || style.hyphenationLimitAfter() != RenderStyle::initialHyphenationLimitAfter()
+        || style.hyphenationLimitLines() != RenderStyle::initialHyphenationLimitLines())
+        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasHypensLimit, reasons, includeReasons);
     if (style.textEmphasisFill() != TextEmphasisFillFilled || style.textEmphasisMark() != TextEmphasisMarkNone)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextEmphasisFillOrMark, reasons, includeReasons);
     if (style.textShadow())
@@ -453,7 +456,7 @@
         unsigned endPosition = fragment.isCollapsed() ? fragment.start() + 1 : fragment.end();
         // New line needs new run.
         if (!m_runsWidth)
-            runs.append(Run(fragment.start(), endPosition, m_runsWidth, m_runsWidth + fragment.width(), false));
+            runs.append(Run(fragment.start(), endPosition, m_runsWidth, m_runsWidth + fragment.width(), false, fragment.hasHyphen()));
         else {
             const auto& lastFragment = m_fragments.last();
             // Advance last completed fragment when the previous fragment is all set (including multiple parts across renderers)
@@ -470,11 +473,13 @@
                 return;
             }
             if (lastFragment.isLastInRenderer() || lastFragment.isCollapsed())
-                runs.append(Run(fragment.start(), endPosition, m_runsWidth, m_runsWidth + fragment.width(), false));
+                runs.append(Run(fragment.start(), endPosition, m_runsWidth, m_runsWidth + fragment.width(), false, fragment.hasHyphen()));
             else {
                 Run& lastRun = runs.last();
                 lastRun.end = endPosition;
                 lastRun.logicalRight += fragment.width();
+                ASSERT(!lastRun.hasHyphen);
+                lastRun.hasHyphen = fragment.hasHyphen();
             }
         }
         m_fragments.append(fragment);
@@ -623,8 +628,26 @@
         return availableWidth < textFragmentIterator.textWidth(start, index + 1, 0);
     });
     unsigned splitPosition = (*it);
-    if (keepAtLeastOneCharacter && splitPosition == fragmentToSplit.start())
-        ++splitPosition;
+    auto& style = textFragmentIterator.style();
+    // Does first character fit this line?
+    if (splitPosition == fragmentToSplit.start()) {
+        if (keepAtLeastOneCharacter)
+            ++splitPosition;
+    } else if (style.shouldHyphenate && enoughWidthForHyphenation(availableWidth, style.font.pixelSize())) {
+        // We might be able to fit the hyphen at the split position.
+        auto splitPositionWithHyphen = splitPosition;
+        // Find a splitting position where hyphen surely fits.
+        auto leftSideWidth = textFragmentIterator.textWidth(start, splitPosition, 0);
+        while (leftSideWidth + style.hyphenStringWidth > availableWidth) {
+            if (--splitPositionWithHyphen <= start)
+                break; // No space for hyphen.
+            leftSideWidth -= textFragmentIterator.textWidth(splitPositionWithHyphen, splitPositionWithHyphen + 1, 0);
+        }
+        if (splitPositionWithHyphen > start) {
+            if (auto hyphenPosition = textFragmentIterator.lastHyphenPosition(fragmentToSplit, splitPositionWithHyphen + 1))
+                return fragmentToSplit.splitWithHyphen(*hyphenPosition, textFragmentIterator);
+        }
+    }
     return fragmentToSplit.split(splitPosition, textFragmentIterator);
 }
 
@@ -736,8 +759,20 @@
                 line.appendFragmentAndCreateRunIfNeeded(fragment, runs);
                 break;
             }
+            ASSERT(fragment.type() == TextFragmentIterator::TextFragment::NonWhitespace);
+            // Find out if this non-whitespace fragment has a hyphen where we can break.
+            if (style.shouldHyphenate) {
+                auto fragmentToSplit = fragment;
+                // Split and check if we actually ended up with a hyphen.
+                auto overflowFragment = splitFragmentToFitLine(fragmentToSplit, line.availableWidth() - line.width(), emptyLine, textFragmentIterator);
+                if (fragmentToSplit.hasHyphen()) {
+                    line.setOverflowedFragment(overflowFragment);
+                    line.appendFragmentAndCreateRunIfNeeded(fragmentToSplit, runs);
+                    break;
+                }
+                // No hyphen, no split.
+            }
             // Non-breakable non-whitespace first fragment. Add it to the current line. -it overflows though.
-            ASSERT(fragment.type() == TextFragmentIterator::TextFragment::NonWhitespace);
             if (emptyLine) {
                 forceFragmentToLine(line, textFragmentIterator, runs, fragment);
                 break;
@@ -956,8 +991,8 @@
     case FlowHasLineSnap:
         stream << "-webkit-line-snap property";
         break;
-    case FlowHasHypensAuto:
-        stream << "hyphen: auto";
+    case FlowHasHypensLimit:
+        stream << "hyphen-limit-* property";
         break;
     case FlowHasTextEmphasisFillOrMark:
         stream << "text-emphasis (fill/mark)";

Modified: trunk/Source/WebCore/rendering/SimpleLineLayout.h (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayout.h	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayout.h	2017-01-24 21:38:20 UTC (rev 211108)
@@ -46,17 +46,19 @@
 #if COMPILER(MSVC)
     Run() { }
 #endif
-    Run(unsigned start, unsigned end, float logicalLeft, float logicalRight, bool isEndOfLine)
-        : start(start)
-        , end(end)
+    Run(unsigned start, unsigned end, float logicalLeft, float logicalRight, bool isEndOfLine, bool hasHyphen)
+        : end(end)
+        , start(start)
         , isEndOfLine(isEndOfLine)
+        , hasHyphen(hasHyphen)
         , logicalLeft(logicalLeft)
         , logicalRight(logicalRight)
     { }
 
-    unsigned start;
-    unsigned end : 31;
+    unsigned end;
+    unsigned start : 30;
     unsigned isEndOfLine : 1;
+    unsigned hasHyphen : 1;
     float logicalLeft;
     float logicalRight;
     // TODO: Move these optional items out of SimpleLineLayout::Run to a supplementary structure.

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFlowContents.h	2017-01-24 21:38:20 UTC (rev 211108)
@@ -37,6 +37,12 @@
     FlowContents(const RenderBlockFlow&);
 
     struct Segment {
+        unsigned toSegmentPosition(unsigned position) const
+        {
+            ASSERT(position >= start);
+            return position - start;
+        }
+        unsigned toRenderPosition(unsigned position) const { return start + position; }
         unsigned start;
         unsigned end;
         String text;

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.cpp	2017-01-24 21:38:20 UTC (rev 211108)
@@ -47,8 +47,21 @@
 RunResolver::Run::Run(const Iterator& iterator)
     : m_iterator(iterator)
 {
+    constructStringForHyphenIfNeeded();
 }
 
+void RunResolver::Run::constructStringForHyphenIfNeeded()
+{
+    auto& run = m_iterator.simpleRun();
+    if (!run.hasHyphen)
+        return;
+    // Empty runs should not have hyphen.
+    ASSERT(run.start < run.end);
+    auto& segment = m_iterator.resolver().m_flowContents.segmentForRun(run.start, run.end);
+    auto text = StringView(segment.text).substring(segment.toSegmentPosition(run.start), run.end - run.start);
+    m_textWithHyphen = makeString(text, m_iterator.resolver().flow().style().hyphenString());
+}
+
 FloatRect RunResolver::Run::rect() const
 {
     auto& run = m_iterator.simpleRun();
@@ -69,12 +82,14 @@
 
 StringView RunResolver::Run::text() const
 {
+    if (m_textWithHyphen)
+        return StringView(*m_textWithHyphen);
     auto& run = m_iterator.simpleRun();
     ASSERT(run.start < run.end);
     auto& segment = m_iterator.resolver().m_flowContents.segmentForRun(run.start, run.end);
     // We currently split runs on segment boundaries (different RenderObject).
     ASSERT(run.end <= segment.end);
-    return StringView(segment.text).substring(run.start - segment.start, run.end - run.start);
+    return StringView(segment.text).substring(segment.toSegmentPosition(run.start), run.end - run.start);
 }
 
 RunResolver::Iterator::Iterator(const RunResolver& resolver, unsigned runIndex, unsigned lineIndex)

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h	2017-01-24 21:38:20 UTC (rev 211108)
@@ -65,13 +65,16 @@
         int baselinePosition() const;
         StringView text() const;
         bool isEndOfLine() const;
+        bool hasHyphen() const { return m_iterator.simpleRun().hasHyphen; }
 
         unsigned lineIndex() const;
 
     private:
         float computeBaselinePosition() const;
+        void constructStringForHyphenIfNeeded();
 
         const Iterator& m_iterator;
+        std::optional<String> m_textWithHyphen;
     };
 
     class Iterator {

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp	2017-01-24 21:38:20 UTC (rev 211108)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "SimpleLineLayoutTextFragmentIterator.h"
 
+#include "Hyphenation.h"
 #include "RenderBlockFlow.h"
 #include "RenderChildIterator.h"
 #include "SimpleLineLayoutFlowContents.h"
@@ -46,6 +47,8 @@
     , spaceWidth(font.width(TextRun(StringView(&space, 1))))
     , wordSpacing(font.wordSpacing())
     , tabWidth(collapseWhitespace ? 0 : style.tabSize())
+    , shouldHyphenate(style.hyphens() == HyphensAuto && canHyphenate(style.locale()))
+    , hyphenStringWidth(shouldHyphenate ? font.width(TextRun(style.hyphenString())) : 0)
     , locale(style.locale())
 {
 }
@@ -143,8 +146,7 @@
         m_lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
         m_lineBreakIterator.resetStringAndReleaseIterator(segment.text, m_style.locale, LineBreakIteratorMode::Default);
     }
-    unsigned segmentPosition = startPosition - segment.start;
-    return segment.start + nextBreakablePositionInSegment(m_lineBreakIterator, segmentPosition, m_style.breakNBSP, m_style.keepAllWordsForCJK);
+    return segment.toRenderPosition(nextBreakablePositionInSegment(m_lineBreakIterator, segment.toSegmentPosition(startPosition), m_style.breakNBSP, m_style.keepAllWordsForCJK));
 }
 
 template <typename CharacterType>
@@ -154,7 +156,7 @@
     const auto* text = segment.text.characters<CharacterType>();
     unsigned position = startPosition;
     for (; position < segment.end; ++position) {
-        auto character = text[position - segment.start];
+        auto character = text[segment.toSegmentPosition(position)];
         bool isWhitespace = character == ' ' || character == '\t' || (!m_style.preserveNewline && character == '\n');
         if (!isWhitespace)
             return position;
@@ -170,10 +172,28 @@
     if (!m_style.font.size())
         return 0;
     if (m_style.font.isFixedPitch() || (from == segment.start && to == segment.end))
-        return downcast<RenderText>(segment.renderer).width(from - segment.start, to - from, m_style.font, xPosition, nullptr, nullptr);
+        return downcast<RenderText>(segment.renderer).width(segment.toSegmentPosition(from), to - from, m_style.font, xPosition, nullptr, nullptr);
     return runWidth(segment, from, to, xPosition);
 }
 
+std::optional<unsigned> TextFragmentIterator::lastHyphenPosition(const TextFragmentIterator::TextFragment& run, unsigned beforeIndex) const
+{
+    ASSERT(run.start() < beforeIndex);
+    auto& segment = *m_currentSegment;
+    ASSERT(segment.start <= beforeIndex && beforeIndex <= segment.end);
+    ASSERT(is<RenderText>(segment.renderer));
+    if (!m_style.shouldHyphenate || run.type() != TextFragment::NonWhitespace)
+        return std::nullopt;
+    
+    auto runStart = segment.toSegmentPosition(run.start());
+    auto before = segment.toSegmentPosition(beforeIndex) - runStart;
+    auto substringForHyphenation = StringView(segment.text).substring(runStart, run.end() - run.start());
+    auto hyphenLocation = lastHyphenLocation(substringForHyphenation, before, m_style.locale);
+    if (hyphenLocation)
+        return segment.toRenderPosition(hyphenLocation + runStart);
+    return std::nullopt;
+}
+
 unsigned TextFragmentIterator::skipToNextPosition(PositionType positionType, unsigned startPosition, float& width, float xPosition, bool& overlappingFragment)
 {
     overlappingFragment = false;
@@ -219,8 +239,8 @@
     ASSERT(startPosition <= endPosition);
     if (startPosition == endPosition)
         return 0;
-    unsigned segmentFrom = startPosition - segment.start;
-    unsigned segmentTo = endPosition - segment.start;
+    unsigned segmentFrom = segment.toSegmentPosition(startPosition);
+    unsigned segmentTo = segment.toSegmentPosition(endPosition);
     bool measureWithEndSpace = m_style.collapseWhitespace && segmentTo < segment.text.length() && segment.text[segmentTo] == ' ';
     if (measureWithEndSpace)
         ++segmentTo;

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h (211107 => 211108)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h	2017-01-24 21:38:20 UTC (rev 211108)
@@ -43,7 +43,7 @@
     public:
         enum Type { ContentEnd, SoftLineBreak, HardLineBreak, Whitespace, NonWhitespace };
         TextFragment() = default;
-        TextFragment(unsigned start, unsigned end, float width, Type type, bool isLastInRenderer = false, bool overlapsToNextRenderer = false, bool isCollapsed = false, bool isCollapsible = false)
+        TextFragment(unsigned start, unsigned end, float width, Type type, bool isLastInRenderer = false, bool overlapsToNextRenderer = false, bool isCollapsed = false, bool isCollapsible = false, bool hasHyphen = false)
             : m_start(start)
             , m_end(end)
             , m_width(width)
@@ -52,6 +52,7 @@
             , m_overlapsToNextRenderer(overlapsToNextRenderer)
             , m_isCollapsed(isCollapsed)
             , m_isCollapsible(isCollapsible)
+            , m_hasHyphen(hasHyphen)
         {
         }
 
@@ -64,9 +65,11 @@
         bool isLineBreak() const { return m_type == SoftLineBreak || m_type == HardLineBreak; }
         bool isCollapsed() const { return m_isCollapsed; }
         bool isCollapsible() const { return m_isCollapsible; }
+        bool hasHyphen() const { return m_hasHyphen; }
 
         bool isEmpty() const { return start() == end() && !isLineBreak(); }
         TextFragment split(unsigned splitPosition, const TextFragmentIterator&);
+        TextFragment splitWithHyphen(unsigned hyphenPosition, const TextFragmentIterator&);
         bool operator==(const TextFragment& other) const
         {
             return m_start == other.m_start
@@ -76,7 +79,8 @@
                 && m_isLastInRenderer == other.m_isLastInRenderer
                 && m_overlapsToNextRenderer == other.m_overlapsToNextRenderer
                 && m_isCollapsed == other.m_isCollapsed
-                && m_isCollapsible == other.m_isCollapsible;
+                && m_isCollapsible == other.m_isCollapsible
+                && m_hasHyphen == other.m_hasHyphen;
         }
 
     private:
@@ -88,10 +92,14 @@
         bool m_overlapsToNextRenderer { false };
         bool m_isCollapsed { false };
         bool m_isCollapsible { false };
+        bool m_hasHyphen { false };
     };
     TextFragment nextTextFragment(float xPosition = 0);
     void revertToEndOfFragment(const TextFragment&);
+
+    // FIXME: These functions below should be decoupled from the text iterator.
     float textWidth(unsigned startPosition, unsigned endPosition, float xPosition) const;
+    std::optional<unsigned> lastHyphenPosition(const TextFragmentIterator::TextFragment& run, unsigned beforeIndex) const;
 
     struct Style {
         explicit Style(const RenderStyle&);
@@ -108,6 +116,8 @@
         float spaceWidth;
         float wordSpacing;
         unsigned tabWidth;
+        bool shouldHyphenate;
+        float hyphenStringWidth;
         AtomicString locale;
     };
     const Style& style() const { return m_style; }
@@ -142,15 +152,25 @@
         fragment.m_isCollapsed = false;
     };
 
-    TextFragment newFragment(*this);
+    TextFragment rightSide(*this);
     m_end = splitPosition;
     updateFragmentProperties(*this);
 
-    newFragment.m_start = splitPosition;
-    updateFragmentProperties(newFragment);
-    return newFragment;
+    rightSide.m_start = splitPosition;
+    updateFragmentProperties(rightSide);
+    return rightSide;
 }
 
+inline TextFragmentIterator::TextFragment TextFragmentIterator::TextFragment::splitWithHyphen(unsigned hyphenPosition,
+    const TextFragmentIterator& textFragmentIterator)
+{
+    ASSERT(textFragmentIterator.style().shouldHyphenate);
+    auto rightSide = split(hyphenPosition, textFragmentIterator);
+    m_hasHyphen = true;
+    m_width += textFragmentIterator.style().hyphenStringWidth;
+    return rightSide;
+}
+
 inline bool TextFragmentIterator::isSoftLineBreak(unsigned position) const
 {
     const auto& segment = *m_currentSegment;

Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (211107 => 211108)


--- trunk/Source/WebCore/rendering/line/BreakingContext.h	2017-01-24 21:23:05 UTC (rev 211107)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h	2017-01-24 21:38:20 UTC (rev 211108)
@@ -687,9 +687,7 @@
     int hyphenWidth = measureHyphenWidth(text, font);
 
     float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
-    // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
-    // that an hyphenation opportunity exists, so do not bother to look for it.
-    if (maxPrefixWidth <= font.pixelSize() * 5 / 4)
+    if (!enoughWidthForHyphenation(maxPrefixWidth, font.pixelSize()))
         return;
 
     const RenderStyle& style = text.style();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to