Commit graph

20 commits

Author SHA1 Message Date
Andreas Kling
e938860126 LibWeb: Make text justification work between floats
While inline content between floating elements was broken correctly,
text justification was still using the original amount of available
space (without accounting for floats) when justifying fragments.
2023-05-16 14:35:10 +02:00
Mathis Wiehl
9927dab993 LibWeb: Don't drop single <br/> lines
Previously, when having inline contexts consisting of just a `<br/>`
tag, we would not create a line box.

Ensure that there is always a line box when a line is explicitly being
broken and also ensure it won't be trimmed due to being empty.

This will a fix a number of sites that use `<br>` tags for layouts
between block elements (even though the spec says they shouldn't).
2023-03-16 08:40:29 +00:00
Sam Atkins
76047d1932 LibWeb: Convert InlineLevelIterator/LineBox/LineBuilder to new px units 2023-01-05 17:42:31 +01:00
Andreas Kling
195ef5e26f LibWeb: Bring CSS line-height implementation closer to spec
We now distribute the line-height evenly between the space above and
below inline-level boxes. This noticeably improves our baseline
alignment in many cases.

Note that the "vertical-align: <length>" case is quite awkward, as the
extra height added by the offset baseline must count towards the line
box height.

There's a lot of room for improvement here, but this makes the buckets
container on Acid3 show up in the right place, with the right size.
2022-03-24 22:52:44 +01:00
Lenny Maiorani
c37820b898 Libraries: Use default constructors/destructors in LibWeb
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-17 17:23:49 +00:00
Andreas Kling
45f717cfad LibWeb: Respect inline-axis margins between line box fragments :^)
This makes the buckets on ACID3 space out nicely.
2022-03-09 18:47:32 +01:00
Andreas Kling
7dae895704 LibWeb: Align actual baselines, not just bottoms
Until now, we've been treating the bottom of every line box fragment as
its baseline, and just aligning all the bottoms to the bottom of the
line box. That gave decent results in many cases, but was not correct.

This patch starts moving towards actual baseline calculations as
specified by CSS2.

Note that once layout is finished with a line box, we also store the
baseline of the line box in LineBox::m_baseline. This allows us to align
the real baseline of display:inline-block elements with other inline
content on the same line.
2022-03-03 12:57:53 +01:00
Andreas Kling
c6cf240f9a LibWeb: Store bottom edge location with each LineBox
Previously we were computing the bottom edge of a line box by finding
the bottommost fragment on the line.

That method didn't give correct results for line boxes with no fragments
(which is exactly what you get when inserting a bunch of <br> elements.)

To cover all situations, we now keep track of the bottommost edge in the
LineBox object itself.
2022-02-28 14:17:44 +01:00
Andreas Kling
916bbf5910 LibWeb: Use Vector<LineBoxFragment> instead of NonnullOwnPtrVector
This removes one step of indirection, but more importantly, makes it
easy to copy these objects. :^)
2022-02-28 14:17:44 +01:00
Andreas Kling
797f51e122 LibWeb: Add border box top/bottom metrics to line box fragments
This will allow us to support more kinds of vertical alignment.
2022-02-26 09:24:40 +01:00
Andreas Kling
8b369bf7bd LibWeb: Remove unused LineBox::ends_with_forced_line_break() 2022-02-26 08:33:45 +01:00
Andreas Kling
c9700e100e LibWeb: Start making our layout system "transactional"
This patch adds a map of Layout::Node to FormattingState::NodeState.
Instead of updating layout nodes incrementally as layout progresses
through the formatting contexts, all updates are now written to the
corresponding NodeState instead.

At the end of layout, FormattingState::commit() is called, which
transfers all the values from the NodeState objects to the Node.

This will soon allow us to perform completely non-destructive layouts
which don't affect the tree.

Note that there are many imperfections here, and still many places
where we assign to the NodeState, but later read directly from the Node
instead. I'm just committing at this stage to make subsequent diffs
easier to understand.
2022-02-21 18:35:12 +01:00
Andreas Kling
f2a917229a LibWeb: Support inline-level padding and border properly
Here's roughly how this works:

- InlineLevelIterator keeps a nesting stack of inline-level nodes with
  box model metrics.
- When entering a node with box model metrics, we add them to the
  current "leading metrics".
- When exiting a node with box model metrics, we add them to the
  current "trailing metrics".
- Pending leading metrics are consumed by the first fragment added
  to the line.
- Pending trailing metrics are consumed by the last fragment added
  to the line.

Like before, the position of a line box fragment is the top left of its
content box. However, fragments are placed horizontally along the line
with space inserted for padding and border.

InlineNode::paint() now expands the content rect as appropriate when
painting background and borders.

Note that margins and margin collapsing is not yet implemented.

This makes the eyes on ACID2 horizontally centered. :^)
2022-02-14 18:00:21 +01:00
Andreas Kling
70a56d21dc LibWeb: Don't do horizontal inline line layout twice for last line
After pruning empty last line boxes, we now avoid re-running the
horizontal fragment positioning step, since that would be wasted work.
2022-01-23 01:22:41 +01:00
Andreas Kling
00bde9ca51 LibWeb: Add Layout::LineBuilder class for incremental line box layout
This class will be used to place items on lines incrementally instead of
the current two-phase approach.
2022-01-23 01:22:41 +01:00
Andreas Kling
1f603c54ff LibWeb: Add inline-level iterator that enumerates items for line layout
This patch adds a new mechanism that allows InlineFormattingContext to
build line boxes incrementally instead of all-in-one go.

Incremental build will eventually allow much better support for CSS
floating objects.
2022-01-23 01:22:41 +01:00
Felix Rauch
30c39e0e41 LibWeb: Fix inline blocks swallowing trailing whitespace
In #10434 an issue with leading whitespace in new lines after
a <br> element was fixed by checking whether the last fragment
of LineBox is empty.

However, this introduced a regression by which whitespace following
inline elements was swallowed, so `<b>Test</b> 123` would appear
like `Test123`.

By asking specifically if we are handling a forced linebreak
instead of implicity asking for a property that may be shared by
other Node types, we can maintain the correct behavior in regards
to leading whitespace on new lines, as well as trailing whitespace
of inline elements.
2021-10-26 17:27:04 +02:00
Andreas Kling
c4826eae4f LibWeb: Rename Layout::BlockBox => BlockContainer
There's a subtle difference here. A "block box" in the spec is a
block-level box, while a "block container" is a box whose children are
either all inline-level boxes in an IFC, or all block-level boxes
participating in a BFC.

Notably, an "inline-block" box is a "block container" but not a "block
box" since it is itself inline-level.
2021-10-06 20:10:36 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Renamed from Libraries/LibWeb/Layout/LineBox.h (Browse further)