From https://drafts.csswg.org/css-flexbox-1/#intrinsic-cross-sizes,
> The min-content/max-content cross size of a single-line flex container
> is the largest min-content contribution/max-content contribution
> (respectively) of its flex items.
We were using the min/max-content size instead of the min/max-content
contribution.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
In particular, this takes into account that flex items may be stretched,
and if they have an aspect ratio, we ma6y need to convert the stretched
size through the ratio.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
When computing the automatic minimum size, flex layout was using the
natural aspect ratio, ignoring the `aspect-ratio` property.
`ReplacedContent::inline_size_over_block_size_intrinsic_ratio()` is now
made private to avoid more accidental uses.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
`main_content_size_info()` was always assigning the main-axis automatic
minimum size into the inline axis. But in a column flexbox, the main
axis corresponds to the block axis.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
We were only handling the aspect ratio of a replaced element when
computing its min/max-content contribution, but not when computing
the min/max-content size. Now both cases will take it into account.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
When computing the min-content or max-content size of an element we
need to ignore `inline-size`, `min-inline-size` and `max-inline-size`.
However, we should take the block-axis sizing properties into account.
That's because the contents could have percentages depending on them,
which can then affect their inline size via an aspect ratio.
Therefore, this patch adds `IndefiniteContainingBlock`, which is similar
to `ContainingBlock`, but it allows an indefinite inline-size. This
struct is then passed arround during intrinsic sizing.
More refinement will be needed in follow-up patches in order to fully
address the problem.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
When laying out the contents of a flex item, we used to resolve their
cross-axis percentages against the preferred cross size of the item.
Now we will take the min and max cross sizes into account.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This adds supports for right-to-left text assigning bidi levels to all
line items when necessary. This includes support for the `dir` attribute
as well as corresponding CSS properties like `unicode-bidi`. It only
implements right-to-left rendering for inline layout at the moment and
doesn't include support for `dir=auto`. Because of missing features,
this causes quite a few tests to start failing, as references become
incorrect due to right-to-left rendering being active in some cases,
but not others (before it didn't exist at all).
Analysis of most of the new failures:
```
- /css/css-flexbox/gap-001-rtl.html
/css/css-flexbox/gap-004-rtl.html
- Require implementing BiDi in Flexbox, because the start and
end inline margins are opposite the order of items.
- /css/CSS2/bidi-text/direction-applies-to-*.xht
/css/CSS2/bidi-text/direction-applies-to-002.xht
/css/CSS2/bidi-text/direction-applies-to-003.xht
/css/CSS2/bidi-text/direction-applies-to-004.xht
- Broken due to a bug in tables, not allocating the
right amount of width for a column.
- /css/css-lists/inline-list.html
- This fails because we wrongly insert a soft wrap opportunity between the
start of an inline box and its first content.
- /css/css-text/bidi/bidi-lines-001.html
/css/css-text/bidi/bidi-lines-002.html
/css/CSS2/text/bidi-flag-emoji.html
- We do not fully support unicode-bidi: plaintext
- /css/css-text/text-align/text-align-end-010.html
/css/css-text/text-align/text-align-justify-006.html
/css/css-text/text-align/text-align-start-010.html
/html/dom/elements/global-attributes/*
- We do not support dir=auto yet.
- /css/css-text/white-space/tab-bidi-001.html
- Servo doesn't support tab stops
- /css/CSS2/positioning/abspos-block-level-001.html
/css/css-text/word-break/word-break-normal-ar-000.html
- Do not yet support RTL layout in block
- /css/css-text/white-space/pre-wrap-018.html
- Even in RTL contexts, spaces at the end of the line must hang and
not be reordered
- /css/css-text/white-space/trailing-space-and-text-alignment-rtl-002.html
- We are letting spaces hang with white-space: pre, but they shouldn't
hang.
```
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
In particular, `main_content_sizes()` now works with columns.
`layout_for_block_content_size()` is now used for both intrinsic sizes
and intrinsic contributions, a IntrinsicSizingMode parameter is added
to choose the behavior.
Also, we consider the main size of a flex item as indefinite if its flex
basis is indefinite and the flex container has an indefinite main size.
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This change adds an expensive layout for the determination of minimum
automatic size and flex basis in process of flexbox layout. Currently,
the layout is not cached, so may be performed up to 2 more times than
necessary.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
We want to selectively enable right-to-left writing modes per layout
context. This change makes that possible by allowing access to
`writing-mode` though an interface that always returns the default
horizontal top-to-bottom (implicitly left-to-right) writing mode.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
These are similar to `flex-start` and `flex-end`, but in `wrap-reverse`
situations, they are the opposite.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This change removes restrictions on using the column layout mode of
flexbox and adds an initial implementation of sizing for that flex
direction. There's a lot of missing pieces still, but in some cases this
does render column flexbox.
In particular, there are now two code paths for preferred widths
(intrinsic size) calcuation: one in the main axis (row) and one in
the cross axis (column) corresponding to the flex direciton with
horizontal writing modes.
In addition, `FlexItemBox::inline_content_sizes` is removed in favor of
making `sizing::outer_inline` /
`IndependentFormattingContext::outer_inline_content_sizes` generic
enough to handle using a different value for auto minimum sizes, which
flexbox needs.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This converts all geometry in the FragmentTree into physical geometry,
doing conversions ahead of time instead of when traversing the fragment
tree. This is necessary to properly implement BiDi in Servo as we need
to know what side borders are on in mixed RTL and LTR contexts.
In addition, fragments are laid out in a particular context and only
that context knows its writing mode. There were issues where were using
one writing mode to lay out and another to convert to phyisical
coordinates. This isn't an issue now since we only use the default
writing mode, but starts to be an issue with BiDi text.
Closes#25564.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This adds support for `align-content: stretch` by splitting flex line
layout into two phases. The first phase takes place before determing how
much extra space to allocate for stretching items. Then line layout
finishes, which might cause two layouts for items with `align-self:
stretch`.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This change add specification text to comments and restructres the code
a bit to better match the specification. In addition, a the
`establishes_scroll_container()` helper is used instead of looking at
overflow directly. It should not change behavior at all.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Some tests are still broken due to missing preferred widths calculation
for flexbox and also for missing column layout.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
Instead of a complex combination of iterators, use a flatter iteration
design when laying out a flex line.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
Make using the logical geometry types more ergonomic by having them all
implement `Copy` (at most 4 64-bit numbers), similar to what `euclid`
does. In addition add an implementation of `Neg` for `LogicalVec` and
`LogicalSides` as it will be used in upcoming table implementation code.
This only paints text in input fields. Selection and cursor are still
not painted.
In addition to adding this feature, the change also updates the
user-agent.css with the latest from the HTML specification. Extra
padding and extraneous settings (such as a bogus line-height and
min-height) are also removed from servo.css. This leads to some new
passes.
There are some new passes, this introduces failures as inserting text
reveals issues that were hidden before. Notably:
- failures in `/html/editing/editing-0/spelling-and-grammar-checking/`:
We do not support spell-checking.
- Most of the rest of the new failures are missing features of input
boxes that are also missing in legacy layout.
The main change here is that collapsed and `text-transform`'d text is
computed as it's processed by DOM traversal. This single transformed
text is stored in the root of the `InlineFormattingContext`.
This will eventually allow performing linebreaking and shaping of the
entire inline formatting context at once. Allowing for intelligent
processing of linebreaking and also shaping across elements. This
matches more closely what LayoutNG does.
This shouldn't have any (or negligable) behavioral changes, but will
allow us to prevent linebreaking inside of clusters in a followup
change.
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
* Upgrade to stylo 6faedad
* Implement start, end, space-evenly content alignment + fix others
Update test expectations for content alignment fixes
Revert test expectations that are still generating the old results in CI
Update layout2013 test expectation for content alignment
Update content alignment fallback to use safe alignment
Implement fallback alignment
Update content alignment with recent spec changes
* make margin in pbm use app unit
* Simplification
* Consistently resolve inline margins as Au, like block margins
---------
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This doesn't really have observable behavior right now, as much as I
tried to trigger some kind of bug. On the other hand, it's just wrong
and is very obvious when you dump the Fragment tree. If you create a
`display: table-cell` that is a child of the `<body>` all parts of the
anonymous table are flagged as if they are the `<body>` element.
* Fix size of tables in flow layout
The contents of a table can make it bigger than what we would expect
from its 'width', 'min-width', 'height' and ' min-height' properties.
Also, 'width: auto' doesn't stretch it to fill the containing block.
We had to refactor the resolution of margins to happen after layout,
otherwise 'auto' margins wouldn't align correctly.
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Feedback
* Consistently use `containing_block_for_table` in table layout
* Update test result
---------
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This moves white space collapse to right before breaking and shaping
happens, which is more similar to what happens in legacy layout. This is
the first step toward making this procedure more efficient (avoiding
string copies) and also implementing support for `text-transform`.
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
This adds an initial implementation of font fallback, on part with the
one used in legacy layout. There are still issues. For instance, font
matching is done per unicode character rather than based on graphemes or
the shape first approach of Chrome. The idea is that these changes can
be made later.