These functions no longer do anything interesting and just forward to
content_width/content_height. Let's make the callers use those directly
instead and remove this indirection layer.
It returns a PaintableBox (a PaintableWithLines, to be specific), not a
'PaintBox'. paintable_box() without the cast is already available
through BlockContainer's Box base class, we don't need to shadow it.
When calculating the intrinsic width of a box, we now make its content
width & height indefinite before entering the intrinsic sizing layout.
This ensures that any geometry assigned to the box by its parent
formatting context is ignored.
For intrinsic heights, we only make the content height indefinite.
This is because used content width is a valid (but optional) input
to intrinsic height calculation.
Negative width/height sizes are not allowed in CSS, so if our layout
algorithm resolves something to a negative size, we have boogs.
Instead of crashing or rendering something very wrong, we now clamp the
values to 0 and whine on the debug log so that someone can go and figure
out how we got the negative values in the first place. :^)
According to CSS Inline Layout Module Level 3 § 2.2 Step 1. atomic
inlines should be layed out in a line box based on their margin box.
However, up until this patch we were unconditionally considering only
the border box during line box height calculation. This made us
essentially drop all vertical margins for atomic inlines.
The name "initial containing block" was wrong for this, as it doesn't
correspond to the HTML element, and that's specifically what it's
supposed to do! :^)
If text-top or text-bottom are given as values for the vertical-align
property, actually use them and calculate the respective position of
the element.
The actual calculations done (using the font_size, descent, etc.) are
not exactly how I imagined them when reading the spec, but the results
seem acceptable when compared to other browsers.
This fixes a few sizing issues too. The page size is now correct in most
cases! \o/
We get to remove some of the `to_type<>()` shenanigans, though it
reappears in some other places.
This colors a bit outside the lines of the specification, but the spec
doesn't offer a proper explanation for how descendants of a flex item
are supposed to have access to the flex item's main size for purposes
of percentage resolution.
The approach I came up with here was to take the hypothetical main size
of each flex item, and assign it as a temporary main size. This allows
percentage resolution in descendants to work against the pre-flexing
main size of items. This seems to match how other engines behave,
although it feels somewhat dirty. If/when we learn more about this,
we can come up with something nicer.
Percentage heights are now considered definite when their containing
block has a definite height. This makes profile pictures have geometry
on Twitter. (We still don't load the images themselves though.)
This is a big and messy change, and here's the gist:
- AvaliableSpace is now 2x AvailableSize (width and height)
- Layout algorithms are redesigned around the idea of available space
- When doing layout across nested formatting contexts, the parent
context tells the child context how much space is available for the
child's root box in both axes.
- "Available space" replaces "containing block width" in most places.
- The width and height in a box's UsedValues are considered to be
definite after they're assigned to. Marking something as having
definite size is no longer a separate step,
This probably introduces various regressions, but the big win here is
that our layout system now works with available space, just like the
specs are written. Fixing issues will be much easier going forward,
since you don't need to do nearly as much conversion from "spec logic"
to "LibWeb logic" as you previously did.
This patch changes the *computed* representation of the following CSS
properties to use CSS::Size:
- width, min-width, max-width
- height, min-height, max-height
A few things had to change in order for things to keep working,
but I tried to keep the diff to a minimum.
The main trouble was that `min-width` and `max-width` can't actually be
`auto`, but they *can* be `none`. We previously treated `auto` as a
valid value (and it behaved mostly like `none`).
Layout box offset coordinates are always relative to their containing
block. Therefore, the functions that convert between coordinate spaces
should only visit containing blocks and apply their offsets, not *every*
box in the parent chain.
This fixes an issue where some floating boxes were unexpectedly far away
from their containing block.
This is rather subtle and points to our architecture around definite
sizes not being exactly right, but...
At some points during flexbox layout, the spec tells us that the sizes
of certain flex items are considered definite from this point on.
We implement this by marking each item's associated UsedValues as
"has-definite-width/height".
However, this breaks code that tries to resolve computed "auto" sizes
by taking the corresponding size from the containing block. The end
result was that the 1st sizing pass in flexbox would find the right size
for an "auto" sized item, but the 2nd pass would override the correct
size with the containing block's content size in that axis instead.
To work around the issue, FFC now remembers when it "definitizes" an
item, and future attempts to resolve an "auto" computed size for that
value will bypass the computed-auto-is-resolved-against-containing-block
step of the algorithm. It's not perfect, and we'll need to think more
about how to really represent these intermediate states relating to
box sizes being definite..
- Use the border box of the floated element when testing if something
needs to flow around it.
- Take the floated element's containing block size into account (instead
of the BFC root) when calculating available space on a line where a
right-side float intrudes.
When we decide that a box has definite width or height based on its
containing block's corresponding size, we'll want to resolve the
current box's size as well. Otherwise anyone querying the size on
this box will get the bogus message of "yes, this definite, and its
value is zero."
This state is less static than we originally assumed, and there are
special formatting context-specific rules that say certain sizes are
definite in special circumstances.
To be able to support this, we move the has-definite-size flags from
the layout node to the UsedValues struct instead.