* Use 2024 style edition
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
* Reformat all code
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
---------
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Instead of keeping a per-FontGroup cache of the previously used fallback
font, cache this value in the caller of `FontGroup::find_by_codepoint`.
The problem with caching this value in the `FontGroup` is that it can
make one layout different from the next.
Still, it is important to cache the value somewhere so that, for
instance, Chinese character don't have to continuously walk through the
entire fallback list when laying out. The heuristic here is to try to
last used font first if the `Script`s match. At the very least this
should make one layout consistent with the next.
Fixes#35704.
Fixes#35697.
Fixes#35689.
Fixes#35679.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
We were always treating an indefinite `stretch` as the automatic size.
This instead treats it as `0px` on min sizing properties, and as `none`
on max sizing properties, aligning with Blink and this recent CSSWG
resolution: https://github.com/w3c/csswg-drafts/issues/11006
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* layout: Add AxesScrollSensitivity to enable control of scroll in axis
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout_2013: Be compatible with AxesScrollSensitivity
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: update struct AxesScrollSensitivity to euclid::Vector2D
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* display_list: implement From<Overflow> for ScrollSensitivity
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: simplify and reuse scroll related logic
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout_2013: simplify and reuse scroll related logic
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout, layout_2013: revert AxesScrollSensitivity to pair struct
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: Reimport ComputedOverflow as #35103 depends on it
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: Add AxesOverflow to replace PhysicalVec
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: implement scroll of viewport for different axes
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: explicitly handle overflow match
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* Update components/shared/webrender/Cargo.toml
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
A box is usually sized by the formatting context in which it participates.
However, tables have some special sizing behaviors that we implemented
with a `content_inline_size_for_table` override.
However, breaking the assumptions of the formatting context isn't great.
It was also bad for performance that we could try to layout a table
among floats even though it wouldn't en up fitting because of a larger
min-content size.
Therefore, this changes the logic so that formatting contexts use some
special sizing for tables, and then tables only override that amount
when there are collapsed columns. Eventually, we should try to remove
that case too, see https://github.com/w3c/csswg-drafts/issues/11408
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
When we try to place a table next to some floats, and it doesn't fit
vertically, then we try again considering more floats. And as an
optimization we were using the previous width of the table as a minimum.
However, this was wrong, because the table might accept a smaller width
when the available space is smaller than beforehand.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
The specification doesn't say how to deal with percentages when
determining the minimum and maximum size of a table grid, so follow the
approach that Chromium uses.
Essentially, figure out the "missing" percentage from the non-percentage
columns and then use that to work backwards to fine the size of the
percentage ones.
This change is larger than one might expect, because this percentage
approach shouldn't happen for tables that are descendants of a flex,
grid or table container (except when there is an interceding absolute).
We have to pass this information down when building the box tree. This
will also make it easier to improve propagated text decorations in the
future.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
We were just checking the computed `display` style, but a few HTML
elements can ignore some `display` values and generate a different
kind of box.
This uses the right check, though for now there is no difference in
behavior since we don't have special HTML layouts.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Some layouts like table need some style overrides. We were handling this
in `ComputedValuesExt`, but it was messy, unreliable and too limited.
For example, we were assuming that a style with `display: table` would
belong to a table wrapper box or table grid box. However, certain HTML
elements can ignore their `display` value and generate a different kind
of box. I think we aren't doing that yet, but we will need this.
Also, resolving the used border of a table needs layout information,
which we don't have in `ComputedValuesExt`. This patch will allow to
improve border collapsing in a follow-up.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
There were two kinds of layout tracing controlled by the same debugging
option:
- modern layout: Functionality that dumped a JSON serialization of the
layout tree before and after layout.
- legacy layout: A scope based tracing that reported the process of
layout in a structured way.
I don't think anyone working on layout is using either of these two
features. For modern layout requiring data structure to implement
`serde` serialization is incredibly inconvenient and also generates a
lot of extra code.
We also have a more modern tracing functionality based on perfetto that
we have started to use for layout and IMO it's actually being used and
more robust.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
It used to be an `AuOrAuto`, turning it into a `SizeConstraint` allows
passing the information about the min and max constraints when the
containing block doesn't have a definite block size.
This will be useful for table layout.
Note that in most cases we were already constructing the containing
block from a `SizeConstraint`, but we were calling `to_auto_or()` to
turn it into an `AuOrAuto`.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Push the interior mutability into enum variants of `Fragment`, so that
they can be cloned. This saves memory in the `Fragment` tree as the
`Fragment` enum is now a relatively wee 16 bytes and the interior parts
can be a variety of sizes. Before, every `Fragment` was the size of the
biggest kind (`BoxFragment` - 248 bytes).
This a step on the way toward incremental layout.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
A box is usually sized by the formatting context in which it participates.
However, tables have some special sizing behaviors, and these were in
conflict.
Instead of letting tables attempting to re-resolve their inline table,
which failed to e.g. take flex properties into account or resolve sizing
keywords correctly, now tables will trust the inline size determined by
the parent. They will only floor it by the min-content size, and maybe
shrink the final size due to collapsed columns.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
When laying out a block-level box that avoids floats, if we know that
its size doesn't depend on the available space, we can take a fast path
and only lay it out once. If its size depends on the available space,
we may have to lay it out multiple times, which can be slower.
This patch improves the check for this dependency on the available space.
For example, `min-width: 200px; width: 100px; max-width: stretch` was
previously considered to depend on the available space because of
`max-width`. However, `max-width` is irrelevant when the min size is
greater than the preferred size.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
There is an early return for independent formatting contexts, so at this
point we don't need to handle them.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
`width` and `max-width` typically treat expressions with percentages as
their initial value, but for the min-content contribution of replaced
elements, they should instead be treated as zero.
https://drafts.csswg.org/css-sizing-3/#replaced-percentage-min-contribution
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
The new version of rust allows us to elide some lifetimes and clippy is
now complaining about this. This change elides them where possible and
removes the clippy exceptions.
Fixes#34804.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Block layout uses some heuristics to guess whether margins are separated
by clearance and then don't collapse. These heuristics now take the
min-content, max-content, fit-content and stretch sizing keywords into
account.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
In order to compute the inline min-content and max-content contributions
of an anonymous block, we were finding its min-content and max-content
inline size with a SizeConstraint coming from the block size of the box.
However, anonymous blocks do not establish a containing block for their
contents, so this patch uses a SizeConstraint from the block size of the
containing block.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
If a table element had e.g. `width: 0px`, we were assuming that this was
its intrinsic min-content and max-content contributions.
However, tables are always at least as big as its min-content size, so
this patch floors the intrinsic contributions by that amount.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
in each layout logic, in order to correctly resolve sizing keywords.
This patch adds a new `Sizes` struct which holds the preferred, min and
max sizing values for one axis, and unifies the logic to resolve the
final size into there.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Adds support for min-content, max-content, fit-content and stretch,
for the case that was missing from #34568: block-level elements that
establish an independent formatting context, when there are floats.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Manage `<iframe>` size updates in `Window`. In addition to removing
duplicated code, this will allow setting `<iframe>` sizes synchronously
on child `Pipeline`s of the same origin in the script process in a
followup change. The goal is remove flakiness from `<iframe>` sizing.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Adds support for min-content, max-content, fit-content and stretch,
for block-level elements that don't establish an independent formatting
context, and for block-level elements when there is no float.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
It was a bit confusing that e.g. a float with `FloatSide::InlineStart`
would set `FloatBand::left`, or that `PlacementAmongFloats` would
compute `max_inline_start` from the various `FloatBand::left`.
So now all the float logic will consistently use logical terminoligy.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Several structs and enums had a `inline_content_sizes()` method, but it
wasn't clear which ones would try to cache the result, and which ones
would always compute it.
Therefore, this performs some clarifying renaming:
- Cached ones stay as `inline_content_sizes()`
- Uncached ones become `compute_inline_content_sizes()`
Also, to simplify calls to `LayoutBoxBase::inline_content_sizes()`,
`compute_inline_content_sizes()` is moved into a new trait.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Block-level elements that establish an independent formatting context
(or are replaced) need to avoid overlapping floats.
In the non-replaced case, we have two different subcases, depending on
whether the inline size of the element is known. This patch makes them
share more logic.
Then `solve_clearance_and_inline_margins_avoiding_floats()` would only
be used in the replaced case, so it's removed, inlining its logic.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
The refactoring in 264c0f972f stopped
caching the `inline_content_sizes()` calls from:
- `FlexItemBox::layout_for_block_content_size()`
- `IndependentFormattingContext::layout_float_or_atomic_inline()`
- `TaffyContainerContext::compute_child_layout()`
Also, the call from `OutsideMarker::layout()` was never cached.
This patch caches all of them.
It's not clear at all which `inline_content_sizes()` are cached and
which aren't, so I plan to improve the situation in a follow-up.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
- Remove the `LayoutBox::InlineBox` variant that was only used for
inline level boxes. Now they are stored in `LayoutBox::InlineLevel`
along with other kinds of out-of-flow and atomic inline items.
- Reduce the size of `InlineItem` by 260 bytes per item by using atomic
indirection / pointers. This adds a bit of overhead to access items in
exchange for a lot of memory saved.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This might make caching these values a bit easier in the future.
Correcting the visibility of `ContainingBlock` also exposed some new
rustc and clippy warnings that are fixed here.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This allows `SameFormattingContextBlock` to cache inline content sizes
and will eventually allow it to participate in incremental layout.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Add a new struct `LayoutBoxBase`, that will be used throughout the box
tree. The idea of this struct is that we have a place to consistently
store common layout information (style and node information) and also to
cache layout results such as content sizes (inline and maybe later box
sizes) and eventually layout results.
In addition to the addition of this struct,
`IndependentFormattingContext` is flattened slightly so that it directly
holds the contents of both replaced and non-replaced elements.
This is only added to independent formatting contexts, but will later be
added to all block containers as well.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
* Refactor computation of preferred aspect ratios
Computing min/max-content sizes required a ContainingBlock in order to
resolve the padding and border when determining the preferred aspect
ratio. However, all callers already knew the padding and border, so they
can compute the ratio themselves, and pass it directly instead of
the ContainingBlock.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Put preferred aspect ratio into ConstraintSpace
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
---------
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
We were using the preferred aspect ratio provided by the `aspect-ratio`
property instead of the natural aspect ratio. However, the preferred
aspect ratio should only be used to size the replaced element. To paint
the replaced contents into that element we need the natural ratio.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
In order to support size keywords in block layout, we may need to call
`inline_content_sizes()` in order to compute the min/max-content sizes.
But this required a mutable reference in order the update the cache,
and in various places we already had mutable references.
So this switches the cache into a RwLock to avoid needing mutable refs.
Note OnceCell wouldn't work because it's not thread-safe.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>