1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-18 18:05:06 +00:00
Commit graph

158 commits

Author SHA1 Message Date
Andreas Kling
dcc25f7d7a LibWeb: Layout table-cell contents once again once final width is known
This makes centered and right-aligned table-cell contents position
itself correctly.
2020-06-28 20:54:45 +02:00
Andreas Kling
7fc988b919 LibWeb: Start working on supporting fixed table layouts
Sometimes people make tables with a specific width. In those cases,
we can't just use the auto-sizing algorithm, but instead have to
respect whatever width the content specifies.

This is a bit rickety right now, since we don't implement generation
of anonymous table boxes.

The basic mechanism here is that block layout (which table-cell uses)
now has a virtual way of asking for the width of the logical containing
block. This is necessary as table-row does not produce a block-level
element and so was previously unable to provide a containing block
width for table-cell layout.

If the table has a non-auto specified width, we now interpret that as
a request to use fixed table layout. This will evolve over time. :^)
2020-06-28 15:13:56 +02:00
Andreas Kling
9576f6b1d4 LibWeb: Collapse top and bottom margin of empty sibling blocks
Margin collapsing is a bit confusing, but if I understand correctly,
when collapsing a box's top margin with the vertically adjacent
sibling box above, we should "skip over" empty (0-height) boxes and
collapse their margin with *their* vertically adjacent sibling box
above, etc. Iterating until we hit the first non-empty in-flow block.

This pulls up the bottom part of the face on ACID2. :^)
2020-06-28 11:20:15 +02:00
Andreas Kling
ba76a72422 LibWeb: Skip over floating elements when collapsing margins
Two sibling blocks are not vertically adjacent if one is float:left
and the other is float:none. Respect this when collapsing margins.
2020-06-26 18:27:12 +02:00
Andreas Kling
62daa6f73c LibWeb: Add the 'float' CSS property to LayoutStyle
Note that we don't use the property for anything yet, as I'm still
wrapping my head around how to implement floats.
2020-06-26 18:27:12 +02:00
Andreas Kling
8be74ea65c LibWeb: Percentage 'height' should sometimes behave as 'auto'
Something like "height: 50%" is equivalent to "height: auto" unless the
containing block has explicitly specified height.
2020-06-25 16:04:57 +02:00
Andreas Kling
bab0143bb2 LibWeb: Place normal-flow blocks relative to non-absolute siblings
We could previously place a box next to a preceding sibling with
position:fixed, which is wrong since fixed-position elements are taken
out of the normal flow.
2020-06-25 15:53:23 +02:00
Andreas Kling
b2f54be514 LibWeb: Draw the margin and padding boxes around the inspected node
When highlighting a node in the inspector, we now paint three overlays:

- The content box (magenta)
- The padding box (cyan)
- The margin box (yellow)

This makes it a lot easier to debug layout issues.
2020-06-25 15:53:23 +02:00
Andreas Kling
8f92ed957b LibWeb: Iterating more on placement of absolutely positioned elements 2020-06-25 15:53:23 +02:00
Andreas Kling
ee1c241be9 LibWeb: Update the border metrics of absolutely positioned boxes
We were neglecting to populate the border parts of BoxModelMetrics for
absolutely positioned block descendants.
2020-06-25 15:53:23 +02:00
Andreas Kling
232e41a238 LibWeb: Remove empty trailing line boxes
Sometimes we end up with an empty line box at the bottom of a block.
Instead of worrying about this in all the places we split into lines,
just remove the trailing box (if any) after splitting is finshed.
2020-06-25 15:53:23 +02:00
Andreas Kling
58f76ed11f LibWeb: Avoid some redundant resolution of padding values during layout
Padding is not affected by the width constraining algorithm, so we can
just resolve it up front.
2020-06-25 15:53:23 +02:00
Andreas Kling
8960c6f8fe LibWeb: Use the cached white-space from LayoutStyle in text_for_style() 2020-06-24 21:44:11 +02:00
Andreas Kling
440b4ece22 LibWeb: Move border width and color into LayoutStyle
To make this possible, I also had to give each LayoutNode a Document&
so it can resolve document-specific colors correctly. There's probably
ways to avoid having this extra member by resolving colors later, but
this works for now.
2020-06-24 19:43:27 +02:00
Andreas Kling
4b2ac34725 LibWeb: Move the offset, margin and padding boxes into LayoutStyle 2020-06-24 18:06:21 +02:00
Andreas Kling
6b334e02e6 LibWeb: Move white-space into LayoutStyle 2020-06-24 18:06:21 +02:00
Andreas Kling
5d86305a72 LibWeb: Move height, min-height and max-height into LayoutStyle 2020-06-24 16:49:51 +02:00
Andreas Kling
ec466c0385 LibWeb: Move min-width and max-width into LayoutStyle 2020-06-24 16:49:51 +02:00
Andreas Kling
ecacab8618 LibWeb: Move width into LayoutStyle
This patch also adds the ability for Length to contain percentage
values. This is a little off-spec, but will make storing and dealing
with lengths a lot easier.

To resolve a Length to a px-or-auto Length, there are now helpers
for that. After calling them, you no longer have to think about
em, rem, %, and such things.
2020-06-24 16:49:51 +02:00
Andreas Kling
959464fce4 LibWeb: Move position and text-align to LayoutStyle 2020-06-24 16:49:51 +02:00
Andreas Kling
6f28f08096 LibWeb: Add LayoutStyle, a place to store style info for layout & paint
StyleProperties is really only the specified "input" to what eventually
becomes the used/computed style we use for layout and painting.

Unlike StyleProperties, LayoutStyle will have strongly typed values for
everything it contains (i.e no CSS::ValueID or strings, etc.)

This first patch moves z-index into LayoutStyle.
2020-06-24 16:49:51 +02:00
Andreas Kling
5e83a97fa2 LibWeb: Rename LayoutNode::style() => specified_style()
Let's make way for a slightly-more-cooked style() that will eventually
replace the raw specified_style() for layout and paint purposes.
2020-06-24 13:54:31 +02:00
Andreas Kling
f742b245b7 LibWeb: Turn BoxModelMetrics into a simple struct
Using getters for this thing was just cumbersome and didn't achieve
anything of value so just turn it into a plain struct.
2020-06-24 11:22:34 +02:00
Andreas Kling
5744dd43c5 LibWeb: Remove default Length constructor and add make_auto()/make_px()
To prepare for adding an undefined/empty state for Length, let's first
move away from Length() creating an auto value.
2020-06-24 11:08:46 +02:00
Andreas Kling
26eef65017 LibWeb: Use the cached text-align value in LineBox::add_fragment() 2020-06-24 00:09:45 +02:00
Andreas Kling
f4ecb5362f LibWeb: Cache the used CSS text-align property on LayoutNodeWithStyle 2020-06-23 23:28:40 +02:00
Andreas Kling
5f0a1ef21b LibWeb: Always inline is<LayoutBox>() and is<LayoutBlock>() 2020-06-23 23:21:39 +02:00
Andreas Kling
9b8464f455 LibWeb: Cache the used CSS 'position' value on LayoutNodeWithStyle
This avoids having to query the StyleProperties hash map whenever we
need to know if an element is absolutely positioned. This was extremely
hot in interactive window resize profiles.
2020-06-23 23:15:23 +02:00
Andreas Kling
86098505ec LibWeb: Handle position:absolute with both left and right specified
In this case, we need to undo the right-side offsetting, since the
width computation algorithm will already have stretched the width to
accomodate both the side constraints.
2020-06-23 20:05:35 +02:00
Andreas Kling
8d235d0e2f LibWeb: Make sure BoxModelMetrics are set for position:absolute boxes
This is all very redundant and we should find a way to share this code
between at least some of the positioning modes.
2020-06-23 19:21:04 +02:00
Andreas Kling
7c848645c3 LibWeb: Take margin into account when positioning absolute descendants 2020-06-23 19:20:06 +02:00
Andreas Kling
aeeaf33638 LibWeb: Respect specified width when computing shrink-to-fit candidates
Previously we would always just use the combined content width as the
shrunken width in shrink-to-fit width calculations, but if the element
has a non-auto specified width, we should just let that take over.

This is far from perfect and doesn't take stuff like min/max-width
into account. Will need more work, this just covers the basic case.
2020-06-23 18:55:25 +02:00
Andreas Kling
10255bc5c6 LibWeb+Browser: Decode non-animated images out-of-process :^)
We now use the ImageDecoder service in LibWeb for everything except
GIF images (we'll have to deal with them later, ofc.)

This has a little bit of overhead but we should be able to optimize
it until it becomes negligible.
2020-06-22 21:47:01 +02:00
Andreas Kling
b959d06ace LibWeb: Generate HTMLCanvasElement bindings from IDL :^) 2020-06-21 15:37:13 +02:00
Andreas Kling
995d93c9d9 LibWeb: Move StackingContext from Layout/ to Painting/
The stacking context tree doesn't affect layout at all, so let's move
it into the Painting/ directory. I'm not sure yet if it's worth going
for a fullly separate painting tree. So far I'm thinking a stacking
context tree with pointers into the layout tree might be enough.
2020-06-18 21:42:19 +02:00
Andreas Kling
8c82d26668 LibWeb: Rename LayoutNode::render() to paint()
"Paint" matches what we call this in the rest of the system. Let's not
confuse things by mixing paint/render/draw all the time. I'm guilty of
this in more places..

Also rename RenderingContext => PaintContext.
2020-06-18 21:37:20 +02:00
Andreas Kling
dec0cd3755 LibWeb: Respect min-width and max-width on position:absolute elements 2020-06-18 21:31:20 +02:00
Andreas Kling
55a3575a7c LibWeb: More work on width of position:absolute elements
The shrink-to-fit width algorithm actually works a little bit different
in the absolute positioning context, so it can't share all of its code
with non-absolute positioning.

Also, inline-block elements were always inserting unnecessary line
breaks when splitting, which caused the preferred width to be smaller
than it should be. This patch fixes that as well, by just not breaking
after inline-block elements in LayoutMode::OnlyRequiredLineBreaks.
2020-06-18 21:16:29 +02:00
Andreas Kling
cfab53903f LibWeb: Separate layout tree rendering into phases
CSS defines a very specific paint order. This patch starts steering us
towards respecting that by introducing the PaintPhase enum with values:

- Background
- Border
- Foreground
- Overlay (internal overlays used by inspector)

Basically, to get the right visual result, we have to render the page
multiple times, going one phase at a time.
2020-06-18 18:57:35 +02:00
Andreas Kling
abe811104f LibWeb: Better width computation for position:absolute blocks
This patch basically translates the CSS2.2 spec language into C++ for
computing the  width of absolutely positioned non-replaced elements.
2020-06-18 18:28:32 +02:00
Andreas Kling
6242e029ed LibWeb: Make Element::tag_name() return a const FlyString&
The more generic virtual variant is renamed to node_name() and now only
Element has tag_name(). This removes a huge amount of String ctor/dtor
churn in selector matching.
2020-06-16 19:09:14 +02:00
Andreas Kling
308c3ccc44 LibWeb: Allow block children of inlines
Hey, why not. We did all the hard work for display:inline-block already
and now we can just allow this.

This makes <a><h1>Hello friends!</h1></a> work :^)
2020-06-15 17:56:00 +02:00
Andreas Kling
96da15a8a4 LibWeb: Respect CSS z-index property while painting
To support z-ordering when painting, the layout tree now has a parallel
sparse tree of stacking contexts. The rules for which layout boxes
establish a stacking context are a bit complex, but the intent is to
encapsulate the decision making into establishes_stacking_context().

When we paint, we start from the ICB (LayoutDocument) who always has a
StackingContext and then paint the tree of StackingContexts where each
node has its children sorted by z-index.

This is pretty crude, but gets the basic job done. Note that this does
not yet support hit testing; hit testing is still done using a naive
treewalk from the root.
2020-06-15 17:56:00 +02:00
Andreas Kling
ce3260c6bf LibWeb: Layout nodes without own style can't be absolutely positioned
The only layout nodes that don't have their own style are LayoutText
(they inherit the style from their parent element since text cannot
be styled by CSS.)

However, it never makes sense for text nodes to have absolute position
so don't claim it.
2020-06-15 17:56:00 +02:00
Andreas Kling
9ad3e6cd8a LibWeb: Don't assert when containing block doesn't know how to place
We can just log that we don't know what to do for now.
2020-06-14 22:07:00 +02:00
Andreas Kling
73c9f7ebf4 LibWeb: Move "visible in viewport" state tracking to ImageLoader
This should technically apply to any LayoutImage, so let's just move
it to ImageLoader.
2020-06-14 19:32:23 +02:00
Andreas Kling
63b1c8e882 LibWeb: Remove some unused functions from LayoutTable 2020-06-14 19:06:02 +02:00
Andreas Kling
c7d9229a0f LibWeb: Reorganize layout algorithm
Previously, layout recursively performed these steps (roughly):

1. Compute own width
2. Compute own position
3. Layout in-flow children
4. Compute own height
5. Layout absolutely positioned descendants

However, step (2) was pretty inconsistent. Some things computed their
own position, others had their parent do it for them, etc.
To get closer to CSS spec language, and make things easier in general,
this patch reorganizes the algorithm into:

1. Compute own width & height
2. Compute width & height of in-flow managed descendants
3. Move in-flow managed descendants to their final position
4. Layout absolutely positioned descendants

Block layout is now driven by the containing block, which will iterate
the descendants it's responsible for. There are a lot of inefficient
patterns in this logic right now, but they can easily be replaced with
better iteration functions once we settle on a long-term architecture.

Since the ICB (LayoutDocument) is at (0, 0), it doesn't rely on a
containing block to move it into place.

This code is still evolving along with my understanding of CSS layout,
so it's likely that we'll reorganize this again sooner or later. :^)
2020-06-14 19:01:54 +02:00
Andreas Kling
332c471301 LibWeb: Simplify LayoutBlock::layout_block_children() a little bit
No need to worry about inline children if children are not inline(!)
2020-06-14 16:48:17 +02:00
Andreas Kling
62615dfc31 LibWeb: Add LayoutNode::frame() reference getter
Any live layout tree always has a corresponding live Frame, as we will
never create a layout tree for a frameless document.
2020-06-14 16:45:45 +02:00