Title: [267925] trunk/Source/WebCore
Revision
267925
Author
[email protected]
Date
2020-10-03 09:12:16 -0700 (Sat, 03 Oct 2020)

Log Message

[LFC][IFC][Soft hyphen] Rebuild the line when need to revert to a previous wrap opportunity due to soft hyphens
https://bugs.webkit.org/show_bug.cgi?id=217272

Reviewed by Antti Koivisto.

This patch reverts the line to a previous wrap opportunity where
1. the trailing soft hyphen fits or
2. no need for soft hyphen (we reverted back to a non-text inline content, where we don't need a hyphen) or
3. reverted all the way back to the beginning of the line.
(We still don't paint hyphens at the soft hyphen locations.)

* layout/inlineformatting/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):
(WebCore::Layout::LineBuilder::rebuildLine):
(WebCore::Layout::LineBuilder::rebuildLineForTrailingSoftHyphen):
* layout/inlineformatting/InlineLineBuilder.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (267924 => 267925)


--- trunk/Source/WebCore/ChangeLog	2020-10-03 15:12:17 UTC (rev 267924)
+++ trunk/Source/WebCore/ChangeLog	2020-10-03 16:12:16 UTC (rev 267925)
@@ -1,5 +1,24 @@
 2020-10-03  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC][Soft hyphen] Rebuild the line when need to revert to a previous wrap opportunity due to soft hyphens
+        https://bugs.webkit.org/show_bug.cgi?id=217272
+
+        Reviewed by Antti Koivisto.
+
+        This patch reverts the line to a previous wrap opportunity where
+        1. the trailing soft hyphen fits or
+        2. no need for soft hyphen (we reverted back to a non-text inline content, where we don't need a hyphen) or
+        3. reverted all the way back to the beginning of the line.
+        (We still don't paint hyphens at the soft hyphen locations.)
+
+        * layout/inlineformatting/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):
+        (WebCore::Layout::LineBuilder::rebuildLine):
+        (WebCore::Layout::LineBuilder::rebuildLineForTrailingSoftHyphen):
+        * layout/inlineformatting/InlineLineBuilder.h:
+
+2020-10-03  Zalan Bujtas  <[email protected]>
+
         [LFC][IFC][Soft hyphen] InlineContentBreaker should return Action::Revert when the trailing soft hyphen does not fit
         https://bugs.webkit.org/show_bug.cgi?id=217269
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (267924 => 267925)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2020-10-03 15:12:17 UTC (rev 267924)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2020-10-03 16:12:16 UTC (rev 267925)
@@ -613,12 +613,12 @@
         ASSERT(result.isEndOfLine == InlineContentBreaker::IsEndOfLine::Yes);
         // Not only this content can't be placed on the current line, but we even need to revert the line back to an earlier position.
         ASSERT(!m_wrapOpportunityList.isEmpty());
-        return { InlineContentBreaker::IsEndOfLine::Yes, { rebuildLine(layoutRange), true } };
+        return { InlineContentBreaker::IsEndOfLine::Yes, { rebuildLine(layoutRange, *m_wrapOpportunityList.last()), true } };
     }
     if (result.action == InlineContentBreaker::Result::Action::RevertToLastNonOverflowingWrapOpportunity) {
         ASSERT(result.isEndOfLine == InlineContentBreaker::IsEndOfLine::Yes);
-        ASSERT_NOT_IMPLEMENTED_YET();
-        return { InlineContentBreaker::IsEndOfLine::Yes, { } };
+        ASSERT(!m_wrapOpportunityList.isEmpty());
+        return { InlineContentBreaker::IsEndOfLine::Yes, { rebuildLineForTrailingSoftHyphen(layoutRange), true } };
     }
     if (result.action == InlineContentBreaker::Result::Action::Break) {
         ASSERT(result.isEndOfLine == InlineContentBreaker::IsEndOfLine::Yes);
@@ -664,34 +664,45 @@
     }
 }
 
-size_t LineBuilder::rebuildLine(const InlineItemRange& layoutRange)
+size_t LineBuilder::rebuildLine(const InlineItemRange& layoutRange, const InlineItem& lastInlineItemToAdd)
 {
     ASSERT(!m_wrapOpportunityList.isEmpty());
     // We might already have added intrusive floats. They shrink the avilable horizontal space for the line.
     // Let's just reuse what the line has at this point.
     m_line.initialize(m_line.horizontalConstraint());
-    auto* lastWrapOpportunityItem = m_wrapOpportunityList.last();
     auto currentItemIndex = layoutRange.start;
-    auto logicalRight = InlineLayoutUnit { };
     if (m_partialLeadingTextItem) {
-        auto logicalWidth = inlineItemWidth(*m_partialLeadingTextItem, logicalRight);
-        m_line.append(*m_partialLeadingTextItem, logicalWidth);
-        logicalRight += logicalWidth;
-        if (&m_partialLeadingTextItem.value() == lastWrapOpportunityItem)
+        m_line.append(*m_partialLeadingTextItem, inlineItemWidth(*m_partialLeadingTextItem, { }));
+        if (&m_partialLeadingTextItem.value() == &lastInlineItemToAdd)
             return 1;
         ++currentItemIndex;
     }
     for (; currentItemIndex < layoutRange.end; ++currentItemIndex) {
         auto& inlineItem = m_inlineItems[currentItemIndex];
-        auto logicalWidth = inlineItemWidth(inlineItem, logicalRight);
-        m_line.append(inlineItem, logicalWidth);
-        logicalRight += logicalWidth;
-        if (&inlineItem == lastWrapOpportunityItem)
+        m_line.append(inlineItem, inlineItemWidth(inlineItem, m_line.contentLogicalWidth()));
+        if (&inlineItem == &lastInlineItemToAdd)
             return currentItemIndex - layoutRange.start + 1;
     }
     return layoutRange.size();
 }
 
+size_t LineBuilder::rebuildLineForTrailingSoftHyphen(const InlineItemRange& layoutRange)
+{
+    ASSERT(!m_wrapOpportunityList.isEmpty());
+    // Revert all the way back to a wrap opportunity when either a soft hyphen fits or no hyphen is required.
+    for (auto i = m_wrapOpportunityList.size(); i-- > 1;) {
+        auto& softWrapOpportunityItem = *m_wrapOpportunityList[i];
+        // FIXME: If this turns out to be a perf issue, we could also traverse the wrap list and keep adding the items
+        // while watching the available width very closely.
+        auto index = rebuildLine(layoutRange, softWrapOpportunityItem);
+        auto trailingSoftHyphenWidth = m_line.trailingSoftHyphenWidth();
+        if (!trailingSoftHyphenWidth || trailingSoftHyphenWidth <= m_line.availableWidth())
+            return index;
+    }
+    // Have at least some content on the line.
+    return rebuildLine(layoutRange, *m_wrapOpportunityList.first());
+}
+
 bool LineBuilder::isLastLineWithInlineContent(const InlineItemRange& lineRange, size_t lastInlineItemIndex, bool hasPartialTrailingContent) const
 {
     if (hasPartialTrailingContent)

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h (267924 => 267925)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2020-10-03 15:12:17 UTC (rev 267924)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2020-10-03 16:12:16 UTC (rev 267925)
@@ -92,7 +92,8 @@
     UsedConstraints constraintsForLine(const FormattingContext::ConstraintsForInFlowContent& initialLineConstraints, bool isFirstLine);
     void commitFloats(const LineCandidate&, CommitIntrusiveFloatsOnly = CommitIntrusiveFloatsOnly::No);
     Result handleFloatsAndInlineContent(InlineContentBreaker&, const InlineItemRange& needsLayoutRange, const LineCandidate&);
-    size_t rebuildLine(const InlineItemRange& needsLayoutRange);
+    size_t rebuildLine(const InlineItemRange& needsLayoutRange, const InlineItem& lastInlineItemToAdd);
+    size_t rebuildLineForTrailingSoftHyphen(const InlineItemRange& layoutRange);
     void commitPartialContent(const InlineContentBreaker::ContinuousContent::RunList&, const InlineContentBreaker::Result::PartialTrailingContent&);
     void initialize(const UsedConstraints&);
     struct CommittedContent {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to