2018-10-26 Zalan Bujtas <zalan@apple.com>
+ [LFC][IFC] Adjust current line with float constraints.
+ https://bugs.webkit.org/show_bug.cgi?id=190940
+
+ Reviewed by Antti Koivisto.
+
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::initializeNewLine const):
+ (WebCore::Layout::InlineFormattingContext::layoutInlineContent const):
+ * layout/inlineformatting/InlineFormattingContext.h:
+ * layout/inlineformatting/InlineRun.h:
+ (WebCore::Layout::InlineRun::moveHorizontally):
+ * layout/inlineformatting/Line.cpp:
+ (WebCore::Layout::InlineFormattingContext::Line::adjustLogicalLeft):
+ (WebCore::Layout::InlineFormattingContext::Line::adjustLogicalRight):
+
+2018-10-26 Zalan Bujtas <zalan@apple.com>
+
[LFC][IFC] Compute float box size and position
https://bugs.webkit.org/show_bug.cgi?id=190938
return run.content.style().collapseWhiteSpace();
}
-void InlineFormattingContext::initializeNewLine(const LayoutContext& layoutContext, Line& line) const
+void InlineFormattingContext::initializeNewLine(const LayoutContext& layoutContext, InlineFormattingState& inlineFormattingState, Line& line) const
{
auto& formattingRoot = downcast<Container>(root());
auto& formattingRootDisplayBox = layoutContext.displayBoxForLayoutBox(formattingRoot);
auto lineLogicalTop = line.isFirstLine() ? formattingRootDisplayBox.contentBoxTop() : line.logicalBottom();
auto availableWidth = formattingRootDisplayBox.contentBoxWidth();
+ // Check for intruding floats and adjust logical left/available width for this line accordingly.
+ auto& floatingState = inlineFormattingState.floatingState();
+ if (!floatingState.isEmpty()) {
+ auto floatConstraints = floatingState.constraints(lineLogicalTop, formattingRoot);
+ // Check if these constraints actually put limitation on the line.
+ if (floatConstraints.left && *floatConstraints.left <= formattingRootDisplayBox.contentBoxLeft())
+ floatConstraints.left = { };
+
+ if (floatConstraints.right && *floatConstraints.right >= formattingRootDisplayBox.contentBoxRight())
+ floatConstraints.right = { };
+
+ if (floatConstraints.left && floatConstraints.right) {
+ ASSERT(*floatConstraints.left < *floatConstraints.right);
+ availableWidth = *floatConstraints.right - *floatConstraints.left;
+ lineLogicalLeft = *floatConstraints.left;
+ } else if (floatConstraints.left) {
+ ASSERT(*floatConstraints.left > lineLogicalLeft);
+ availableWidth -= (*floatConstraints.left - lineLogicalLeft);
+ lineLogicalLeft = *floatConstraints.left;
+ } else if (floatConstraints.right) {
+ ASSERT(*floatConstraints.right > lineLogicalLeft);
+ availableWidth = *floatConstraints.right - lineLogicalLeft;
+ }
+ }
+
Display::Box::Rect logicalRect;
logicalRect.setTop(lineLogicalTop);
logicalRect.setLeft(lineLogicalLeft);
auto previousRunPositionIsLineEnd = false;
Line line(inlineFormattingState, root());
- initializeNewLine(layoutContext, line);
+ initializeNewLine(layoutContext, inlineFormattingState, line);
InlineLineBreaker lineBreaker(layoutContext, inlineFormattingState.inlineContent(), inlineRunProvider.runs());
while (auto run = lineBreaker.nextRun(line.contentLogicalRight(), line.availableWidth(), !line.hasContent())) {
// Previous run ended up being at the line end. Adjust the line accordingly.
if (!previousRunPositionIsLineEnd) {
line.close();
- initializeNewLine(layoutContext, line);
+ initializeNewLine(layoutContext, inlineFormattingState, line);
}
// Skip leading whitespace.
if (!trimLeadingRun(*run))
line.appendContent(*run);
// Move over to the next line.
line.close();
- initializeNewLine(layoutContext, line);
+ initializeNewLine(layoutContext, inlineFormattingState, line);
continue;
}
void init(const Display::Box::Rect&);
void appendContent(const InlineLineBreaker::Run&);
+
+ void adjustLogicalLeft(LayoutUnit delta);
+ void adjustLogicalRight(LayoutUnit delta);
+
enum class LastLine { No, Yes };
void close(LastLine = LastLine::No);
};
void layoutInlineContent(const LayoutContext&, InlineFormattingState&, const InlineRunProvider&) const;
- void initializeNewLine(const LayoutContext&, Line&) const;
+ void initializeNewLine(const LayoutContext&, InlineFormattingState&, Line&) const;
void computeWidthAndHeight(LayoutContext&, const Box&) const;
void computeFloatPosition(const LayoutContext&, const FloatingContext&, Line&, const Box&) const;
m_trailingTrimmableContent = { };
}
+void InlineFormattingContext::Line::adjustLogicalLeft(LayoutUnit delta)
+{
+ m_availableWidth -= delta;
+ m_logicalRect.shiftLeftTo(m_logicalRect.left() + delta);
+
+ if (!m_firstRunIndex)
+ return;
+
+ auto& inlineRuns = m_formattingState.inlineRuns();
+ for (auto runIndex = *m_firstRunIndex; runIndex < inlineRuns.size(); ++runIndex)
+ inlineRuns[runIndex].moveHorizontally(delta);
+}
+
+void InlineFormattingContext::Line::adjustLogicalRight(LayoutUnit delta)
+{
+ m_availableWidth -= delta;
+ m_logicalRect.shiftRightTo(m_logicalRect.right() - delta);
+}
+
static LayoutUnit adjustedLineLogicalLeft(TextAlignMode align, LayoutUnit lineLogicalLeft, LayoutUnit remainingWidth)
{
switch (align) {