Commit graph

35 commits

Author SHA1 Message Date
Andreas Kling
4d401bf796 LibWeb: Make the paint tree GC-allocated
This simplifies the ownership model between DOM/layout/paint nodes
immensely by deferring to the garbage collector for figuring out what's
live and what's not.
2023-01-11 12:55:00 +01:00
Andreas Kling
a0e6882d99 LibWeb: Remove Layout::Node::set_inline()
Now that this flag is no longer used, we can stop setting it.
2022-10-06 15:29:38 +02: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
e099960e4d LibWeb: Remove a bunch of no-longer needed #includes 2022-03-11 00:21:49 +01:00
Andreas Kling
ed84fbce47 LibWeb: Make Paintable ref-counted
This will allow us to use a protective NonnullRefPtr to keep paintables
alive while running arbitrary JavaScript in response to events.
2022-03-11 00:21:49 +01:00
Andreas Kling
aae356baf1 LibWeb: Port inline elements to the new Paintable system
This patch adds InlinePaintable which corresponds to Layout::InlineNode.
2022-03-11 00:21:49 +01:00
Andreas Kling
9461e44afa LibWeb: Use Layout::Box::paint_box() accessor in more places 2022-03-11 00:21:49 +01:00
Andreas Kling
02b316fd5c LibWeb: Let Paintable perform the painting
This patch adds a bunch of Paintable subclasses, each corresponding to
the Layout::Node subclasses that had a paint() override. All painting
logic is moved from layout nodes into their corresponding paintables.

Paintables are now created by asking a Layout::Box to produce one:

    static NonnullOwnPtr<Paintable> Layout::Box::create_paintable()

Note that inline nodes still have their painting logic. Since they
are not boxes, and all paintables have a corresponding box, we'll need
to come up with some other solution for them.
2022-03-11 00:21:49 +01:00
Andreas Kling
7af03df4c3 LibWeb: Make Painting::Box virtual and add Painting::BoxWithLines
BlockContainer paint boxes are the only ones that have line boxes
associated, so let's not waste memory on line boxes in all the other
types of boxes.

This also adds Layout::Box::paint_box() and the more tightly typed
Layout::BlockContainer::paint_box() to get at the paint box from the
corresponding layout box.
2022-03-11 00:21:49 +01:00
Andreas Kling
f0d833a3d7 LibWeb: Move StackingContext and PaintPhase into the Painting namespace 2022-03-11 00:21:49 +01:00
Andreas Kling
a4d51b3dc2 LibWeb: Add Painting::Box and move things from Layout::Box into it
The "paintable" state in Layout::Box was actually not safe to access
until after layout had been performed.

As a first step towards making this harder to mess up accidentally,
this patch moves painting information from Layout::Box to a new class:
Painting::Box. Every layout can have a corresponding paint box, and
it holds the final used metrics determined by layout.

The paint box is created and populated by FormattingState::commit().

I've also added DOM::Node::paint_box() as a convenient way to access
the paint box (if available) of a given DOM node.

Going forward, I believe this will allow us to better separate data
that belongs to layout vs painting, and also open up opportunities
for naturally invalidating caches in the paint box (since it's
reconstituted by every layout.)
2022-03-11 00:21:49 +01:00
Sam Atkins
5113128bc9 LibWeb: Paint InlineNode overlay in correct phase, skip pseudo-elements
We were painting this in the Foreground phase by mistake. Also, the
`inspected_node() == dom_node()` check returns true for pseudo-elements
(both values are nullptr) so I've added an extra check there. As noted,
once pseudo-elements are inspectable we will need to revisit this.
2022-02-25 19:35:34 +01:00
Sam Atkins
7bb721bea2 LibWeb: Make display: foo box constructors take the Element by pointer
This means we can instantiate them for pseudo-elements, which don't have
an associated Element. They all pass it to their parent as a
`Layout::Node*` and handle a lack of `layout_node()` already so this
won't affect any functionality.
2022-02-25 19:35:34 +01:00
Sam Atkins
b715943035 LibWeb: Remove redundant Length::resolved() calls
Now that calc() is also resolved in to_px(), code in the form
`foo.resolved(bar).to_px(bar)` can be simplified to `foo.to_px(bar)`.
2022-02-18 19:04:37 +01:00
Sam Atkins
67066c5140 LibWeb: Remove fallback value from Length::resolved()
Nobody makes undefined Lengths now, (although actually removing
Undefined will come in a later commit) so we can remove this parameter,
and `resolved_or_auto()`/`resolved_or_zero()`.
2022-02-18 19:04:37 +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
Sam Atkins
103613a3a9 LibWeb: Incorporate spread-distance into box-shadow rendering
We also pass whether the shadow goes inside or outside the element. Only
outer shadows are rendered currently, and inner ones may want to be
handled separately from them, as they will never interfere with each
other.
2022-02-08 17:45:51 +01:00
Sam Atkins
10c6c77b5c LibWeb: Render multiple box-shadows
Because why not? :^)
2022-02-08 17:45:51 +01:00
Andreas Kling
d30cbf5d72 LibWeb: Remove unnecessary check for 0-sized fragments in InlineNode
We should no longer be generating empty fragments at the start and end
of an InlineNode, so we can drop this check.
2022-02-06 02:15:59 +01:00
Andreas Kling
3ad08a932c LibWeb: Only compute containing block rect once in InlineNode::paint() 2022-02-06 02:15:49 +01:00
Andreas Kling
766d816db3 LibWeb: Remove old Layout::Node::split_into_lines() API
Now that we build lines incrementally, we no longer need the atomic line
splitting API.

The new InlineLevelIterator and LineBuilder setup does have some
regressions from the old behavior, but we can deal with them as we go.
2022-01-23 01:22:41 +01:00
Sam Atkins
bfcbab0dcf LibWeb: Remove reference_for_percent parameter from Length::resolved()
Despite looking like it was still needed, it was only used for passing
to other calls to Length::resolved() recursively. This makes the
various `foo.resolved().resolved()` calls a lot less awkward.
(Though, still quite awkward.)

I think we'd need to separate calculated lengths out to properly tidy
these calls up, but one yak at a time. :^)
2022-01-20 00:04:10 +01:00
Sam Atkins
dc681913e8 LibWeb: Convert width/height and min-/max- versions to LengthPercentage
A lot of this is quite ugly, but it should only be so until I remove
Length::Type::Percentage entirely. (Which should happen later in this
PR, otherwise, yell at me!) For now, a lot of things have to be
resolved twice, first from a LengthPercentage to a Length, and then
from a Length to a pixel one.
2022-01-20 00:04:10 +01:00
Sam Atkins
6234e3fcb3 LibWeb: Implement background-clip :^)
We now pass in the Layout Node so that we can read the BoxModelMetrics.
Renamed a couple of variables too for clarity.
2021-11-17 22:20:01 +01:00
Sam Atkins
e8b7946732 LibWeb: Paint backgrounds with multiple layers :^) 2021-11-17 22:20:01 +01:00
Sam Atkins
1e53768f1b LibWeb: Combine background-repeat-x/y pseudo-properties
While right now this doesn't save much complexity, it will do once we
care about multiple background layers per node. Then, having a single
repeat value per layer will simplify things.

It also means we can remove the pseudo-property concept entirely! :^)
2021-11-10 14:38:49 +01:00
Andreas Kling
f73aa8e2bd LibWeb: Move line boxes from Layout::Box to BlockContainer
Per the spec, only a BlockContainer" can have line boxes, so let's not
clutter up every Layout::Box with line boxes.

This also allows us to establish an invariant that BFC and IFC always
operate on a Layout::BlockContainer.

Note that if BlockContainer has all block-level children, its line boxes
are not used for anything. They are only used in the all inline-level
children scenario.
2021-10-06 21:53:25 +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
Sam Atkins
0cedb7a7c4 LibWeb: Give InlineNodes borders :^) 2021-09-19 22:53:35 +02:00
Sam Atkins
0712036485 LibWeb: Give InlineNodes a box-shadow :^) 2021-09-19 22:53:35 +02:00
Sam Atkins
912596fae8 LibWeb: Give InlineNodes a background
This now uses the same code as Box, so images, repeat-rules, and
anything that's added in the future will work for `display: inline`
elements too. :^)
2021-09-19 22:53:35 +02:00
Sam Atkins
3b6325e787 LibWeb: Move InlineNode background code from paint_fragment -> paint
`paint_fragment()` seems to never get called. Moving the painting to
`paint()` fixes the background.
2021-09-19 22:53:35 +02:00
Sam Atkins
226fe4b57d LibWeb: Paint inspection outline for InlineNodes :^)
This iterates the fragments of the containing block, and paints their
outlines if they are descendants of the InlineNode.

If multiple fragments are adjacent, eg:

```html
<span><b>Well</b> hello <i>friends!</i></span>
```

...then we get a double-thick outline between "Well", " hello " and
"friends!", but we can come back to this after we implement
non-rectangular outlines for the `outline` CSS property.
2021-08-23 15:59:29 +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/InlineNode.cpp (Browse further)