Modified: trunk/Source/WebCore/ChangeLog (240974 => 240975)
--- trunk/Source/WebCore/ChangeLog 2019-02-05 15:38:20 UTC (rev 240974)
+++ trunk/Source/WebCore/ChangeLog 2019-02-05 16:01:30 UTC (rev 240975)
@@ -1,3 +1,21 @@
+2019-02-05 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] collectInlineContent should use pre-computed margins, paddings and borders
+ https://bugs.webkit.org/show_bug.cgi?id=194269
+
+ Reviewed by Antti Koivisto.
+
+ In this patch we pre-compute the margins padding and borders for formatting context roots, replaced boxes and non-replaced containers.
+ These property values are input to collectInlineContent's inline item detaching logic.
+
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::nextInPreOrder):
+ (WebCore::Layout::InlineFormattingContext::layout const):
+ (WebCore::Layout::InlineFormattingContext::computeMarginBorderAndPadding const):
+ (WebCore::Layout::InlineFormattingContext::collectInlineContent const):
+ * layout/inlineformatting/InlineFormattingContext.h:
+ * layout/layouttree/LayoutBox.h: ran out bits.
+
2019-02-05 Antoine Quint <[email protected]>
REGRESSION (r240579): com.apple.WebKit.WebContent at WebCore: WebCore::Document::absoluteEventRegionForNode
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (240974 => 240975)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2019-02-05 15:38:20 UTC (rev 240974)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2019-02-05 16:01:30 UTC (rev 240975)
@@ -53,6 +53,19 @@
{
}
+static inline const Box* nextInPreOrder(const Box& layoutBox, const Container& root)
+{
+ const Box* nextInPreOrder = nullptr;
+ if (!layoutBox.establishesFormattingContext() && is<Container>(layoutBox) && downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
+ return downcast<Container>(layoutBox).firstInFlowOrFloatingChild();
+
+ for (nextInPreOrder = &layoutBox; nextInPreOrder && nextInPreOrder != &root; nextInPreOrder = nextInPreOrder->parent()) {
+ if (auto* nextSibling = nextInPreOrder->nextInFlowOrFloatingSibling())
+ return nextSibling;
+ }
+ return nullptr;
+}
+
void InlineFormattingContext::layout() const
{
if (!is<Container>(root()))
@@ -59,24 +72,23 @@
return;
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Start] -> inline formatting context -> formatting root(" << &root() << ")");
+ auto& root = downcast<Container>(this->root());
+ auto* layoutBox = root.firstInFlowOrFloatingChild();
+ // Compute width/height for non-text content and margin/border/padding for inline containers.
+ while (layoutBox) {
+ if (layoutBox->establishesFormattingContext())
+ layoutFormattingContextRoot(*layoutBox);
+ else if (is<Container>(*layoutBox))
+ computeMarginBorderAndPadding(downcast<InlineContainer>(*layoutBox));
+ else if (layoutBox->isReplaced())
+ computeWidthAndHeightForReplacedInlineBox(*layoutBox);
+ layoutBox = nextInPreOrder(*layoutBox, root);
+ }
InlineRunProvider inlineRunProvider;
collectInlineContent(inlineRunProvider);
- // Compute width/height for non-text content.
- for (auto& inlineRun : inlineRunProvider.runs()) {
- if (inlineRun.isText())
- continue;
-
- auto& layoutBox = inlineRun.inlineItem().layoutBox();
- if (layoutBox.establishesFormattingContext()) {
- layoutFormattingContextRoot(layoutBox);
- continue;
- }
- computeWidthAndHeightForReplacedInlineBox(layoutBox);
- }
-
layoutInlineContent(inlineRunProvider);
- LOG_WITH_STREAM(FormattingContextLayout, stream << "[End] -> inline formatting context -> formatting root(" << &root() << ")");
+ LOG_WITH_STREAM(FormattingContextLayout, stream << "[End] -> inline formatting context -> formatting root(" << &root << ")");
}
static bool isTrimmableContent(const InlineLineBreaker::Run& run)
@@ -329,6 +341,19 @@
closeLine(line, IsLastLine::Yes);
}
+void InlineFormattingContext::computeMarginBorderAndPadding(const InlineContainer& inlineContainer) const
+{
+ // Non-replaced, non-formatting root containers (<span></span>) don't have width property -> non width computation.
+ ASSERT(!inlineContainer.replaced());
+ ASSERT(!inlineContainer.establishesFormattingContext());
+
+ computeBorderAndPadding(inlineContainer);
+ auto& displayBox = layoutState().displayBoxForLayoutBox(inlineContainer);
+ auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState(), inlineContainer);
+ displayBox.setHorizontalComputedMargin(computedHorizontalMargin);
+ displayBox.setHorizontalMargin({ computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) });
+}
+
void InlineFormattingContext::computeWidthAndMargin(const Box& layoutBox) const
{
auto& layoutState = this->layoutState();
@@ -470,14 +495,10 @@
enum class NonBreakableWidthType { Start, End };
auto nonBreakableWidth = [&](auto& container, auto type) {
- auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState, container);
- auto horizontalMargin = UsedHorizontalMargin { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
- auto border = Geometry::computedBorder(layoutState, container);
- auto padding = Geometry::computedPadding(layoutState, container);
-
+ auto& displayBox = layoutState.displayBoxForLayoutBox(container);
if (type == NonBreakableWidthType::Start)
- return border.horizontal.left + horizontalMargin.start + (padding ? padding->horizontal.left : LayoutUnit());
- return border.horizontal.right + horizontalMargin.end + (padding ? padding->horizontal.right : LayoutUnit());
+ return displayBox.marginStart() + displayBox.borderLeft() + displayBox.paddingLeft().valueOr(0);
+ return displayBox.marginEnd() + displayBox.borderRight() + displayBox.paddingRight().valueOr(0);
};
LayoutQueue layoutQueue;
@@ -496,9 +517,9 @@
if (container.establishesFormattingContext()) {
// Formatting contexts are treated as leaf nodes.
auto& inlineItem = createAndAppendInlineItem(inlineRunProvider, inlineContent, container);
- auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState, container);
- auto currentNonBreakableStartWidth = nonBreakableStartWidth.valueOr(0) + computedHorizontalMargin.start.valueOr(0) + nonBreakableEndWidth.valueOr(0);
- addDetachingRules(inlineItem, currentNonBreakableStartWidth, computedHorizontalMargin.end);
+ auto& displayBox = layoutState.displayBoxForLayoutBox(container);
+ auto currentNonBreakableStartWidth = nonBreakableStartWidth.valueOr(0) + displayBox.marginStart() + nonBreakableEndWidth.valueOr(0);
+ addDetachingRules(inlineItem, currentNonBreakableStartWidth, displayBox.marginEnd());
nonBreakableStartWidth = { };
nonBreakableEndWidth = { };
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (240974 => 240975)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-02-05 15:38:20 UTC (rev 240974)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-02-05 16:01:30 UTC (rev 240975)
@@ -35,6 +35,7 @@
namespace WebCore {
namespace Layout {
+class InlineContainer;
class InlineFormattingState;
class InlineRunProvider;
@@ -112,6 +113,7 @@
void layoutFormattingContextRoot(const Box&) const;
void computeWidthAndHeightForReplacedInlineBox(const Box&) const;
+ void computeMarginBorderAndPadding(const InlineContainer&) const;
void computeHeightAndMargin(const Box&) const;
void computeWidthAndMargin(const Box&) const;
void computeFloatPosition(const FloatingContext&, Line&, const Box&) const;
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (240974 => 240975)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2019-02-05 15:38:20 UTC (rev 240974)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2019-02-05 16:01:30 UTC (rev 240975)
@@ -155,7 +155,7 @@
std::unique_ptr<Replaced> m_replaced;
- unsigned m_baseTypeFlags : 4;
+ unsigned m_baseTypeFlags : 5;
};
}