Title: [253938] trunk/Source/WebCore
- Revision
- 253938
- Author
- [email protected]
- Date
- 2019-12-29 11:33:29 -0800 (Sun, 29 Dec 2019)
Log Message
[LFC][IFC] Implement LineBuilder::revert
https://bugs.webkit.org/show_bug.cgi?id=205629
<rdar://problem/58231425>
Reviewed by Antti Koivisto.
LineBuilder::revert simply removes trailing runs, shrinks the line and rebuilds the collapsible content.
* layout/inlineformatting/InlineLineBuilder.cpp:
(WebCore::Layout::HangingContent::width const):
(WebCore::Layout::HangingContent::isConditional const):
(WebCore::Layout::HangingContent::setIsConditional):
(WebCore::Layout::HangingContent::expand):
(WebCore::Layout::HangingContent::reset):
(WebCore::Layout::LineBuilder::initialize):
(WebCore::Layout::LineBuilder::close):
(WebCore::Layout::LineBuilder::revert):
(WebCore::Layout::LineBuilder::alignHorizontally):
(WebCore::Layout::LineBuilder::collectHangingContent):
* layout/inlineformatting/InlineLineBuilder.h:
(WebCore::Layout::LineBuilder::InlineItemRun::operator== const):
(WebCore::Layout::LineBuilder::InlineItemRun::operator!= const):
(WebCore::Layout::LineBuilder::HangingContent::width const): Deleted. Remove m_hangingContent so that revert does not need to deal with it.
(WebCore::Layout::LineBuilder::HangingContent::isConditional const): Deleted.
(WebCore::Layout::LineBuilder::HangingContent::setIsConditional): Deleted.
(WebCore::Layout::LineBuilder::HangingContent::expand): Deleted.
(WebCore::Layout::LineBuilder::HangingContent::reset): Deleted.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (253937 => 253938)
--- trunk/Source/WebCore/ChangeLog 2019-12-29 18:28:25 UTC (rev 253937)
+++ trunk/Source/WebCore/ChangeLog 2019-12-29 19:33:29 UTC (rev 253938)
@@ -1,5 +1,35 @@
2019-12-29 Zalan Bujtas <[email protected]>
+ [LFC][IFC] Implement LineBuilder::revert
+ https://bugs.webkit.org/show_bug.cgi?id=205629
+ <rdar://problem/58231425>
+
+ Reviewed by Antti Koivisto.
+
+ LineBuilder::revert simply removes trailing runs, shrinks the line and rebuilds the collapsible content.
+
+ * layout/inlineformatting/InlineLineBuilder.cpp:
+ (WebCore::Layout::HangingContent::width const):
+ (WebCore::Layout::HangingContent::isConditional const):
+ (WebCore::Layout::HangingContent::setIsConditional):
+ (WebCore::Layout::HangingContent::expand):
+ (WebCore::Layout::HangingContent::reset):
+ (WebCore::Layout::LineBuilder::initialize):
+ (WebCore::Layout::LineBuilder::close):
+ (WebCore::Layout::LineBuilder::revert):
+ (WebCore::Layout::LineBuilder::alignHorizontally):
+ (WebCore::Layout::LineBuilder::collectHangingContent):
+ * layout/inlineformatting/InlineLineBuilder.h:
+ (WebCore::Layout::LineBuilder::InlineItemRun::operator== const):
+ (WebCore::Layout::LineBuilder::InlineItemRun::operator!= const):
+ (WebCore::Layout::LineBuilder::HangingContent::width const): Deleted. Remove m_hangingContent so that revert does not need to deal with it.
+ (WebCore::Layout::LineBuilder::HangingContent::isConditional const): Deleted.
+ (WebCore::Layout::LineBuilder::HangingContent::setIsConditional): Deleted.
+ (WebCore::Layout::LineBuilder::HangingContent::expand): Deleted.
+ (WebCore::Layout::LineBuilder::HangingContent::reset): Deleted.
+
+2019-12-29 Zalan Bujtas <[email protected]>
+
[LFC][IFC] Add LineBreaker::Result::Revert to indicate an earlier line wrap opportunity
https://bugs.webkit.org/show_bug.cgi?id=205623
<rdar://problem/58228339>
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (253937 => 253938)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp 2019-12-29 18:28:25 UTC (rev 253937)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp 2019-12-29 19:33:29 UTC (rev 253938)
@@ -43,6 +43,27 @@
return whitespace == WhiteSpace::Pre || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::BreakSpaces;
}
+struct HangingContent {
+public:
+ void reset();
+
+ InlineLayoutUnit width() const { return m_width; }
+ bool isConditional() const { return m_isConditional; }
+
+ void setIsConditional() { m_isConditional = true; }
+ void expand(InlineLayoutUnit width) { m_width += width; }
+
+private:
+ bool m_isConditional { false };
+ InlineLayoutUnit m_width { 0 };
+};
+
+void HangingContent::reset()
+{
+ m_isConditional = false;
+ m_width = 0;
+}
+
struct LineBuilder::ContinousContent {
public:
ContinousContent(const InlineItemRun&, bool textIsAlignJustify);
@@ -192,7 +213,6 @@
m_inlineItemRuns.clear();
m_collapsibleContent.reset();
- m_hangingContent.reset();
m_lineIsVisuallyEmptyBeforeCollapsibleContent = { };
}
@@ -210,7 +230,7 @@
// 2. Join text runs together when possible [foo][ ][bar] -> [foo bar].
// 3. Align merged runs both vertically and horizontally.
removeTrailingCollapsibleContent();
- collectHangingContent(isLastLineWithInlineContent);
+ auto hangingContent = collectHangingContent(isLastLineWithInlineContent);
RunList runList;
unsigned runIndex = 0;
while (runIndex < m_inlineItemRuns.size()) {
@@ -238,11 +258,61 @@
m_lineBox.resetDescent();
}
alignContentVertically(runList);
- alignHorizontally(runList, isLastLineWithInlineContent);
+ alignHorizontally(runList, hangingContent, isLastLineWithInlineContent);
}
return runList;
}
+void LineBuilder::revert(const InlineItem& revertTo)
+{
+ // 1. Remove and shrink the trailing content.
+ // 2. Rebuild collapsible trailing whitespace content.
+ ASSERT(!m_inlineItemRuns.isEmpty());
+ ASSERT(m_inlineItemRuns.last() != revertTo);
+ auto revertedWidth = InlineLayoutUnit { };
+ auto index = m_inlineItemRuns.size() - 1;
+ while (index >= 0 && m_inlineItemRuns[index] != revertTo)
+ revertedWidth += m_inlineItemRuns[index--].logicalWidth();
+ m_lineBox.shrinkHorizontally(revertedWidth);
+ m_inlineItemRuns.shrink(index + 1);
+ // Should never need to clear the line.
+ ASSERT(!m_inlineItemRuns.isEmpty());
+
+ // It's easier just to rebuild trailing collapsible content.
+ m_collapsibleContent.reset();
+ m_lineIsVisuallyEmptyBeforeCollapsibleContent = isVisuallyEmpty();
+ // Find the first collapsible run.
+ Optional<size_t> firstCollapsibleRunIndex;
+ for (auto index = m_inlineItemRuns.size(); index--;) {
+ auto& inlineItemRun = m_inlineItemRuns[index];
+ if (inlineItemRun.isContainerStart() || inlineItemRun.isContainerEnd())
+ continue;
+ auto hasCollapsibleContent = inlineItemRun.isCollapsibleWhitespace() || inlineItemRun.hasTrailingLetterSpacing();
+ if (!hasCollapsibleContent)
+ break;
+ if (inlineItemRun.isCollapsibleWhitespace()) {
+ firstCollapsibleRunIndex = index;
+ continue;
+ }
+ if (inlineItemRun.hasTrailingLetterSpacing()) {
+ // While trailing letter spacing is considered collapsible, it is supposed to be last one in the list.
+ firstCollapsibleRunIndex = index;
+ break;
+ }
+ }
+ // Forward-append runs to m_collapsibleContent.
+ if (firstCollapsibleRunIndex) {
+ for (auto index = *firstCollapsibleRunIndex; index < m_inlineItemRuns.size(); ++index) {
+ auto& inlineItemRun = m_inlineItemRuns[index];
+ if (inlineItemRun.isContainerStart() || inlineItemRun.isContainerEnd())
+ continue;
+ ASSERT(inlineItemRun.isText());
+ m_collapsibleContent.append(index);
+ }
+ }
+ // Consider alternative solutions if the (edge case)revert gets overly complicated.
+}
+
void LineBuilder::alignContentVertically(RunList& runList)
{
ASSERT(!m_isIntrinsicSizing);
@@ -330,10 +400,10 @@
}
}
-void LineBuilder::alignHorizontally(RunList& runList, IsLastLineWithInlineContent lastLine)
+void LineBuilder::alignHorizontally(RunList& runList, const HangingContent& hangingContent, IsLastLineWithInlineContent lastLine)
{
ASSERT(!m_isIntrinsicSizing);
- auto availableWidth = this->availableWidth() + m_hangingContent.width();
+ auto availableWidth = this->availableWidth() + hangingContent.width();
if (runList.isEmpty() || availableWidth <= 0)
return;
@@ -409,17 +479,18 @@
m_lineIsVisuallyEmptyBeforeCollapsibleContent = { };
}
-void LineBuilder::collectHangingContent(IsLastLineWithInlineContent isLastLineWithInlineContent)
+HangingContent LineBuilder::collectHangingContent(IsLastLineWithInlineContent isLastLineWithInlineContent)
{
+ auto hangingContent = HangingContent { };
// Can't setup hanging content with removable trailing whitspaces.
ASSERT(m_collapsibleContent.isEmpty());
if (isLastLineWithInlineContent == IsLastLineWithInlineContent::Yes)
- m_hangingContent.setIsConditional();
+ hangingContent.setIsConditional();
for (auto& inlineItemRun : WTF::makeReversedRange(m_inlineItemRuns)) {
if (inlineItemRun.isContainerStart() || inlineItemRun.isContainerEnd())
continue;
if (inlineItemRun.isLineBreak()) {
- m_hangingContent.setIsConditional();
+ hangingContent.setIsConditional();
continue;
}
if (!inlineItemRun.isText() || !inlineItemRun.isWhitespace() || inlineItemRun.isCollapsible())
@@ -428,8 +499,9 @@
if (inlineItemRun.style().whiteSpace() != WhiteSpace::PreWrap)
break;
// This is either a normal or conditionally hanging trailing whitespace.
- m_hangingContent.expand(inlineItemRun.logicalWidth());
+ hangingContent.expand(inlineItemRun.logicalWidth());
}
+ return hangingContent;
}
void LineBuilder::moveLogicalLeft(InlineLayoutUnit delta)
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h (253937 => 253938)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h 2019-12-29 18:28:25 UTC (rev 253937)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h 2019-12-29 19:33:29 UTC (rev 253938)
@@ -35,6 +35,7 @@
namespace WebCore {
namespace Layout {
+struct HangingContent;
class InlineFormattingContext;
class LineBuilder {
@@ -114,6 +115,7 @@
using RunList = Vector<Run, 50>;
enum class IsLastLineWithInlineContent { No, Yes };
RunList close(IsLastLineWithInlineContent = IsLastLineWithInlineContent::No);
+ void revert(const InlineItem& revertTo);
static Display::LineBox::Baseline halfLeadingMetrics(const FontMetrics&, InlineLayoutUnit lineLogicalHeight);
@@ -140,8 +142,8 @@
void appendLineBreak(const InlineItem&);
void removeTrailingCollapsibleContent();
- void collectHangingContent(IsLastLineWithInlineContent);
- void alignHorizontally(RunList&, IsLastLineWithInlineContent);
+ HangingContent collectHangingContent(IsLastLineWithInlineContent);
+ void alignHorizontally(RunList&, const HangingContent&, IsLastLineWithInlineContent);
void alignContentVertically(RunList&);
void adjustBaselineAndLineHeight(const Run&);
@@ -192,6 +194,9 @@
bool hasExpansionOpportunity() const { return isWhitespace() && !isCollapsedToZeroAdvanceWidth(); }
+ bool operator==(const InlineItem& other) const { return &other == &m_inlineItem; }
+ bool operator!=(const InlineItem& other) const { return !(*this == other); }
+
private:
const InlineItem& m_inlineItem;
InlineLayoutUnit m_logicalLeft { 0 };
@@ -224,25 +229,9 @@
bool m_lastRunIsFullyCollapsible { false };
};
- struct HangingContent {
- public:
- void reset();
-
- InlineLayoutUnit width() const { return m_width; }
- bool isConditional() const { return m_isConditional; }
-
- void setIsConditional() { m_isConditional = true; }
- void expand(InlineLayoutUnit width) { m_width += width; }
-
- private:
- bool m_isConditional { false };
- InlineLayoutUnit m_width { 0 };
- };
-
const InlineFormattingContext& m_inlineFormattingContext;
InlineItemRunList m_inlineItemRuns;
CollapsibleContent m_collapsibleContent;
- HangingContent m_hangingContent;
Optional<Display::LineBox::Baseline> m_initialStrut;
InlineLayoutUnit m_lineLogicalWidth { 0 };
Optional<TextAlignMode> m_horizontalAlignment;
@@ -259,12 +248,6 @@
m_lastRunIsFullyCollapsible = false;
}
-inline void LineBuilder::HangingContent::reset()
-{
- m_isConditional = false;
- m_width = 0;
}
-
}
-}
#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes