Diff
Modified: trunk/Source/WebCore/ChangeLog (270228 => 270229)
--- trunk/Source/WebCore/ChangeLog 2020-11-29 19:10:00 UTC (rev 270228)
+++ trunk/Source/WebCore/ChangeLog 2020-11-29 19:44:42 UTC (rev 270229)
@@ -1,5 +1,25 @@
2020-11-29 Zalan Bujtas <[email protected]>
+ [LFC][IFC] Create runs for inline boxes
+ https://bugs.webkit.org/show_bug.cgi?id=219329
+
+ Reviewed by Antti Koivisto.
+
+ With this patch we start constructing runs for inline boxes (these are spec "inline boxes" and not legacy line layout "inline boxes").
+
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+ * layout/inlineformatting/InlineLineBox.cpp:
+ (WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const):
+ * layout/inlineformatting/InlineLineBox.h:
+ * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLines const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayInlineBoxes const):
+ * layout/layouttree/LayoutTreeBuilder.cpp:
+ (WebCore::Layout::showInlineTreeAndRuns):
+
+2020-11-29 Zalan Bujtas <[email protected]>
+
[LFC][IFC] Remove LineBuilder::availableWidth
https://bugs.webkit.org/show_bug.cgi?id=219330
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (270228 => 270229)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2020-11-29 19:10:00 UTC (rev 270228)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2020-11-29 19:44:42 UTC (rev 270229)
@@ -436,8 +436,11 @@
// FIXME: We should not need to construct a line run for <br>.
if (lineRun.isText() || lineRun.isLineBreak())
formattingState.addLineRun({ lineIndex, lineRun.layoutBox(), lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
- else if (lineRun.isBox())
- formattingState.addLineRun({ lineIndex, lineRun.layoutBox(), lineBox.logicalMarginRectForInlineLevelBox(lineRun.layoutBox()), lineRun.expansion(), { } });
+ else if (lineRun.isBox() || lineRun.isInlineBoxStart()) {
+ auto& layoutBox = lineRun.layoutBox();
+ auto& boxGeometry = formattingState.boxGeometry(layoutBox);
+ formattingState.addLineRun({ lineIndex, lineRun.layoutBox(), lineBox.logicalMarginRectForInlineLevelBox(lineRun.layoutBox(), boxGeometry), lineRun.expansion(), { } });
+ }
}
};
constructLineRuns();
@@ -454,10 +457,10 @@
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
// Inline box coordinates are relative to the line box.
// Let's convert top/left relative to the formatting context root.
- auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox);
- // Inline box height includes the margin box. Let's account for that.
+ auto logicalMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+ // Inline level box height includes the margin box. Let's account for that.
auto borderBoxLogicalTopLeft = lineBoxLogicalRect.topLeft();
- borderBoxLogicalTopLeft.move(logicalRect.left(), logicalRect.top() + boxGeometry.marginBefore());
+ borderBoxLogicalTopLeft.move(logicalMarginRect.left() + boxGeometry.marginStart(), logicalMarginRect.top() + boxGeometry.marginBefore());
if (layoutBox.isInFlowPositioned())
borderBoxLogicalTopLeft += geometry.inFlowPositionedPositionOffset(layoutBox, horizontalConstraints);
@@ -467,12 +470,14 @@
boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
continue;
}
+ // FIXME: Check if this is a multi line inline box and whether horizontal margin/padding/border should be included.
+ auto contentBoxHeight = toLayoutUnit(logicalMarginRect.height() - boxGeometry.verticalMarginBorderAndPadding());
if (layoutBox.isLineBreakBox()) {
boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
- boxGeometry.setContentBoxHeight(toLayoutUnit(logicalRect.height()));
+ boxGeometry.setContentBoxHeight(contentBoxHeight);
}
- auto marginBoxWidth = logicalRect.width();
- auto contentBoxWidth = marginBoxWidth - (boxGeometry.marginStart() + boxGeometry.borderLeft() + boxGeometry.paddingLeft().valueOr(0));
+ auto marginBoxWidth = logicalMarginRect.width();
+ auto contentBoxWidth = toLayoutUnit(marginBoxWidth - boxGeometry.horizontalMarginBorderAndPadding());
// Non-atomic inline level boxes may or may not be wrapped and have geometries on multiple lines.
int previousLineIndex = formattingState.lineBoxes().size() - 2;
auto isSpanningInlineBox = previousLineIndex > 0 && formattingState.lineBoxes()[previousLineIndex].containsInlineLevelBox(layoutBox);
@@ -479,14 +484,14 @@
if (!isSpanningInlineBox) {
// This box showed up on this line the first time.
boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
- boxGeometry.setContentBoxWidth(toLayoutUnit(contentBoxWidth));
- boxGeometry.setContentBoxHeight(toLayoutUnit(logicalRect.height()));
+ boxGeometry.setContentBoxWidth(contentBoxWidth);
+ boxGeometry.setContentBoxHeight(contentBoxHeight);
continue;
}
// This is a just a simple box geometry for the line spanning inline box. getBoundingClientRect looks into each line boxes (will turn into fragmented boxes).
boxGeometry.setLogicalLeft(std::min(BoxGeometry::borderBoxLeft(boxGeometry), toLayoutUnit(borderBoxLogicalTopLeft.x())));
- boxGeometry.setContentBoxWidth(std::max(toLayoutUnit(contentBoxWidth), boxGeometry.contentBoxWidth()));
- boxGeometry.setContentBoxHeight(boxGeometry.contentBoxHeight() + toLayoutUnit(logicalRect.height()));
+ boxGeometry.setContentBoxWidth(std::max(contentBoxWidth, boxGeometry.contentBoxWidth()));
+ boxGeometry.setContentBoxHeight(boxGeometry.contentBoxHeight() + contentBoxHeight);
}
};
updateBoxGeometry();
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (270228 => 270229)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp 2020-11-29 19:10:00 UTC (rev 270228)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp 2020-11-29 19:44:42 UTC (rev 270229)
@@ -110,20 +110,30 @@
return { runlogicalTop, m_horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }) + run.logicalLeft(), run.logicalWidth(), logicalHeight };
}
-InlineRect LineBox::logicalMarginRectForInlineLevelBox(const Box& layoutBox) const
+InlineRect LineBox::logicalMarginRectForInlineLevelBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
{
- auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
- if (inlineBox->hasLineBoxRelativeAlignment())
- return inlineBox->logicalRect();
+ auto logicalRect = [&] {
+ auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
+ if (inlineBox->hasLineBoxRelativeAlignment())
+ return inlineBox->logicalRect();
- auto inlineBoxLogicalRect = inlineBox->logicalRect();
- auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
- while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
- inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
- ASSERT(inlineBox->isInlineBox());
- inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
- }
- return { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
+ auto inlineBoxLogicalRect = inlineBox->logicalRect();
+ auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
+ while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
+ inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
+ ASSERT(inlineBox->isInlineBox());
+ inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
+ }
+ return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
+ }();
+ if (!layoutBox.isInlineBox())
+ return logicalRect;
+
+ // This logical rect is as tall as the "text" content is. Let's adjust with vertical border and padding -vertical margin is ignored.
+ auto verticalBorderAndPadding = boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu);
+ logicalRect.expandVertically(verticalBorderAndPadding);
+ logicalRect.moveVertically(-(boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0_lu)));
+ return logicalRect;
}
}
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h (270228 => 270229)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h 2020-11-29 19:10:00 UTC (rev 270228)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h 2020-11-29 19:44:42 UTC (rev 270229)
@@ -29,7 +29,6 @@
#include "InlineLine.h"
#include "InlineRect.h"
-#include "LayoutBoxGeometry.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/WeakPtr.h>
@@ -36,6 +35,7 @@
namespace WebCore {
namespace Layout {
+class BoxGeometry;
class InlineFormattingContext;
class LineBoxBuilder;
@@ -143,7 +143,7 @@
const InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) const { return *m_inlineLevelBoxRectMap.get(&layoutBox); }
InlineRect logicalRectForTextRun(const Line::Run&) const;
- InlineRect logicalMarginRectForInlineLevelBox(const Box&) const;
+ InlineRect logicalMarginRectForInlineLevelBox(const Box&, const BoxGeometry&) const;
auto inlineLevelBoxList() const { return m_inlineLevelBoxRectMap.values(); }
bool containsInlineLevelBox(const Box& layoutBox) const { return m_inlineLevelBoxRectMap.contains(&layoutBox); }
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (270228 => 270229)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2020-11-29 19:10:00 UTC (rev 270228)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2020-11-29 19:44:42 UTC (rev 270229)
@@ -325,9 +325,9 @@
auto& lineBox = lineBoxes[lineIndex];
for (auto& inlineLevelBox : lineBox.inlineLevelBoxList()) {
auto& layoutBox = inlineLevelBox->layoutBox();
- auto inlineLevelBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox);
+ auto& geometry = m_layoutState.geometryForBox(layoutBox);
+ auto inlineLevelBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, geometry);
// inlineLevelBoxLogicalRect encloses the margin box, but we need border box for the display line.
- auto& geometry = m_layoutState.geometryForBox(layoutBox);
inlineLevelBoxLogicalRect.expandVertically(-std::max(0_lu, geometry.marginBefore() + geometry.marginAfter()));
inlineLevelBoxLogicalRect.moveVertically(std::max(0_lu, geometry.marginBefore()));
@@ -363,9 +363,9 @@
if (!inlineLevelBox->isInlineBox() || inlineLevelBox->isRootInlineBox())
continue;
auto& layoutBox = inlineLevelBox->layoutBox();
- auto inlineLevelBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox);
+ auto& geometry = m_layoutState.geometryForBox(layoutBox);
+ auto inlineLevelBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, geometry);
// inlineLevelBoxLogicalRect encloses the margin box, but we need border box for the display line.
- auto& geometry = m_layoutState.geometryForBox(layoutBox);
inlineLevelBoxLogicalRect.expandVertically(-std::max(0_lu, geometry.marginBefore() + geometry.marginAfter()));
inlineLevelBoxLogicalRect.moveVertically(std::max(0_lu, geometry.marginBefore()));
inlineLevelBoxLogicalRect.moveBy(lineBoxLogicalRect.topLeft());
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (270228 => 270229)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2020-11-29 19:10:00 UTC (rev 270228)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2020-11-29 19:44:42 UTC (rev 270229)
@@ -416,7 +416,8 @@
stream << "Generic inline box";
else
stream << "Generic inline level box";
- auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(inlineLevelBox.layoutBox());
+ auto& layoutBox = inlineLevelBox.layoutBox();
+ auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, layoutState.geometryForBox(layoutBox));
stream
<< " at (" << logicalRect.left() << "," << logicalRect.top() << ")"
<< " size (" << logicalRect.width() << "x" << logicalRect.height() << ")"