Title: [245850] trunk/Source/WebCore
Revision
245850
Author
[email protected]
Date
2019-05-29 09:07:19 -0700 (Wed, 29 May 2019)

Log Message

[LFC][IFC] Move Line class to a dedicated file
https://bugs.webkit.org/show_bug.cgi?id=198332
<rdar://problem/51221403>

Reviewed by Antti Koivisto.

An upcoming refactoring requires the Line class to be in a .h.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/displaytree/DisplayRun.h:
* layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
(WebCore::Layout::InlineFormattingContext::LineLayout::initializeLine const):
(WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
(WebCore::Layout::halfLeadingMetrics): Deleted.
(WebCore::Layout::Line::availableWidth const): Deleted.
(WebCore::Layout::Line::contentLogicalRight const): Deleted.
(WebCore::Layout::Line::contentLogicalWidth const): Deleted.
(WebCore::Layout::Line::logicalTop const): Deleted.
(WebCore::Layout::Line::logicalLeft const): Deleted.
(WebCore::Layout::Line::logicalRight const): Deleted.
(WebCore::Layout::Line::logicalBottom const): Deleted.
(WebCore::Layout::Line::logicalWidth const): Deleted.
(WebCore::Layout::Line::logicalHeight const): Deleted.
(WebCore::Layout::Line::LineItem::LineItem): Deleted.
(WebCore::Layout::Line::Line): Deleted.
(WebCore::Layout::Line::reset): Deleted.
(WebCore::Layout::Line::close): Deleted.
(WebCore::Layout::Line::removeTrailingTrimmableContent): Deleted.
(WebCore::Layout::Line::moveLogicalLeft): Deleted.
(WebCore::Layout::Line::moveLogicalRight): Deleted.
(WebCore::Layout::isTrimmableContent): Deleted.
(WebCore::Layout::Line::trailingTrimmableWidth const): Deleted.
(WebCore::Layout::Line::hasContent const): Deleted.
(WebCore::Layout::Line::appendNonBreakableSpace): Deleted.
(WebCore::Layout::Line::appendInlineContainerStart): Deleted.
(WebCore::Layout::Line::appendInlineContainerEnd): Deleted.
(WebCore::Layout::Line::appendTextContent): Deleted.
(WebCore::Layout::Line::appendNonReplacedInlineBox): Deleted.
(WebCore::Layout::Line::appendReplacedInlineBox): Deleted.
(WebCore::Layout::Line::appendHardLineBreak): Deleted.
* layout/inlineformatting/InlineTextItem.h:
* layout/inlineformatting/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::isTrimmableContent):
* layout/inlineformatting/text/TextUtil.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (245849 => 245850)


--- trunk/Source/WebCore/ChangeLog	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/ChangeLog	2019-05-29 16:07:19 UTC (rev 245850)
@@ -1,3 +1,51 @@
+2019-05-29  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Move Line class to a dedicated file
+        https://bugs.webkit.org/show_bug.cgi?id=198332
+        <rdar://problem/51221403>
+
+        Reviewed by Antti Koivisto.
+
+        An upcoming refactoring requires the Line class to be in a .h.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/displaytree/DisplayRun.h:
+        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
+        (WebCore::Layout::InlineFormattingContext::LineLayout::initializeLine const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
+        (WebCore::Layout::halfLeadingMetrics): Deleted.
+        (WebCore::Layout::Line::availableWidth const): Deleted.
+        (WebCore::Layout::Line::contentLogicalRight const): Deleted.
+        (WebCore::Layout::Line::contentLogicalWidth const): Deleted.
+        (WebCore::Layout::Line::logicalTop const): Deleted.
+        (WebCore::Layout::Line::logicalLeft const): Deleted.
+        (WebCore::Layout::Line::logicalRight const): Deleted.
+        (WebCore::Layout::Line::logicalBottom const): Deleted.
+        (WebCore::Layout::Line::logicalWidth const): Deleted.
+        (WebCore::Layout::Line::logicalHeight const): Deleted.
+        (WebCore::Layout::Line::LineItem::LineItem): Deleted.
+        (WebCore::Layout::Line::Line): Deleted.
+        (WebCore::Layout::Line::reset): Deleted.
+        (WebCore::Layout::Line::close): Deleted.
+        (WebCore::Layout::Line::removeTrailingTrimmableContent): Deleted.
+        (WebCore::Layout::Line::moveLogicalLeft): Deleted.
+        (WebCore::Layout::Line::moveLogicalRight): Deleted.
+        (WebCore::Layout::isTrimmableContent): Deleted.
+        (WebCore::Layout::Line::trailingTrimmableWidth const): Deleted.
+        (WebCore::Layout::Line::hasContent const): Deleted.
+        (WebCore::Layout::Line::appendNonBreakableSpace): Deleted.
+        (WebCore::Layout::Line::appendInlineContainerStart): Deleted.
+        (WebCore::Layout::Line::appendInlineContainerEnd): Deleted.
+        (WebCore::Layout::Line::appendTextContent): Deleted.
+        (WebCore::Layout::Line::appendNonReplacedInlineBox): Deleted.
+        (WebCore::Layout::Line::appendReplacedInlineBox): Deleted.
+        (WebCore::Layout::Line::appendHardLineBreak): Deleted.
+        * layout/inlineformatting/InlineTextItem.h:
+        * layout/inlineformatting/text/TextUtil.cpp:
+        (WebCore::Layout::TextUtil::isTrimmableContent):
+        * layout/inlineformatting/text/TextUtil.h:
+
 2019-05-29  Ludovico de Nittis  <[email protected]>
 
         PlatformEventKeyboardGtk still uses old key aliases

Modified: trunk/Source/WebCore/Sources.txt (245849 => 245850)


--- trunk/Source/WebCore/Sources.txt	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/Sources.txt	2019-05-29 16:07:19 UTC (rev 245850)
@@ -1349,6 +1349,7 @@
 layout/inlineformatting/InlineFormattingContextLineLayout.cpp
 layout/inlineformatting/InlineFormattingState.cpp
 layout/inlineformatting/InlineInvalidation.cpp
+layout/inlineformatting/InlineLine.cpp
 layout/inlineformatting/InlineLineBreaker.cpp
 layout/inlineformatting/InlineTextItem.cpp
 layout/inlineformatting/text/TextUtil.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (245849 => 245850)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-05-29 16:07:19 UTC (rev 245850)
@@ -2016,6 +2016,7 @@
 		6ED878C5147493F4004C3597 /* RenderTableCaption.h in Headers */ = {isa = PBXBuildFile; fileRef = 6ED878C3147493F4004C3597 /* RenderTableCaption.h */; };
 		6ED8C37A183BFF8C009E53BD /* BoxShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 6ED8C378183BFF8C009E53BD /* BoxShape.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */; };
+		6F0CD695229ED32700C5994E /* InlineLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0CD694229ED32700C5994E /* InlineLine.h */; };
 		6F1CC1DE225F8B4900720AD2 /* InlineTextItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F222B761AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */; };
 		6F3E1F622136142000A65A08 /* FloatBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F3E1F612136141700A65A08 /* FloatBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9127,6 +9128,8 @@
 		6EE8A77010F803F3005A4A24 /* JSWebGLContextAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebGLContextAttributes.cpp; sourceTree = "<group>"; };
 		6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebGLContextAttributes.h; sourceTree = "<group>"; };
 		6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BlockFormattingContextGeometry.cpp; sourceTree = "<group>"; };
+		6F0CD692229ED31900C5994E /* InlineLine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLine.cpp; sourceTree = "<group>"; };
+		6F0CD694229ED32700C5994E /* InlineLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLine.h; sourceTree = "<group>"; };
 		6F1CC1DC225F8B4100720AD2 /* InlineTextItem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineTextItem.cpp; sourceTree = "<group>"; };
 		6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlineTextItem.h; sourceTree = "<group>"; };
 		6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
@@ -16380,6 +16383,8 @@
 		115CFA9A208BC140001E6991 /* inlineformatting */ = {
 			isa = PBXGroup;
 			children = (
+				6F0CD694229ED32700C5994E /* InlineLine.h */,
+				6F0CD692229ED31900C5994E /* InlineLine.cpp */,
 				6FE7DDDD20EC6E8B008B5B4E /* text */,
 				6F7CA3C9208C2B2E002F29AB /* InlineFormattingContext.cpp */,
 				6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */,
@@ -28180,6 +28185,7 @@
 				714C7C661FDAD2A100F2BEE1 /* AnimationPlaybackEvent.h in Headers */,
 				714C7C671FDAD2A900F2BEE1 /* AnimationPlaybackEventInit.h in Headers */,
 				71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */,
+				6F0CD695229ED32700C5994E /* InlineLine.h in Headers */,
 				0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */,
 				57152B5A21CB3E88000C37CA /* ApduCommand.h in Headers */,
 				57152B5C21CC1902000C37CA /* ApduResponse.h in Headers */,

Modified: trunk/Source/WebCore/layout/displaytree/DisplayRun.h (245849 => 245850)


--- trunk/Source/WebCore/layout/displaytree/DisplayRun.h	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/layout/displaytree/DisplayRun.h	2019-05-29 16:07:19 UTC (rev 245850)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "DisplayRect.h"
 #include "InlineItem.h"
 #include "LayoutUnit.h"
 #include "TextFlags.h"

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp (245849 => 245850)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp	2019-05-29 16:07:19 UTC (rev 245850)
@@ -31,6 +31,7 @@
 #include "FloatingContext.h"
 #include "FloatingState.h"
 #include "InlineFormattingState.h"
+#include "InlineLine.h"
 #include "InlineLineBreaker.h"
 #include "LayoutBox.h"
 #include "LayoutContainer.h"
@@ -40,296 +41,6 @@
 namespace WebCore {
 namespace Layout {
 
-struct UsedHeightAndDepth {
-    LayoutUnit height;
-    LayoutUnit depth;
-};
-
-static UsedHeightAndDepth halfLeadingMetrics(const FontMetrics& fontMetrics, LayoutUnit lineLogicalHeight)
-{
-    auto ascent = fontMetrics.ascent();
-    auto descent = fontMetrics.descent();
-    // 10.8.1 Leading and half-leading
-    auto leading = lineLogicalHeight - (ascent + descent);
-    // Inline tree is all integer based.
-    auto adjustedAscent = std::max((ascent + leading / 2).floor(), 0);
-    auto adjustedDescent = std::max((descent + leading / 2).ceil(), 0);
-    return { adjustedAscent, adjustedDescent }; 
-}
-
-class Line {
-public:
-    Line(const LayoutState&);
-
-    void reset(const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimumLineHeight, LayoutUnit baselineOffset);
-
-    struct LineItem {
-        LineItem(Display::Run, const InlineItem&, bool isCollapsed, bool canBeExtended);
-
-        // Relative to the baseline.
-        Display::Run inlineRun;
-        const InlineItem& inlineItem;
-        bool isCollapsed { false };
-        bool canBeExtended { false };
-    };
-
-    using LineItems = Vector<std::unique_ptr<LineItem>>;
-    const LineItems& close();
-
-    void appendTextContent(const InlineTextItem&, LayoutSize);
-    void appendNonReplacedInlineBox(const InlineItem&, LayoutSize);
-    void appendReplacedInlineBox(const InlineItem&, LayoutSize);
-    void appendInlineContainerStart(const InlineItem&);
-    void appendInlineContainerEnd(const InlineItem&);
-    void appendHardLineBreak(const InlineItem&);
-
-    bool hasContent() const;
-
-    LayoutUnit trailingTrimmableWidth() const;
-
-    void moveLogicalLeft(LayoutUnit);
-    void moveLogicalRight(LayoutUnit);
-
-    LayoutUnit availableWidth() const { return logicalWidth() - contentLogicalWidth(); }
-    
-    LayoutUnit contentLogicalRight() const { return logicalLeft() + contentLogicalWidth(); }
-    LayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
-
-    LayoutUnit logicalTop() const { return m_logicalTopLeft.y(); }
-    LayoutUnit logicalLeft() const { return m_logicalTopLeft.x(); }
-    LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
-    LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
-    LayoutUnit logicalWidth() const { return m_lineLogicalWidth; }
-    LayoutUnit logicalHeight() const { return m_logicalHeight.height + m_logicalHeight.depth; }
-
-private:
-    void appendNonBreakableSpace(const InlineItem&, const Display::Rect& logicalRect);
-    void removeTrailingTrimmableContent();
-
-    const LayoutState& m_layoutState;
-    LineItems m_lineItems;
-    ListHashSet<LineItem*> m_trimmableContent;
-
-    LayoutPoint m_logicalTopLeft;
-    LayoutUnit m_contentLogicalWidth;
-
-    UsedHeightAndDepth m_logicalHeight;
-    LayoutUnit m_lineLogicalWidth;
-};
-
-Line::LineItem::LineItem(Display::Run inlineRun, const InlineItem& inlineItem, bool isCollapsed, bool canBeExtended)
-    : inlineRun(inlineRun)
-    , inlineItem(inlineItem)
-    , isCollapsed(isCollapsed)
-    , canBeExtended(canBeExtended)
-{
-}
-
-Line::Line(const LayoutState& layoutState)
-    : m_layoutState(layoutState)
-{
-}
-
-void Line::reset(const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimumHeight, LayoutUnit baselineOffset)
-{
-    m_logicalTopLeft = topLeft;
-    m_lineLogicalWidth = availableWidth;
-    m_logicalHeight = { baselineOffset, minimumHeight - baselineOffset };
-    
-    m_contentLogicalWidth = { };
-
-    m_lineItems.clear();
-    m_trimmableContent.clear();
-}
-
-const Line::LineItems& Line::close()
-{
-    removeTrailingTrimmableContent();
-    // Convert inline run geometry from relative to the baseline to relative to logical top.
-    for (auto& lineItem : m_lineItems) {
-        auto adjustedLogicalTop = lineItem->inlineRun.logicalTop() + m_logicalHeight.height + m_logicalTopLeft.y();
-        lineItem->inlineRun.setLogicalTop(adjustedLogicalTop);
-    }
-    return m_lineItems;
-}
-
-void Line::removeTrailingTrimmableContent()
-{
-    // Collapse trimmable trailing content
-    LayoutUnit trimmableWidth;
-    for (auto* trimmableRun : m_trimmableContent) {
-        trimmableRun->isCollapsed = true;
-        trimmableWidth += trimmableRun->inlineRun.logicalWidth();
-    }
-    m_contentLogicalWidth -= trimmableWidth;
-}
-
-void Line::moveLogicalLeft(LayoutUnit delta)
-{
-    if (!delta)
-        return;
-    ASSERT(delta > 0);
-    // Shrink the line and move the items.
-    m_logicalTopLeft.move(delta, 0);
-    m_lineLogicalWidth -= delta;
-    for (auto& lineItem : m_lineItems)
-        lineItem->inlineRun.moveHorizontally(delta);
-}
-
-void Line::moveLogicalRight(LayoutUnit delta)
-{
-    ASSERT(delta > 0);
-    m_lineLogicalWidth -= delta;
-}
-
-static bool isTrimmableContent(const InlineItem& inlineItem)
-{
-    if (!is<InlineTextItem>(inlineItem))
-        return false;
-    auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
-    return inlineTextItem.isWhitespace() && inlineTextItem.style().collapseWhiteSpace();
-}
-
-LayoutUnit Line::trailingTrimmableWidth() const
-{
-    LayoutUnit trimmableWidth;
-    for (auto* trimmableRun : m_trimmableContent)
-        trimmableWidth += trimmableRun->inlineRun.logicalWidth();
-    return trimmableWidth;
-}
-
-bool Line::hasContent() const
-{
-    // Return false for empty containers like <span></span>.
-    if (m_lineItems.isEmpty())
-        return false;
-    for (auto& lineItem : m_lineItems) {
-        if (lineItem->inlineItem.isContainerStart() || lineItem->inlineItem.isContainerEnd())
-            continue;
-        if (!lineItem->isCollapsed)
-            return true;
-    }
-    return false;
-}
-
-void Line::appendNonBreakableSpace(const InlineItem& inlineItem, const Display::Rect& logicalRect)
-{
-    m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
-    m_contentLogicalWidth += inlineItem.width();
-}
-
-void Line::appendInlineContainerStart(const InlineItem& inlineItem)
-{
-    auto& layoutBox = inlineItem.layoutBox();
-    auto& style = layoutBox.style();
-    auto& fontMetrics = style.fontMetrics();
-    
-    auto alignAndAdjustLineHeight = [&] {
-        LayoutUnit inlineBoxHeight = style.computedLineHeight();
-
-        auto halfLeading = halfLeadingMetrics(fontMetrics, inlineBoxHeight);
-        if (halfLeading.depth > 0)
-            m_logicalHeight.depth = std::max(m_logicalHeight.depth, halfLeading.depth);
-        if (halfLeading.height > 0)
-            m_logicalHeight.height = std::max(m_logicalHeight.height, halfLeading.height);
-    };
-
-    alignAndAdjustLineHeight();
-    auto& displayBox = m_layoutState.displayBoxForLayoutBox(layoutBox);
-    auto containerHeight = fontMetrics.height() + displayBox.verticalBorder() + displayBox.verticalPadding().valueOr(0);
-    auto logicalTop = -fontMetrics.ascent() - displayBox.borderTop() - displayBox.paddingTop().valueOr(0);
-    auto logicalRect = Display::Rect { logicalTop, contentLogicalRight(), inlineItem.width(), containerHeight };
-    appendNonBreakableSpace(inlineItem, logicalRect);
-}
-
-void Line::appendInlineContainerEnd(const InlineItem& inlineItem)
-{
-    // This is really just a placeholder to mark the end of the inline level container.
-    auto logicalRect = Display::Rect { 0, contentLogicalRight(), inlineItem.width(), 0 };
-    appendNonBreakableSpace(inlineItem, logicalRect);
-}
-
-void Line::appendTextContent(const InlineTextItem& inlineItem, LayoutSize runSize)
-{
-    auto isTrimmable = isTrimmableContent(inlineItem);
-    if (!isTrimmable)
-        m_trimmableContent.clear();
-
-    auto shouldCollapseCompletely = [&] {
-        if (!isTrimmable)
-            return false;
-        // Leading whitespace.
-        if (m_lineItems.isEmpty())
-            return true;
-        // Check if the last item is trimmable as well.
-        for (int index = m_lineItems.size() - 1; index >= 0; --index) {
-            auto& inlineItem = m_lineItems[index]->inlineItem;
-            if (inlineItem.isBox())
-                return false;
-            if (inlineItem.isText())
-                return inlineItem.isText() && isTrimmableContent(downcast<InlineTextItem>(inlineItem));
-            ASSERT(inlineItem.isContainerStart() || inlineItem.isContainerEnd());
-        }
-        return true;
-    };
-
-    // Collapsed line items don't contribute to the line width.
-    auto isCompletelyCollapsed = shouldCollapseCompletely();
-    auto canBeExtended = !isCompletelyCollapsed && !inlineItem.isCollapsed();
-    auto logicalRect = Display::Rect { -inlineItem.style().fontMetrics().ascent(), contentLogicalRight(), runSize.width(), runSize.height() };
-    auto textContext = Display::Run::TextContext { inlineItem.start(), inlineItem.isCollapsed() ? 1 : inlineItem.length() };
-    auto displayRun = Display::Run(logicalRect, textContext);
-
-    auto lineItem = std::make_unique<LineItem>(displayRun, inlineItem, isCompletelyCollapsed, canBeExtended);
-    if (isTrimmable) 
-        m_trimmableContent.add(lineItem.get());
-
-    m_lineItems.append(WTFMove(lineItem));
-    m_contentLogicalWidth += isCompletelyCollapsed ? LayoutUnit() : runSize.width();
-}
-
-void Line::appendNonReplacedInlineBox(const InlineItem& inlineItem, LayoutSize runSize)
-{
-    auto alignAndAdjustLineHeight = [&] {
-        auto inlineBoxHeight = runSize.height();
-        // FIXME: We need to look inside the inline-block's formatting context and check the lineboxes (if any) to be able to baseline align.
-        if (inlineItem.layoutBox().establishesInlineFormattingContext()) {
-            if (inlineBoxHeight == logicalHeight())
-                return;
-            // FIXME: This fails when the line height difference comes from font-size diff. 
-            m_logicalHeight.depth = std::max<LayoutUnit>(0, m_logicalHeight.depth);
-            m_logicalHeight.height = std::max(inlineBoxHeight, m_logicalHeight.height);
-            return;
-        }
-        // 0 descent -> baseline aligment for now.
-        m_logicalHeight.depth = std::max<LayoutUnit>(0, m_logicalHeight.depth);
-        m_logicalHeight.height = std::max(inlineBoxHeight, m_logicalHeight.height);
-    };
-
-    alignAndAdjustLineHeight();
-    auto& displayBox = m_layoutState.displayBoxForLayoutBox(inlineItem.layoutBox());
-    auto logicalTop = -runSize.height();
-    auto horizontalMargin = displayBox.horizontalMargin();
-    auto logicalRect = Display::Rect { logicalTop, contentLogicalRight() + horizontalMargin.start, runSize.width(), runSize.height() };
-
-    m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
-    m_contentLogicalWidth += (runSize.width() + horizontalMargin.start + horizontalMargin.end);
-    m_trimmableContent.clear();
-}
-
-void Line::appendReplacedInlineBox(const InlineItem& inlineItem, LayoutSize runSize)
-{
-    // FIXME Surely replaced boxes behave differently.
-    appendNonReplacedInlineBox(inlineItem, runSize);
-}
-
-void Line::appendHardLineBreak(const InlineItem& inlineItem)
-{
-    auto ascent = inlineItem.layoutBox().style().fontMetrics().ascent(); 
-    auto logicalRect = Display::Rect { -ascent, contentLogicalRight(), { }, logicalHeight() };
-    m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
-}
-
 struct UncommittedContent {
     void add(InlineItem&);
     void reset();
@@ -395,7 +106,7 @@
 
     auto& formattingRootStyle = m_formattingRoot.style();
     auto mimimumLineHeight = formattingRootStyle.computedLineHeight();
-    auto baselineOffset = halfLeadingMetrics(formattingRootStyle.fontMetrics(), mimimumLineHeight).height;
+    auto baselineOffset = Line::halfLeadingMetrics(formattingRootStyle.fontMetrics(), mimimumLineHeight).height;
     line.reset({ lineLogicalLeft, lineLogicalTop }, availableWidth, mimimumLineHeight, baselineOffset);
 }
 
@@ -491,7 +202,7 @@
             trimmableTrailingWidth = { };
             lineLogicalRight = { };
         }
-        if (isTrimmableContent(*inlineItem)) {
+        if (TextUtil::isTrimmableContent(*inlineItem)) {
             // Skip leading whitespace.
             if (!lineLogicalRight)
                 continue;

Added: trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp (0 => 245850)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp	2019-05-29 16:07:19 UTC (rev 245850)
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InlineLine.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+Line::LineItem::LineItem(Display::Run inlineRun, const InlineItem& inlineItem, bool isCollapsed, bool canBeExtended)
+    : inlineRun(inlineRun)
+    , inlineItem(inlineItem)
+    , isCollapsed(isCollapsed)
+    , canBeExtended(canBeExtended)
+{
+}
+
+Line::Line(const LayoutState& layoutState)
+    : m_layoutState(layoutState)
+{
+}
+
+void Line::reset(const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimumHeight, LayoutUnit baselineOffset)
+{
+    m_logicalTopLeft = topLeft;
+    m_lineLogicalWidth = availableWidth;
+    m_logicalHeight = { baselineOffset, minimumHeight - baselineOffset };
+
+    m_contentLogicalWidth = { };
+
+    m_lineItems.clear();
+    m_trimmableContent.clear();
+}
+
+const Line::LineItems& Line::close()
+{
+    removeTrailingTrimmableContent();
+    // Convert inline run geometry from relative to the baseline to relative to logical top.
+    for (auto& lineItem : m_lineItems) {
+        auto adjustedLogicalTop = lineItem->inlineRun.logicalTop() + m_logicalHeight.height + m_logicalTopLeft.y();
+        lineItem->inlineRun.setLogicalTop(adjustedLogicalTop);
+    }
+    return m_lineItems;
+}
+
+void Line::removeTrailingTrimmableContent()
+{
+    // Collapse trimmable trailing content
+    LayoutUnit trimmableWidth;
+    for (auto* trimmableRun : m_trimmableContent) {
+        trimmableRun->isCollapsed = true;
+        trimmableWidth += trimmableRun->inlineRun.logicalWidth();
+    }
+    m_contentLogicalWidth -= trimmableWidth;
+}
+
+void Line::moveLogicalLeft(LayoutUnit delta)
+{
+    if (!delta)
+        return;
+    ASSERT(delta > 0);
+    // Shrink the line and move the items.
+    m_logicalTopLeft.move(delta, 0);
+    m_lineLogicalWidth -= delta;
+    for (auto& lineItem : m_lineItems)
+        lineItem->inlineRun.moveHorizontally(delta);
+}
+
+void Line::moveLogicalRight(LayoutUnit delta)
+{
+    ASSERT(delta > 0);
+    m_lineLogicalWidth -= delta;
+}
+
+LayoutUnit Line::trailingTrimmableWidth() const
+{
+    LayoutUnit trimmableWidth;
+    for (auto* trimmableRun : m_trimmableContent)
+        trimmableWidth += trimmableRun->inlineRun.logicalWidth();
+    return trimmableWidth;
+}
+
+bool Line::hasContent() const
+{
+    // Return false for empty containers like <span></span>.
+    if (m_lineItems.isEmpty())
+        return false;
+    for (auto& lineItem : m_lineItems) {
+        if (lineItem->inlineItem.isContainerStart() || lineItem->inlineItem.isContainerEnd())
+            continue;
+        if (!lineItem->isCollapsed)
+            return true;
+    }
+    return false;
+}
+
+void Line::appendNonBreakableSpace(const InlineItem& inlineItem, const Display::Rect& logicalRect)
+{
+    m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
+    m_contentLogicalWidth += inlineItem.width();
+}
+
+void Line::appendInlineContainerStart(const InlineItem& inlineItem)
+{
+    auto& layoutBox = inlineItem.layoutBox();
+    auto& style = layoutBox.style();
+    auto& fontMetrics = style.fontMetrics();
+
+    auto alignAndAdjustLineHeight = [&] {
+        LayoutUnit inlineBoxHeight = style.computedLineHeight();
+
+        auto halfLeading = halfLeadingMetrics(fontMetrics, inlineBoxHeight);
+        if (halfLeading.depth > 0)
+            m_logicalHeight.depth = std::max(m_logicalHeight.depth, halfLeading.depth);
+        if (halfLeading.height > 0)
+            m_logicalHeight.height = std::max(m_logicalHeight.height, halfLeading.height);
+    };
+
+    alignAndAdjustLineHeight();
+    auto& displayBox = m_layoutState.displayBoxForLayoutBox(layoutBox);
+    auto containerHeight = fontMetrics.height() + displayBox.verticalBorder() + displayBox.verticalPadding().valueOr(0);
+    auto logicalTop = -fontMetrics.ascent() - displayBox.borderTop() - displayBox.paddingTop().valueOr(0);
+    auto logicalRect = Display::Rect { logicalTop, contentLogicalRight(), inlineItem.width(), containerHeight };
+    appendNonBreakableSpace(inlineItem, logicalRect);
+}
+
+void Line::appendInlineContainerEnd(const InlineItem& inlineItem)
+{
+    // This is really just a placeholder to mark the end of the inline level container.
+    auto logicalRect = Display::Rect { 0, contentLogicalRight(), inlineItem.width(), 0 };
+    appendNonBreakableSpace(inlineItem, logicalRect);
+}
+
+void Line::appendTextContent(const InlineTextItem& inlineItem, LayoutSize runSize)
+{
+    auto isTrimmable = TextUtil::isTrimmableContent(inlineItem);
+    if (!isTrimmable)
+        m_trimmableContent.clear();
+
+    auto shouldCollapseCompletely = [&] {
+        if (!isTrimmable)
+            return false;
+        // Leading whitespace.
+        if (m_lineItems.isEmpty())
+            return true;
+        // Check if the last item is trimmable as well.
+        for (int index = m_lineItems.size() - 1; index >= 0; --index) {
+            auto& inlineItem = m_lineItems[index]->inlineItem;
+            if (inlineItem.isBox())
+                return false;
+            if (inlineItem.isText())
+                return TextUtil::isTrimmableContent(inlineItem);
+            ASSERT(inlineItem.isContainerStart() || inlineItem.isContainerEnd());
+        }
+        return true;
+    };
+
+    // Collapsed line items don't contribute to the line width.
+    auto isCompletelyCollapsed = shouldCollapseCompletely();
+    auto canBeExtended = !isCompletelyCollapsed && !inlineItem.isCollapsed();
+    auto logicalRect = Display::Rect { -inlineItem.style().fontMetrics().ascent(), contentLogicalRight(), runSize.width(), runSize.height() };
+    auto textContext = Display::Run::TextContext { inlineItem.start(), inlineItem.isCollapsed() ? 1 : inlineItem.length() };
+    auto displayRun = Display::Run(logicalRect, textContext);
+
+    auto lineItem = std::make_unique<LineItem>(displayRun, inlineItem, isCompletelyCollapsed, canBeExtended);
+    if (isTrimmable)
+        m_trimmableContent.add(lineItem.get());
+
+    m_lineItems.append(WTFMove(lineItem));
+    m_contentLogicalWidth += isCompletelyCollapsed ? LayoutUnit() : runSize.width();
+}
+
+void Line::appendNonReplacedInlineBox(const InlineItem& inlineItem, LayoutSize runSize)
+{
+    auto alignAndAdjustLineHeight = [&] {
+        auto inlineBoxHeight = runSize.height();
+        // FIXME: We need to look inside the inline-block's formatting context and check the lineboxes (if any) to be able to baseline align.
+        if (inlineItem.layoutBox().establishesInlineFormattingContext()) {
+            if (inlineBoxHeight == logicalHeight())
+                return;
+            // FIXME: This fails when the line height difference comes from font-size diff.
+            m_logicalHeight.depth = std::max<LayoutUnit>(0, m_logicalHeight.depth);
+            m_logicalHeight.height = std::max(inlineBoxHeight, m_logicalHeight.height);
+            return;
+        }
+        // 0 descent -> baseline aligment for now.
+        m_logicalHeight.depth = std::max<LayoutUnit>(0, m_logicalHeight.depth);
+        m_logicalHeight.height = std::max(inlineBoxHeight, m_logicalHeight.height);
+    };
+
+    alignAndAdjustLineHeight();
+    auto& displayBox = m_layoutState.displayBoxForLayoutBox(inlineItem.layoutBox());
+    auto logicalTop = -runSize.height();
+    auto horizontalMargin = displayBox.horizontalMargin();
+    auto logicalRect = Display::Rect { logicalTop, contentLogicalRight() + horizontalMargin.start, runSize.width(), runSize.height() };
+
+    m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
+    m_contentLogicalWidth += (runSize.width() + horizontalMargin.start + horizontalMargin.end);
+    m_trimmableContent.clear();
+}
+
+void Line::appendReplacedInlineBox(const InlineItem& inlineItem, LayoutSize runSize)
+{
+    // FIXME Surely replaced boxes behave differently.
+    appendNonReplacedInlineBox(inlineItem, runSize);
+}
+
+void Line::appendHardLineBreak(const InlineItem& inlineItem)
+{
+    auto ascent = inlineItem.layoutBox().style().fontMetrics().ascent();
+    auto logicalRect = Display::Rect { -ascent, contentLogicalRight(), { }, logicalHeight() };
+    m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
+}
+
+Line::UsedHeightAndDepth Line::halfLeadingMetrics(const FontMetrics& fontMetrics, LayoutUnit lineLogicalHeight)
+{
+    auto ascent = fontMetrics.ascent();
+    auto descent = fontMetrics.descent();
+    // 10.8.1 Leading and half-leading
+    auto leading = lineLogicalHeight - (ascent + descent);
+    // Inline tree is all integer based.
+    auto adjustedAscent = std::max((ascent + leading / 2).floor(), 0);
+    auto adjustedDescent = std::max((descent + leading / 2).ceil(), 0);
+    return { adjustedAscent, adjustedDescent };
+}
+
+}
+}
+
+#endif

Added: trunk/Source/WebCore/layout/inlineformatting/InlineLine.h (0 => 245850)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.h	2019-05-29 16:07:19 UTC (rev 245850)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "DisplayRun.h"
+#include "InlineItem.h"
+
+namespace WebCore {
+namespace Layout {
+
+class Line {
+public:
+    Line(const LayoutState&);
+
+    void reset(const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimumLineHeight, LayoutUnit baselineOffset);
+
+    struct LineItem {
+        LineItem(Display::Run, const InlineItem&, bool isCollapsed, bool canBeExtended);
+
+        // Relative to the baseline.
+        Display::Run inlineRun;
+        const InlineItem& inlineItem;
+        bool isCollapsed { false };
+        bool canBeExtended { false };
+    };
+
+    using LineItems = Vector<std::unique_ptr<LineItem>>;
+    const LineItems& close();
+
+    void appendTextContent(const InlineTextItem&, LayoutSize);
+    void appendNonReplacedInlineBox(const InlineItem&, LayoutSize);
+    void appendReplacedInlineBox(const InlineItem&, LayoutSize);
+    void appendInlineContainerStart(const InlineItem&);
+    void appendInlineContainerEnd(const InlineItem&);
+    void appendHardLineBreak(const InlineItem&);
+
+    bool hasContent() const;
+
+    LayoutUnit trailingTrimmableWidth() const;
+
+    void moveLogicalLeft(LayoutUnit);
+    void moveLogicalRight(LayoutUnit);
+
+    LayoutUnit availableWidth() const { return logicalWidth() - contentLogicalWidth(); }
+    
+    LayoutUnit contentLogicalRight() const { return logicalLeft() + contentLogicalWidth(); }
+    LayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
+
+    LayoutUnit logicalTop() const { return m_logicalTopLeft.y(); }
+    LayoutUnit logicalLeft() const { return m_logicalTopLeft.x(); }
+    LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
+    LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
+    LayoutUnit logicalWidth() const { return m_lineLogicalWidth; }
+    LayoutUnit logicalHeight() const { return m_logicalHeight.height + m_logicalHeight.depth; }
+
+    struct UsedHeightAndDepth {
+        LayoutUnit height;
+        LayoutUnit depth;
+    };
+    static UsedHeightAndDepth halfLeadingMetrics(const FontMetrics&, LayoutUnit lineLogicalHeight);
+
+private:
+    void appendNonBreakableSpace(const InlineItem&, const Display::Rect& logicalRect);
+    void removeTrailingTrimmableContent();
+
+    const LayoutState& m_layoutState;
+    LineItems m_lineItems;
+    ListHashSet<LineItem*> m_trimmableContent;
+
+    LayoutPoint m_logicalTopLeft;
+    LayoutUnit m_contentLogicalWidth;
+
+    UsedHeightAndDepth m_logicalHeight;
+    LayoutUnit m_lineLogicalWidth;
+};
+
+}
+}
+#endif

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.h (245849 => 245850)


--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.h	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.h	2019-05-29 16:07:19 UTC (rev 245850)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "InlineFormattingState.h"
 #include "InlineItem.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp (245849 => 245850)


--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp	2019-05-29 16:07:19 UTC (rev 245850)
@@ -89,6 +89,14 @@
     return width;
 }
 
+bool TextUtil::isTrimmableContent(const InlineItem& inlineItem)
+{
+    if (!is<InlineTextItem>(inlineItem))
+        return false;
+    auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
+    return inlineTextItem.isWhitespace() && inlineTextItem.style().collapseWhiteSpace();
 }
+
 }
+}
 #endif

Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h (245849 => 245850)


--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h	2019-05-29 13:07:02 UTC (rev 245849)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h	2019-05-29 16:07:19 UTC (rev 245850)
@@ -36,6 +36,7 @@
 public:
     static LayoutUnit width(const InlineBox&, unsigned from, unsigned to, LayoutUnit contentLogicalLeft);
     static Optional<unsigned> hyphenPositionBefore(const InlineItem&, unsigned from, unsigned length);
+    static bool isTrimmableContent(const InlineItem&);
 
 private:
     static LayoutUnit fixedPitchWidth(String, const RenderStyle&, unsigned from, unsigned to, LayoutUnit contentLogicalLeft);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to