|
Lines 213-220
void LineBoxBuilder::constructInlineLevelBoxes(LineBox& lineBox, const Line::Run
a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp_sec1
|
| 213 |
auto isInitiallyConsideredNonEmpty = !lineBox.isLineVisuallyEmpty() && lineHasImaginaryStrut; |
213 |
auto isInitiallyConsideredNonEmpty = !lineBox.isLineVisuallyEmpty() && lineHasImaginaryStrut; |
| 214 |
if (isInitiallyConsideredNonEmpty) |
214 |
if (isInitiallyConsideredNonEmpty) |
| 215 |
rootInlineBox->setIsNonEmpty(); |
215 |
rootInlineBox->setIsNonEmpty(); |
| 216 |
if (lineHasImaginaryStrut) |
216 |
setVerticalGeometryForInlineBox(*rootInlineBox); |
| 217 |
setVerticalGeometryForInlineBox(*rootInlineBox); |
|
|
| 218 |
lineBox.addRootInlineBox(WTFMove(rootInlineBox)); |
217 |
lineBox.addRootInlineBox(WTFMove(rootInlineBox)); |
| 219 |
}; |
218 |
}; |
| 220 |
createRootInlineBox(); |
219 |
createRootInlineBox(); |
|
Lines 252-265
void LineBoxBuilder::constructInlineLevelBoxes(LineBox& lineBox, const Line::Run
a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp_sec2
|
| 252 |
}; |
251 |
}; |
| 253 |
createWrappedInlineBoxes(); |
252 |
createWrappedInlineBoxes(); |
| 254 |
|
253 |
|
| 255 |
auto stretchRootInlineBoxIfNeededQuirk = [&] (const auto& layoutBox) { |
|
|
| 256 |
auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent()); |
| 257 |
if (!isRootInlineBox(parentInlineBox) || !parentInlineBox.isEmpty()) |
| 258 |
return; |
| 259 |
setVerticalGeometryForInlineBox(parentInlineBox); |
| 260 |
parentInlineBox.setIsNonEmpty(); |
| 261 |
}; |
| 262 |
|
| 263 |
for (auto& run : runs) { |
254 |
for (auto& run : runs) { |
| 264 |
auto& layoutBox = run.layoutBox(); |
255 |
auto& layoutBox = run.layoutBox(); |
| 265 |
auto logicalLeft = horizontalAligmentOffset + run.logicalLeft(); |
256 |
auto logicalLeft = horizontalAligmentOffset + run.logicalLeft(); |
|
Lines 292-303
void LineBoxBuilder::constructInlineLevelBoxes(LineBox& lineBox, const Line::Run
a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp_sec3
|
| 292 |
inlineBox.setLogicalWidth(run.logicalRight() - inlineBox.logicalLeft()); |
283 |
inlineBox.setLogicalWidth(run.logicalRight() - inlineBox.logicalLeft()); |
| 293 |
} else if (run.isText() || run.isSoftLineBreak()) { |
284 |
} else if (run.isText() || run.isSoftLineBreak()) { |
| 294 |
// FIXME: Adjust non-empty inline box height when glyphs from the non-primary font stretch the box. |
285 |
// FIXME: Adjust non-empty inline box height when glyphs from the non-primary font stretch the box. |
| 295 |
stretchRootInlineBoxIfNeededQuirk(layoutBox); |
286 |
lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent()).setIsNonEmpty(); |
| 296 |
} else if (run.isHardLineBreak()) { |
287 |
} else if (run.isHardLineBreak()) { |
| 297 |
auto lineBreakBox = LineBox::InlineLevelBox::createLineBreakBox(layoutBox, logicalLeft); |
288 |
auto lineBreakBox = LineBox::InlineLevelBox::createLineBreakBox(layoutBox, logicalLeft); |
| 298 |
setVerticalGeometryForInlineBox(*lineBreakBox); |
289 |
setVerticalGeometryForInlineBox(*lineBreakBox); |
|
|
290 |
lineBreakBox->setIsNonEmpty(); |
| 299 |
lineBox.addInlineLevelBox(WTFMove(lineBreakBox)); |
291 |
lineBox.addInlineLevelBox(WTFMove(lineBreakBox)); |
| 300 |
stretchRootInlineBoxIfNeededQuirk(layoutBox); |
|
|
| 301 |
} else if (run.isWordBreakOpportunity()) |
292 |
} else if (run.isWordBreakOpportunity()) |
| 302 |
lineBox.addInlineLevelBox(LineBox::InlineLevelBox::createGenericInlineLevelBox(layoutBox, logicalLeft)); |
293 |
lineBox.addInlineLevelBox(LineBox::InlineLevelBox::createGenericInlineLevelBox(layoutBox, logicalLeft)); |
| 303 |
else |
294 |
else |
|
Lines 314-319
void LineBoxBuilder::alignInlineLevelBoxesVerticallyAndComputeLineBoxHeight(Line
a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp_sec4
|
| 314 |
struct AbsoluteTopAndBottom { |
305 |
struct AbsoluteTopAndBottom { |
| 315 |
InlineLayoutUnit top { 0 }; |
306 |
InlineLayoutUnit top { 0 }; |
| 316 |
InlineLayoutUnit bottom { 0 }; |
307 |
InlineLayoutUnit bottom { 0 }; |
|
|
308 |
const LineBox::InlineLevelBox* inlineLevelBox { nullptr }; |
| 317 |
}; |
309 |
}; |
| 318 |
HashMap<LineBox::InlineLevelBox*, AbsoluteTopAndBottom> absoluteLogicalTopAndBottomMap; |
310 |
HashMap<LineBox::InlineLevelBox*, AbsoluteTopAndBottom> absoluteLogicalTopAndBottomMap; |
| 319 |
auto& rootInlineBox = lineBox.rootInlineBox(); |
311 |
auto& rootInlineBox = lineBox.rootInlineBox(); |
|
Lines 351-385
void LineBoxBuilder::alignInlineLevelBoxesVerticallyAndComputeLineBoxHeight(Line
a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp_sec5
|
| 351 |
inlineLevelBox->setLogicalTop(logicalTop); |
343 |
inlineLevelBox->setLogicalTop(logicalTop); |
| 352 |
auto parentAbsoluteLogicalTop = absoluteLogicalTopAndBottomMap.get(&parentInlineBox).top; |
344 |
auto parentAbsoluteLogicalTop = absoluteLogicalTopAndBottomMap.get(&parentInlineBox).top; |
| 353 |
auto absoluteLogicalTop = parentAbsoluteLogicalTop + logicalTop; |
345 |
auto absoluteLogicalTop = parentAbsoluteLogicalTop + logicalTop; |
| 354 |
absoluteLogicalTopAndBottomMap.add(inlineLevelBox.get(), AbsoluteTopAndBottom { absoluteLogicalTop, absoluteLogicalTop + inlineLevelBox->layoutBounds().height() }); |
346 |
absoluteLogicalTopAndBottomMap.add(inlineLevelBox.get(), AbsoluteTopAndBottom { absoluteLogicalTop, absoluteLogicalTop + inlineLevelBox->layoutBounds().height(), inlineLevelBox.get() }); |
| 355 |
} |
347 |
} |
| 356 |
}; |
348 |
}; |
| 357 |
alignInlineBoxRelativeInlineLevelBoxes(); |
349 |
alignInlineBoxRelativeInlineLevelBoxes(); |
| 358 |
|
350 |
|
| 359 |
auto lineBoxLogicalHeight = InlineLayoutUnit { }; |
351 |
auto lineBoxLogicalHeight = InlineLayoutUnit { }; |
| 360 |
auto minimumInlineBoxRelativeLogicalTop = InlineLayoutUnit { }; |
|
|
| 361 |
auto inlineBoxRelativeLogicalHeight = InlineLayoutUnit { }; |
352 |
auto inlineBoxRelativeLogicalHeight = InlineLayoutUnit { }; |
|
|
353 |
auto quirks = formattingContext().quirks(); |
| 354 |
auto maximumBaselineAlignedAscent = rootInlineBox.isEmpty() ? InlineLayoutUnit() : rootInlineBox.layoutBounds().ascent; |
| 362 |
auto computeLineBoxLogicalHeight = [&] { |
355 |
auto computeLineBoxLogicalHeight = [&] { |
|
|
356 |
auto shouldStretchLineBox = [&](const auto& inlineLevelBox) { |
| 357 |
if (inlineLevelBox.isEmpty()) |
| 358 |
return false; |
| 359 |
return quirks.shouldInlineLevelBoxStretchLineBox(lineBox, inlineLevelBox); |
| 360 |
}; |
| 363 |
// FIXME: Add support for layout bounds based line box height. |
361 |
// FIXME: Add support for layout bounds based line box height. |
| 364 |
auto minimumLogicalTop = InlineLayoutUnit { }; |
362 |
auto minimumLogicalTop = Optional<InlineLayoutUnit> { }; |
| 365 |
auto maximumlogicalBottom = InlineLayoutUnit { }; |
363 |
auto maximumLogicalBottom = Optional<InlineLayoutUnit> { }; |
| 366 |
for (auto absoluteLogicalTopAndBottom : absoluteLogicalTopAndBottomMap.values()) { |
364 |
for (auto absoluteLogicalTopAndBottom : absoluteLogicalTopAndBottomMap.values()) { |
| 367 |
minimumLogicalTop = std::min(minimumLogicalTop, absoluteLogicalTopAndBottom.top); |
365 |
auto& inlineLevelBox = *absoluteLogicalTopAndBottom.inlineLevelBox; |
| 368 |
maximumlogicalBottom = std::max(maximumlogicalBottom, absoluteLogicalTopAndBottom.bottom); |
366 |
if (!shouldStretchLineBox(inlineLevelBox)) |
|
|
367 |
continue; |
| 368 |
minimumLogicalTop = std::min(minimumLogicalTop.valueOr(absoluteLogicalTopAndBottom.top), absoluteLogicalTopAndBottom.top); |
| 369 |
maximumLogicalBottom = std::max(maximumLogicalBottom.valueOr(absoluteLogicalTopAndBottom.bottom), absoluteLogicalTopAndBottom.bottom); |
| 370 |
if (inlineLevelBox.verticalAlign() == VerticalAlign::Baseline) |
| 371 |
maximumBaselineAlignedAscent = std::max(maximumBaselineAlignedAscent, inlineLevelBox.layoutBounds().ascent); |
| 369 |
} |
372 |
} |
| 370 |
minimumInlineBoxRelativeLogicalTop = minimumLogicalTop; |
373 |
inlineBoxRelativeLogicalHeight = maximumLogicalBottom.valueOr(InlineLayoutUnit()) - minimumLogicalTop.valueOr(InlineLayoutUnit()); |
| 371 |
inlineBoxRelativeLogicalHeight = maximumlogicalBottom - minimumLogicalTop; |
|
|
| 372 |
lineBoxLogicalHeight = inlineBoxRelativeLogicalHeight; |
374 |
lineBoxLogicalHeight = inlineBoxRelativeLogicalHeight; |
| 373 |
// Now stretch the line box with the line box relative inline level boxes. |
375 |
// Now stretch the line box with the line box relative inline level boxes. |
| 374 |
for (auto* lineBoxRelativeInlineLevelBox : lineBoxRelativeInlineLevelBoxes) |
376 |
for (auto* lineBoxRelativeInlineLevelBox : lineBoxRelativeInlineLevelBoxes) { |
|
|
377 |
if (!shouldStretchLineBox(*lineBoxRelativeInlineLevelBox)) |
| 378 |
continue; |
| 375 |
lineBoxLogicalHeight = std::max(lineBoxLogicalHeight, lineBoxRelativeInlineLevelBox->layoutBounds().height()); |
379 |
lineBoxLogicalHeight = std::max(lineBoxLogicalHeight, lineBoxRelativeInlineLevelBox->layoutBounds().height()); |
|
|
380 |
} |
| 376 |
}; |
381 |
}; |
| 377 |
computeLineBoxLogicalHeight(); |
382 |
computeLineBoxLogicalHeight(); |
| 378 |
|
383 |
|
| 379 |
auto adjustRootInlineBoxVerticalPosition = [&] { |
384 |
auto adjustRootInlineBoxVerticalPosition = [&] { |
| 380 |
if (minimumInlineBoxRelativeLogicalTop >= 0) |
385 |
// FIXME: Add support for cases when the stretching inline boxes are not baseline aligned. |
| 381 |
return; |
386 |
auto logicalTop = maximumBaselineAlignedAscent - rootInlineBox.layoutBounds().ascent; |
| 382 |
rootInlineBox.setLogicalTop(-minimumInlineBoxRelativeLogicalTop); |
387 |
rootInlineBox.setLogicalTop(logicalTop); |
| 383 |
}; |
388 |
}; |
| 384 |
adjustRootInlineBoxVerticalPosition(); |
389 |
adjustRootInlineBoxVerticalPosition(); |
| 385 |
|
390 |
|
|
Lines 417-424
LineBox InlineFormattingContext::Geometry::lineBoxForLineContent(const LineBuild
a/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp_sec6
|
| 417 |
|
422 |
|
| 418 |
InlineRect InlineFormattingContext::Geometry::computedLineLogicalRect(const LineBox& lineBox, const LineBuilder::LineContent& lineContent) const |
423 |
InlineRect InlineFormattingContext::Geometry::computedLineLogicalRect(const LineBox& lineBox, const LineBuilder::LineContent& lineContent) const |
| 419 |
{ |
424 |
{ |
| 420 |
auto isConsideredEmpty = lineContent.runs.isEmpty() || lineBox.isLineVisuallyEmpty(); |
425 |
return { lineContent.logicalTopLeft, lineContent.lineLogicalWidth, lineBox.logicalHeight() }; |
| 421 |
return { lineContent.logicalTopLeft, lineContent.lineLogicalWidth, isConsideredEmpty ? InlineLayoutUnit() : lineBox.logicalHeight()}; |
|
|
| 422 |
} |
426 |
} |
| 423 |
|
427 |
|
| 424 |
InlineLayoutUnit InlineFormattingContext::Geometry::logicalTopForNextLine(const LineBuilder::LineContent& lineContent, InlineLayoutUnit previousLineLogicalBottom, const FloatingContext& floatingContext) const |
428 |
InlineLayoutUnit InlineFormattingContext::Geometry::logicalTopForNextLine(const LineBuilder::LineContent& lineContent, InlineLayoutUnit previousLineLogicalBottom, const FloatingContext& floatingContext) const |