Simple line layout: Add support for -webkit-hyphenate-limit-lines
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Jan 2017 21:19:38 +0000 (21:19 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Jan 2017 21:19:38 +0000 (21:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167446
<rdar://problem/30194030>

Reviewed by Antti Koivisto.

Source/WebCore:

Now we can set the limit on the number of lines that a word can split across through hyphenation.

Tests: fast/text/simple-line-layout-hyphen-limit-lines.html
       fast/text/simple-line-layout-hyphen-limit-lines2.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseForStyle):
(WebCore::SimpleLineLayout::splitFragmentToFitLine):
(WebCore::SimpleLineLayout::printReason):
* rendering/SimpleLineLayoutTextFragmentIterator.cpp:
(WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
* rendering/SimpleLineLayoutTextFragmentIterator.h:
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::TextFragment):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::wrappingWithHyphenCounter):
(WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::splitWithHyphen): The right side of the split has +1 on the wrapping counter.

LayoutTests:

* fast/text/simple-line-layout-hyphen-limit-lines-expected.html: Added.
* fast/text/simple-line-layout-hyphen-limit-lines.html: Added.
* fast/text/simple-line-layout-hyphen-limit-lines2-expected.html: Added.
* fast/text/simple-line-layout-hyphen-limit-lines2.html: Added.
* platform/mac/fast/text/hyphenate-limit-lines-expected.txt: progression

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@211228 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines-expected.html [new file with mode: 0644]
LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines.html [new file with mode: 0644]
LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines2-expected.html [new file with mode: 0644]
LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines2.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/text/hyphenate-limit-lines-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/rendering/SimpleLineLayout.cpp
Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp
Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h

index 299ff53..e081d26 100644 (file)
@@ -1,5 +1,19 @@
 2017-01-26  Zalan Bujtas  <zalan@apple.com>
 
+        Simple line layout: Add support for -webkit-hyphenate-limit-lines
+        https://bugs.webkit.org/show_bug.cgi?id=167446
+        <rdar://problem/30194030>
+
+        Reviewed by Antti Koivisto.
+
+        * fast/text/simple-line-layout-hyphen-limit-lines-expected.html: Added.
+        * fast/text/simple-line-layout-hyphen-limit-lines.html: Added.
+        * fast/text/simple-line-layout-hyphen-limit-lines2-expected.html: Added.
+        * fast/text/simple-line-layout-hyphen-limit-lines2.html: Added.
+        * platform/mac/fast/text/hyphenate-limit-lines-expected.txt: progression
+
+2017-01-26  Zalan Bujtas  <zalan@apple.com>
+
         Simple line layout: Add support for -webkit-hyphenate-limit-after and -webkit-hyphenate-limit-before
         https://bugs.webkit.org/show_bug.cgi?id=167439
         <rdar://problem/30180184>
diff --git a/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines-expected.html b/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines-expected.html
new file mode 100644 (file)
index 0000000..d77944d
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphenate-limit-lines</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto; 
+  width: 35px;
+  border: 1px solid green;
+  margin-right: 100px;
+  vertical-align: top;
+}
+</style>
+<script>
+if (internal.settings)
+    internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+</head>
+<body>
+<div style="-webkit-hyphenate-limit-lines: 0;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 1;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 2;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 3;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 4;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 5;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines.html b/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines.html
new file mode 100644 (file)
index 0000000..081ac1c
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphenate-limit-lines</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto; 
+  width: 35px;
+  border: 1px solid green;
+  margin-right: 100px;
+  vertical-align: top;
+}
+</style>
+</head>
+<body>
+<div style="-webkit-hyphenate-limit-lines: 0;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 1;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 2;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 3;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 4;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+<div style="-webkit-hyphenate-limit-lines: 5;">accoutrements accessories anomalistic auspicious favorable prosperous circumlocution conviviality coruscant cuddlesome cynosure equanimity excogitate gasconading idiosyncratic luminescent magnanimous nidificate penultimate perfidiousness perspicacious proficuous profitable advantageous remunerative profitability saxicolous sesquipedalian superabundant unencumbered responsibilities unparagoned peerless</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines2-expected.html b/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines2-expected.html
new file mode 100644 (file)
index 0000000..4771ac3
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphenate-limit-lines</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto;
+  width: 40px;
+  border: 1px solid green;
+  margin-right: 100px;
+  vertical-align: top;
+}
+</style>
+<script>
+if (internal.settings)
+    internals.settings.setSimpleLineLayoutEnabled(false);
+</script>
+</head>
+<body>
+<div style="-webkit-hyphenate-limit-lines: 0;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 1;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 2;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 3;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 4;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 5;">foobarness foobarnessability</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines2.html b/LayoutTests/fast/text/simple-line-layout-hyphen-limit-lines2.html
new file mode 100644 (file)
index 0000000..5424931
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphenate-limit-lines</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto;
+  width: 40px;
+  border: 1px solid green;
+  margin-right: 100px;
+  vertical-align: top;
+}
+</style>
+</head>
+<body>
+<div style="-webkit-hyphenate-limit-lines: 0;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 1;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 2;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 3;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 4;">foobarness foobarnessability</div>
+<div style="-webkit-hyphenate-limit-lines: 5;">foobarness foobarnessability</div>
+</body>
+</html>
index c82b959..1f5a999 100644 (file)
@@ -1,7 +1,7 @@
-layer at (0,0) size 785x1066
+layer at (0,0) size 785x1035
   RenderView at (0,0) size 785x600
-layer at (0,0) size 785x1066
-  RenderBlock {HTML} at (0,0) size 785x1066
+layer at (0,0) size 785x1035
+  RenderBlock {HTML} at (0,0) size 785x1035
     RenderBody {BODY} at (8,8) size 769x584
       RenderBlock (floating) {DIV} at (4,0) size 202x498 [border: (1px solid #ADD8E6)]
         RenderText {#text} at (1,1) size 200x496
@@ -47,8 +47,8 @@ layer at (0,0) size 785x1066
           text run at (1,435) width 200: "probably first in" + hyphen string "-"
           text run at (1,466) width 109: "vented by "
           text run at (109,466) width 61: "Plato."
-      RenderBlock (floating) {DIV} at (424,0) size 202x529 [border: (1px solid #ADD8E6)]
-        RenderText {#text} at (1,1) size 200x527
+      RenderBlock (floating) {DIV} at (424,0) size 202x498 [border: (1px solid #ADD8E6)]
+        RenderText {#text} at (1,1) size 200x496
           text run at (1,1) width 200: "also the division of"
           text run at (1,32) width 200: "the mind into the"
           text run at (1,63) width 200: "rational, concupis" + hyphen string "-"
@@ -57,18 +57,19 @@ layer at (0,0) size 785x1066
           text run at (1,125) width 200: "elements, or of"
           text run at (1,156) width 200: "pleasures and de" + hyphen string "-"
           text run at (1,187) width 200: "sires into neces" + hyphen string "-"
-          text run at (1,218) width 200: "sary and"
-          text run at (1,249) width 154: "unnecessary\x{2014}"
-          text run at (1,280) width 200: "these and other"
-          text run at (1,311) width 200: "great forms of"
-          text run at (1,342) width 200: "thought are all of"
-          text run at (1,373) width 67: "them "
-          text run at (67,373) width 134: "to be found"
-          text run at (1,404) width 200: "in the Republic,"
-          text run at (1,435) width 200: "and were probably"
-          text run at (1,466) width 200: "first invented by"
-          text run at (1,497) width 60: "Plato."
-      RenderBlock (floating) {DIV} at (4,529) size 202x498 [border: (1px solid #ADD8E6)]
+          text run at (1,218) width 108: "sary and "
+          text run at (108,218) width 93: "unneces" + hyphen string "-"
+          text run at (1,249) width 200: "sary\x{2014}these and"
+          text run at (1,280) width 200: "other great forms"
+          text run at (1,311) width 200: "of thought are all"
+          text run at (1,342) width 129: "of them "
+          text run at (129,342) width 72: "to be"
+          text run at (1,373) width 200: "found in the Re" + hyphen string "-"
+          text run at (1,404) width 200: "public, and were"
+          text run at (1,435) width 200: "probably first in" + hyphen string "-"
+          text run at (1,466) width 109: "vented by "
+          text run at (109,466) width 61: "Plato."
+      RenderBlock (floating) {DIV} at (4,498) size 202x498 [border: (1px solid #ADD8E6)]
         RenderText {#text} at (1,1) size 200x496
           text run at (1,1) width 200: "also the division of"
           text run at (1,32) width 200: "the mind into the"
@@ -77,20 +78,20 @@ layer at (0,0) size 785x1066
           text run at (112,94) width 89: "irascible"
           text run at (1,125) width 200: "elements, or of"
           text run at (1,156) width 200: "pleasures and de" + hyphen string "-"
-          text run at (1,187) width 200: "sires into"
-          text run at (1,218) width 166: "necessary and "
-          text run at (166,218) width 35: "un" + hyphen string "-"
-          text run at (1,249) width 181: "necessary\x{2014}these"
-          text run at (1,280) width 200: "and other great"
-          text run at (1,311) width 200: "forms of thought"
-          text run at (1,342) width 180: "are all of them "
-          text run at (180,342) width 21: "to"
-          text run at (1,373) width 200: "be found in the"
-          text run at (1,404) width 200: "Republic, and"
-          text run at (1,435) width 200: "were probably first"
-          text run at (1,466) width 129: "invented by "
-          text run at (129,466) width 61: "Plato."
-      RenderBlock (floating) {DIV} at (214,529) size 202x529 [border: (1px solid #ADD8E6)]
+          text run at (1,187) width 200: "sires into neces" + hyphen string "-"
+          text run at (1,218) width 108: "sary and "
+          text run at (108,218) width 93: "unneces" + hyphen string "-"
+          text run at (1,249) width 200: "sary\x{2014}these and"
+          text run at (1,280) width 200: "other great forms"
+          text run at (1,311) width 200: "of thought are all"
+          text run at (1,342) width 129: "of them "
+          text run at (129,342) width 72: "to be"
+          text run at (1,373) width 200: "found in the Re" + hyphen string "-"
+          text run at (1,404) width 200: "public, and were"
+          text run at (1,435) width 200: "probably first in" + hyphen string "-"
+          text run at (1,466) width 109: "vented by "
+          text run at (109,466) width 61: "Plato."
+      RenderBlock (floating) {DIV} at (214,498) size 202x529 [border: (1px solid #ADD8E6)]
         RenderText {#text} at (1,1) size 200x527
           text run at (1,1) width 200: "also the division of"
           text run at (1,32) width 200: "the mind into the"
@@ -100,7 +101,7 @@ layer at (0,0) size 785x1066
           text run at (1,156) width 200: "or of pleasures and"
           text run at (1,187) width 200: "desires into"
           text run at (1,218) width 200: "necessary and"
-          text run at (1,249) width 154: "unnecessary\x{2014}"
+          text run at (1,249) width 200: "unnecessary\x{2014}"
           text run at (1,280) width 200: "these and other"
           text run at (1,311) width 200: "great forms of"
           text run at (1,342) width 200: "thought are all of"
index f3f1bf8..336d981 100644 (file)
@@ -1,3 +1,27 @@
+2017-01-26  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: Add support for -webkit-hyphenate-limit-lines
+        https://bugs.webkit.org/show_bug.cgi?id=167446
+        <rdar://problem/30194030>
+
+        Reviewed by Antti Koivisto.
+
+        Now we can set the limit on the number of lines that a word can split across through hyphenation.
+
+        Tests: fast/text/simple-line-layout-hyphen-limit-lines.html
+               fast/text/simple-line-layout-hyphen-limit-lines2.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::canUseForStyle):
+        (WebCore::SimpleLineLayout::splitFragmentToFitLine):
+        (WebCore::SimpleLineLayout::printReason):
+        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
+        * rendering/SimpleLineLayoutTextFragmentIterator.h:
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::TextFragment):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::wrappingWithHyphenCounter):
+        (WebCore::SimpleLineLayout::TextFragmentIterator::TextFragment::splitWithHyphen): The right side of the split has +1 on the wrapping counter.
+
 2017-01-26  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Add support for recognizing data interaction gestures in WebKit2
index a1dc70c..ef74e96 100644 (file)
@@ -86,34 +86,33 @@ enum AvoidanceReason_ : uint64_t {
     FlowHasRTLOrdering                    = 1LLU  << 20,
     FlowHasLineAlignEdges                 = 1LLU  << 21,
     FlowHasLineSnap                       = 1LLU  << 22,
-    FlowHasHypensLineLimit                = 1LLU  << 23,
-    FlowHasTextEmphasisFillOrMark         = 1LLU  << 24,
-    FlowHasTextShadow                     = 1LLU  << 25,
-    FlowHasPseudoFirstLine                = 1LLU  << 26,
-    FlowHasPseudoFirstLetter              = 1LLU  << 27,
-    FlowHasTextCombine                    = 1LLU  << 28,
-    FlowHasTextFillBox                    = 1LLU  << 29,
-    FlowHasBorderFitLines                 = 1LLU  << 30,
-    FlowHasNonAutoLineBreak               = 1LLU  << 31,
-    FlowHasNonAutoTrailingWord            = 1LLU  << 32,
-    FlowHasSVGFont                        = 1LLU  << 33,
-    FlowTextIsEmpty                       = 1LLU  << 34,
-    FlowTextHasSoftHyphen                 = 1LLU  << 35,
-    FlowTextHasDirectionCharacter         = 1LLU  << 36,
-    FlowIsMissingPrimaryFont              = 1LLU  << 37,
-    FlowFontIsMissingGlyph                = 1LLU  << 38,
-    FlowTextIsCombineText                 = 1LLU  << 39,
-    FlowTextIsRenderCounter               = 1LLU  << 40,
-    FlowTextIsRenderQuote                 = 1LLU  << 41,
-    FlowTextIsTextFragment                = 1LLU  << 42,
-    FlowTextIsSVGInlineText               = 1LLU  << 43,
-    FlowFontIsNotSimple                   = 1LLU  << 44,
-    FeatureIsDisabled                     = 1LLU  << 45,
-    FlowHasNoParent                       = 1LLU  << 46,
-    FlowHasNoChild                        = 1LLU  << 47,
-    FlowChildIsSelected                   = 1LLU  << 48,
-    FlowHasHangingPunctuation             = 1LLU  << 49,
-    EndOfReasons                          = 1LLU  << 50
+    FlowHasTextEmphasisFillOrMark         = 1LLU  << 23,
+    FlowHasTextShadow                     = 1LLU  << 24,
+    FlowHasPseudoFirstLine                = 1LLU  << 25,
+    FlowHasPseudoFirstLetter              = 1LLU  << 26,
+    FlowHasTextCombine                    = 1LLU  << 27,
+    FlowHasTextFillBox                    = 1LLU  << 28,
+    FlowHasBorderFitLines                 = 1LLU  << 29,
+    FlowHasNonAutoLineBreak               = 1LLU  << 30,
+    FlowHasNonAutoTrailingWord            = 1LLU  << 31,
+    FlowHasSVGFont                        = 1LLU  << 32,
+    FlowTextIsEmpty                       = 1LLU  << 33,
+    FlowTextHasSoftHyphen                 = 1LLU  << 34,
+    FlowTextHasDirectionCharacter         = 1LLU  << 35,
+    FlowIsMissingPrimaryFont              = 1LLU  << 36,
+    FlowFontIsMissingGlyph                = 1LLU  << 37,
+    FlowTextIsCombineText                 = 1LLU  << 38,
+    FlowTextIsRenderCounter               = 1LLU  << 39,
+    FlowTextIsRenderQuote                 = 1LLU  << 40,
+    FlowTextIsTextFragment                = 1LLU  << 41,
+    FlowTextIsSVGInlineText               = 1LLU  << 42,
+    FlowFontIsNotSimple                   = 1LLU  << 43,
+    FeatureIsDisabled                     = 1LLU  << 44,
+    FlowHasNoParent                       = 1LLU  << 45,
+    FlowHasNoChild                        = 1LLU  << 46,
+    FlowChildIsSelected                   = 1LLU  << 47,
+    FlowHasHangingPunctuation             = 1LLU  << 48,
+    EndOfReasons                          = 1LLU  << 49
 };
 const unsigned NoReason = 0;
 
@@ -237,8 +236,6 @@ static AvoidanceReasonFlags canUseForStyle(const RenderStyle& style, IncludeReas
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineAlignEdges, reasons, includeReasons);
     if (style.lineSnap() != LineSnapNone)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasLineSnap, reasons, includeReasons);
-    if (style.hyphenationLimitLines() != RenderStyle::initialHyphenationLimitLines())
-        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasHypensLineLimit, reasons, includeReasons);
     if (style.textEmphasisFill() != TextEmphasisFillFilled || style.textEmphasisMark() != TextEmphasisMarkNone)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextEmphasisFillOrMark, reasons, includeReasons);
     if (style.textShadow())
@@ -617,6 +614,31 @@ static void updateLineConstrains(const RenderBlockFlow& flow, LineState& line, b
     line.setAvailableWidth(std::max<float>(0, logicalRightOffset - line.logicalLeftOffset()));
 }
 
+static std::optional<unsigned> hyphenPositionForFragment(unsigned splitPosition, TextFragmentIterator::TextFragment& fragmentToSplit,
+    const TextFragmentIterator& textFragmentIterator, float availableWidth)
+{
+    auto& style = textFragmentIterator.style();
+    bool shouldHyphenate = style.shouldHyphenate && (!style.hyphenLimitLines || fragmentToSplit.wrappingWithHyphenCounter() < *style.hyphenLimitLines);
+    if (!shouldHyphenate)
+        return std::nullopt;
+
+    if (!enoughWidthForHyphenation(availableWidth, style.font.pixelSize()))
+        return std::nullopt;
+
+    // We might be able to fit the hyphen at the split position.
+    auto splitPositionWithHyphen = splitPosition;
+    // Find a splitting position where hyphen surely fits.
+    unsigned start = fragmentToSplit.start();
+    auto leftSideWidth = textFragmentIterator.textWidth(start, splitPosition, 0);
+    while (leftSideWidth + style.hyphenStringWidth > availableWidth) {
+        if (--splitPositionWithHyphen <= start)
+            return std::nullopt; // No space for hyphen.
+        leftSideWidth -= textFragmentIterator.textWidth(splitPositionWithHyphen, splitPositionWithHyphen + 1, 0);
+    }
+    ASSERT(splitPositionWithHyphen > start);
+    return textFragmentIterator.lastHyphenPosition(fragmentToSplit, splitPositionWithHyphen + 1);
+}
+
 static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIterator::TextFragment& fragmentToSplit, float availableWidth, bool keepAtLeastOneCharacter, const TextFragmentIterator& textFragmentIterator)
 {
     // FIXME: add surrogate pair support.
@@ -626,26 +648,12 @@ static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIte
         return availableWidth < textFragmentIterator.textWidth(start, index + 1, 0);
     });
     unsigned splitPosition = (*it);
-    auto& style = textFragmentIterator.style();
     // Does first character fit this line?
-    if (splitPosition == fragmentToSplit.start()) {
+    if (splitPosition == 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);
-        }
-    }
+    } else if (auto hyphenPosition = hyphenPositionForFragment(splitPosition, fragmentToSplit, textFragmentIterator, availableWidth))
+        return fragmentToSplit.splitWithHyphen(*hyphenPosition, textFragmentIterator);
     return fragmentToSplit.split(splitPosition, textFragmentIterator);
 }
 
@@ -989,9 +997,6 @@ static void printReason(AvoidanceReason reason, TextStream& stream)
     case FlowHasLineSnap:
         stream << "-webkit-line-snap property";
         break;
-    case FlowHasHypensLineLimit:
-        stream << "-webkit-hyphenate-limit-lines property";
-        break;
     case FlowHasTextEmphasisFillOrMark:
         stream << "text-emphasis (fill/mark)";
         break;
index 3294b46..21708e3 100644 (file)
@@ -53,6 +53,8 @@ TextFragmentIterator::Style::Style(const RenderStyle& style)
     , hyphenLimitAfter(style.hyphenationLimitAfter() < 0 ? 2 : style.hyphenationLimitAfter())
     , locale(style.locale())
 {
+    if (style.hyphenationLimitLines() > -1)
+        hyphenLimitLines = style.hyphenationLimitLines();
 }
 
 TextFragmentIterator::TextFragmentIterator(const RenderBlockFlow& flow)
index cd3cdb6..a57a807 100644 (file)
@@ -43,7 +43,7 @@ public:
     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, bool hasHyphen = false)
+        TextFragment(unsigned start, unsigned end, float width, Type type, bool isLastInRenderer = false, bool overlapsToNextRenderer = false, bool isCollapsed = false, bool isCollapsible = false)
             : m_start(start)
             , m_end(end)
             , m_width(width)
@@ -52,7 +52,6 @@ public:
             , m_overlapsToNextRenderer(overlapsToNextRenderer)
             , m_isCollapsed(isCollapsed)
             , m_isCollapsible(isCollapsible)
-            , m_hasHyphen(hasHyphen)
         {
         }
 
@@ -66,6 +65,7 @@ public:
         bool isCollapsed() const { return m_isCollapsed; }
         bool isCollapsible() const { return m_isCollapsible; }
         bool hasHyphen() const { return m_hasHyphen; }
+        unsigned wrappingWithHyphenCounter() const { return m_hyphenationCounter; }
 
         bool isEmpty() const { return start() == end() && !isLineBreak(); }
         TextFragment split(unsigned splitPosition, const TextFragmentIterator&);
@@ -93,6 +93,7 @@ public:
         bool m_isCollapsed { false };
         bool m_isCollapsible { false };
         bool m_hasHyphen { false };
+        unsigned m_hyphenationCounter { 0 };
     };
     TextFragment nextTextFragment(float xPosition = 0);
     void revertToEndOfFragment(const TextFragment&);
@@ -121,6 +122,7 @@ public:
         unsigned hyphenLimitBefore;
         unsigned hyphenLimitAfter;
         AtomicString locale;
+        std::optional<unsigned> hyphenLimitLines;
     };
     const Style& style() const { return m_style; }
 
@@ -168,6 +170,7 @@ inline TextFragmentIterator::TextFragment TextFragmentIterator::TextFragment::sp
 {
     ASSERT(textFragmentIterator.style().shouldHyphenate);
     auto rightSide = split(hyphenPosition, textFragmentIterator);
+    rightSide.m_hyphenationCounter = m_hyphenationCounter + 1;
     m_hasHyphen = true;
     m_width += textFragmentIterator.style().hyphenStringWidth;
     return rightSide;