Simple line layout: Adjust hyphenation constrains based on the normal line layout...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Mar 2017 21:58:39 +0000 (21:58 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Mar 2017 21:58:39 +0000 (21:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169617

Source/WebCore:

Reviewed by Antti Koivisto.

This patch ensures that simple line layout ends up with the same hyphenation context as normal line layout.

Test: fast/text/simple-line-layout-hyphenation-constrains.html

* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::hyphenPositionForFragment): see webkit.org/b/169613
(WebCore::SimpleLineLayout::splitFragmentToFitLine):
* rendering/line/BreakingContext.h: Integral -> fractional.
(WebCore::tryHyphenating):

LayoutTests:

Reviewed by Antti Koivisto.

* fast/text/simple-line-layout-hyphenation-constrains-expected.html: Added.
* fast/text/simple-line-layout-hyphenation-constrains.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/text/simple-line-layout-hyphenation-constrains-expected.html [new file with mode: 0644]
LayoutTests/fast/text/simple-line-layout-hyphenation-constrains.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/SimpleLineLayout.cpp
Source/WebCore/rendering/line/BreakingContext.h

index 56505ed..c7aa499 100644 (file)
@@ -1,3 +1,13 @@
+2017-03-14  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: Adjust hyphenation constrains based on the normal line layout line-breaking logic.
+        https://bugs.webkit.org/show_bug.cgi?id=169617
+
+        Reviewed by Antti Koivisto.
+
+        * fast/text/simple-line-layout-hyphenation-constrains-expected.html: Added.
+        * fast/text/simple-line-layout-hyphenation-constrains.html: Added.
+
 2017-03-14  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark imported/w3c/web-platform-tests/cors/status.htm as flaky.
diff --git a/LayoutTests/fast/text/simple-line-layout-hyphenation-constrains-expected.html b/LayoutTests/fast/text/simple-line-layout-hyphenation-constrains-expected.html
new file mode 100644 (file)
index 0000000..db70d25
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphenation and enlarged font</title>
+<style>
+div {
+  display: inline-block;
+  width: 43px;
+  margin-right: 150px;
+  vertical-align: top;
+  font-size: 30px;
+}
+</style>
+</head>
+<body>
+<div>advantageous remunerative profitability</div>
+<div>saxicolous sesquipedalian superabundant</div>
+<div>unencumbered responsibilities unparagoned peerless</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/text/simple-line-layout-hyphenation-constrains.html b/LayoutTests/fast/text/simple-line-layout-hyphenation-constrains.html
new file mode 100644 (file)
index 0000000..99f5ea0
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that simple and normal line layout produce the same lines with hyphenation and enlarged font</title>
+<style>
+div {
+  display: inline-block;
+  -webkit-hyphens: auto;
+  width: 43px;
+  margin-right: 150px;
+  vertical-align: top;
+  font-size: 30px;
+}
+</style>
+</head>
+<body>
+<div>advantageous remunerative profitability</div>
+<div>saxicolous sesquipedalian superabundant</div>
+<div>unencumbered responsibilities unparagoned peerless</div>
+</body>
+</html>
index 504687c..78e9c5e 100644 (file)
@@ -1,3 +1,20 @@
+2017-03-14  Alan Kinsley  <zalan@apple.com>
+
+        Simple line layout: Adjust hyphenation constrains based on the normal line layout line-breaking logic.
+        https://bugs.webkit.org/show_bug.cgi?id=169617
+
+        Reviewed by Antti Koivisto.
+
+        This patch ensures that simple line layout ends up with the same hyphenation context as normal line layout. 
+
+        Test: fast/text/simple-line-layout-hyphenation-constrains.html
+
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::hyphenPositionForFragment): see webkit.org/b/169613
+        (WebCore::SimpleLineLayout::splitFragmentToFitLine):
+        * rendering/line/BreakingContext.h: Integral -> fractional.
+        (WebCore::tryHyphenating):
+
 2017-03-06  Jer Noble  <jer.noble@apple.com>
 
         Refactor: Allow WebKit2 to override the creation of RealtimeMediaSources
index 7f73b17..f63a869 100644 (file)
@@ -612,14 +612,19 @@ static void updateLineConstrains(const RenderBlockFlow& flow, LineState& line, c
 }
 
 static std::optional<unsigned> hyphenPositionForFragment(unsigned splitPosition, TextFragmentIterator::TextFragment& fragmentToSplit,
-    const TextFragmentIterator& textFragmentIterator, float availableWidth)
+    const TextFragmentIterator& textFragmentIterator, float availableWidth, bool lineIsEmpty)
 {
     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()))
+    // FIXME: This is a workaround for webkit.org/b/169613. See maxPrefixWidth computation in tryHyphenating().
+    // It does not work properly with non-collapsed leading tabs when font is enlarged.
+    auto adjustedAvailableWidth = availableWidth - style.hyphenStringWidth;
+    if (!lineIsEmpty)
+        adjustedAvailableWidth += style.spaceWidth;
+    if (!enoughWidthForHyphenation(adjustedAvailableWidth, style.font.pixelSize()))
         return std::nullopt;
 
     // We might be able to fit the hyphen at the split position.
@@ -636,7 +641,7 @@ static std::optional<unsigned> hyphenPositionForFragment(unsigned splitPosition,
     return textFragmentIterator.lastHyphenPosition(fragmentToSplit, splitPositionWithHyphen + 1);
 }
 
-static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIterator::TextFragment& fragmentToSplit, float availableWidth, bool keepAtLeastOneCharacter, const TextFragmentIterator& textFragmentIterator)
+static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIterator::TextFragment& fragmentToSplit, float availableWidth, bool lineIsEmpty, const TextFragmentIterator& textFragmentIterator)
 {
     // FIXME: add surrogate pair support.
     unsigned start = fragmentToSplit.start();
@@ -647,9 +652,9 @@ static TextFragmentIterator::TextFragment splitFragmentToFitLine(TextFragmentIte
     unsigned splitPosition = (*it);
     // Does first character fit this line?
     if (splitPosition == start) {
-        if (keepAtLeastOneCharacter)
+        if (lineIsEmpty)
             ++splitPosition;
-    } else if (auto hyphenPosition = hyphenPositionForFragment(splitPosition, fragmentToSplit, textFragmentIterator, availableWidth))
+    } else if (auto hyphenPosition = hyphenPositionForFragment(splitPosition, fragmentToSplit, textFragmentIterator, availableWidth, lineIsEmpty))
         return fragmentToSplit.splitWithHyphen(*hyphenPosition, textFragmentIterator);
     return fragmentToSplit.split(splitPosition, textFragmentIterator);
 }
index b643be1..7e22ff2 100644 (file)
@@ -662,7 +662,7 @@ inline void ensureCharacterGetsLineBox(LineWhitespaceCollapsingState& lineWhites
     lineWhitespaceCollapsingState.stopIgnoringSpaces(InlineIterator(0, textParagraphSeparator.renderer(), textParagraphSeparator.offset()));
 }
 
-inline void tryHyphenating(RenderText& text, const FontCascade& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, std::optional<unsigned> nextBreakable, bool& hyphenated)
+inline void tryHyphenating(RenderText& text, const FontCascade& font, const AtomicString& localeIdentifier, unsigned consecutiveHyphenatedLines, int consecutiveHyphenatedLinesLimit, int minimumPrefixLimit, int minimumSuffixLimit, unsigned lastSpace, unsigned pos, float xPos, float availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, std::optional<unsigned> nextBreakable, bool& hyphenated)
 {
     // Map 'hyphenate-limit-{before,after}: auto;' to 2.
     unsigned minimumPrefixLength;
@@ -684,7 +684,7 @@ inline void tryHyphenating(RenderText& text, const FontCascade& font, const Atom
     if (consecutiveHyphenatedLinesLimit >= 0 && consecutiveHyphenatedLines >= static_cast<unsigned>(consecutiveHyphenatedLinesLimit))
         return;
 
-    int hyphenWidth = measureHyphenWidth(text, font);
+    float hyphenWidth = measureHyphenWidth(text, font);
 
     float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
     if (!enoughWidthForHyphenation(maxPrefixWidth, font.pixelSize()))