Put table cell content fragments into a hieararchy of fragments that
include their table row and table row group fragments. This ensures that
things like relative positioning and transforms set on rows and row
groups properly affect cells and cell content.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
At the root of an inline formatting context, we used its vertical-align
in order to compute the strut. That was wrong, since vertical-align
on a block container shouldn't affect the contents, it should only
affect the alignment of the block container (if it's inline-level)
within the parent IFC.
This was only working well if the block container was block-level, since
effective_vertical_align_for_inline_layout returned `baseline` for
block-level boxes.
Instead of the outer display type, this patch changes the logic to check
whether we are at the root of the IFC.
The specification gives instructions for how these values should be
propagated. The other big changs here is that they aren't applied to the
`<body>`.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Anonymous tables should not use legacy pseudos, as the legacy layout
engine had them inherit lots of random properites that lead to bad
layout in the new layout engine.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* 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 change adds a version of row height distribution that follows the
distribtuion algorithm used for tables in Blink's LayoutNG. This is just
an intermediate step toward implementing a distribution algorithm for
both rows and columns more similar to Layout NG.
The CSS Table 3 specification is often wrong with regard to web
compatability, which is why we have abandoned it in favor of the Layout
NG algorithm for row height distribution. this work.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Synthetic small caps is supported by the font subsystem, but this is
disabled in Layout 2020. We can turn this on to bring support to parity
with the old layout system.
In addition to turning on synthetic small-caps this change also improves
the way that they work. Before, synthetic small caps meant that every
character was a small version of capitalized character. After this
change, capital letters are larger than small caps versions of small
letters -- matching other browsers and the common expectation of how
small caps works.
Absolutes need to be placed at their hypothetical position as if the
position value was static. This position differs based on the value they
had before blockification. The code for placing absolutes was taking
into account the original display for the inline value, but not for the
block value. A static `display: block` box would placed at a new block
position past the end of the linebox.
This adds basic support for `text-transform` in a way that is more
complete than legacy layout. There are still many missing elements of
proper `text-transform` support such as:
1. Support for `full-width` and `full-size-kana`
2. Support for grapheme based uppercasing, lowercasing, and
capitalization. These are all done per-code point right now.
3. Support for the language-specific `SpecialCasing.txt` cases for case
mapping such as the ones for Irish and Turkish.
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
This deviates from css2, but it's mandated by css-align, and matches
what other browsers do when no margin is 'auto'.
When some margin is 'auto', this should keep the proper round-tripping
behavior that Gecko and WebKit lack, and Blink recently adopted.
This adds support for table rows, columns, rowgroups and colgroups.
There are few additions here:
1. The createion of fragments, which allows script queries and hit
testing to work properly. These fragments are empty as all cells are
still direct descendants of the table fragment.
2. Properly handling size information from tracks and track groups as
well as frustrating rules about reordering rowgroups.
3. Painting a background seemlessly across track groups and groups. This
is a thing that isn't done in legacy layout (nor WebKit)!
Co-authored-by: Oriol Brufau <obrufau@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.
This implements a very naive row height allocation approach. It has just
enough to implement `vertical-align` in table cells. Rowspanned cells
get enough space for their content, with the extra space necessary being
allocated to the last row. There's still a lot missing here, including
proper distribution of row height to rowspanned cells.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Instead of using the border widths from the style, use the ones recorded
by the `BoxFragment`. This is necessary because inline layout can
override these border widths during fragmentation. For instance, when a
box is split across two lines only one fragment should have an inline
start border.
This change starts collecting the starting baseline set for fragments,
which is necessary for some layout modes (flex and tables, namely) as
well as being important for the implementation of `align-items`. In
addition, it converts baseline measurement to use `Au` everywhere.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This adds support for table `border-spacing` property. Note that we do
not yet support the collapsed border model.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* layout: Implement computation of table column widths
This change implements the various steps of table column width
computation, ignoring features that don't exist yet (such as separated
borders, column elements, and colgroups).
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* Fix an issue with the assignment of column percent width
* Respond to review comments
---------
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Replaced elements should never be able to have a layout internal
display, according to the specification. This change makes it so that
the used value of replaced element's display is always inline, as the
specification says.
* layout: Add *very* basic support for table layout
This is the first step to proper table layout. It implements a naive
layout algorithm, notably only taking into account the preferred widths
of the first table row. Still, it causes some float tests to start
passing, so turn on the `layout.tables.enabled` preference for those
directories.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* Address review comments
* Fix a crash with rowspan=0
* Turn on pref and update results for `/css/css-tables` and `/css/CSS2/tables`
---------
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* layout: Implement support for `line-height` and `vertical-align`
This is an initial implementation of proper `line-height` and
`vertical-align` support. While this change includes the bulk of the
work there are still many missing pieces for full support. In particular
some big missing things are:
- Flex containers do not properly compute their baselines. The idea is
to tackle this in a followup change. This causes various flex tests
to start failing because everything used to be top aligned.
- The implementation of the line-height quirks (only active in quirks
mode) are incomplete. While the quirk works in many cases, there are
still some cases where it is handled incorrectly. This requires more
redesign and refinement, better suited for a followup.
- Most of the features are CSS 3 such as precision control of the
baseline and first and last baselines are not implemented. This
change gets us close to CSS 2.x support.
While there are many new test passes with this change some tests are
starting to fail. An accounting of new failures:
Tests failing also in Layout 2013:
- /css/css2/positioning/toogle-abspos-on-relpos-inline-child.html (only passes in Chrome)
- /css/CSS2/fonts/font-applies-to-001.xht (potentially an issue with font size)
Invalid tests:
- /css/CSS2/visudet/inline-block-baseline-003.xht
- /css/CSS2/visudet/inline-block-baseline-004.xht
- These are are failing in all browsers. See https://bugs.chromium.org/p/chromium/issues/detail?id=1222151.
Missing table support:
- /_mozilla/mozilla/table_valign_middle.html
Missing `font-size-adjust` support :
- /css/css-fonts/font-size-adjust-zero-2.html (also failing in 2013)
Incomplete form field support :
- /html/rendering/widgets/the-select-element/option-add-label-quirks.html (label isn't rendered so button isn't the right size in quirks mode due to line height quirk)
Need support for calculating flexbox baseline:
- /css/css-flexbox/fieldset-baseline-alignment.html
- /css/css-flexbox/flex-inline.html
- /css/css-flexbox/flexbox-baseline-multi-line-horiz-001.html
- /css/css-flexbox/flexbox-baseline-single-item-001a.html
- /css/css-flexbox/flexbox-baseline-single-item-001b.html
Failing because we don't create anonymous inline boxes for text children of blocks:
- /css/CSS2/linebox/anonymous-inline-inherit-001.html
Passes locally (potentially related to fonts):
- /css/CSS2/css1/c414-flt-fit-004.xht
- /css/css-transforms/transform-input-017.html
- /html/obsolete/requirements-for-implementations/the-marquee-element-0/marquee-min-intrinsic-size.html
- /css/css-fonts/first-available-font-005.html
- /css/css-fonts/first-available-font-006.html
* Some cleanups after live review with @mukilan
Also update results.
This change adds support for `text-align-last` as well as ensuring that
it also applies to lines before forced line breaks. Two tests start to
fail because they rely on right-to-left text to pass:
- /css/css-text/text-align/text-align-last-010.html.ini
- /css/css-text/text-align/text-align-last-011.html.ini
* Update web-platform-tests to revision b'dd47ca67f55ac9df45235b2335200fb885dd1357'
* Update test expectations
---------
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Earlier versions of inline layout in the new layout system did not
properly support line breaking when unbreakable segments spanned
multiple inline boxes. This change updates inline layout to add support
for that. Now items are added to an unbreakable segment before being
committed to a line.
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Flattening the LineItem tree into a token stream will allow for handling
the case where an unbreakable line segment spans multiple inline boxes
which might have different hierarchies. This change also fixes the
handling of the second anonymous fragment of a block-in-inline-split.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
They are not transitionable:
https://drafts.csswg.org/css-transitions-1/#transitionable
There are some new failures in background-image-interpolation.html,
but I think the test is wrong, because it expects background-image
to be transitionable, even though the spec defines it with a discrete
animation type.
After placing a float, FloatBox's layout_into_line_items() was calling
place_line_among_floats() with ifc.current_line.inline_position as the
width of needed by the contents of the line.
The problem is that this amount includes the trailing whitespace advance
and thus it could seem that the in-flow contents wouldn't fit next to
the float.
That's not the case, since collapsible whitespace at the end of the line
is removed, and preserved whitespace hangs.
So this patch subtracts ifc.current_line.trailing_whitespace_advance
when calling place_line_among_floats(), like it was already happening
when computing the available_inline_size.
Fixes#30561
Improve the calculation of the block size of line boxes and all their
component elements. Even empty spans can increase the size of the line
based on their font-size. Elements that have a line-height should
increase the block size of the line, but that setting should not effect
their own size.
In addition to the new passes there are some new failures
Failing because a progression exposes the real issue these tests are
testing:
- css/css-color/t32-opacity-offscreen-multiple-boxes-1-c.xht
- css/css-color/t32-opacity-offscreen-multiple-boxes-2-c.xht
Likely failing because of vertical-align and another sizing issue:
- css/css-transforms/perspective-untransformable-no-stacking-context.html
Failing because a progression reveals another failure:
- html/rendering/non-replaced-elements/hidden-elements.html
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
When a box has overflow, any floats placed in that box will lower the
float ceiling into the overflow. If no float is placed in the box
though, the ceiling should be the block position where the overflow
starts. We already know where this is, because we might be passing a
negative value for the new block position after processing a box
(content_size - actual_size would be negative). This negative value
never raises the ceiling though since a maximum is used.
In the case that there is overflow, this change allows raising the
ceiling, but never passed the lowest float. This necessitates keeping
two values for the ceiling: one for floats and one for non-floats.
Fixes#30304.
* Sort stacking contexts and stacking containers by painting order
* fix stealing of stacking containers; fix interleaving with fragments
* actually positioned stacking containers should be stolen too
* update expectations and clean up panic changes
* rework naming and docs
* rename s_c_a_p_s_c to real_s_c_a_p_s_c; fix docs
* rename InlineStackingContainer to AtomicInlineStackingContainer
* rework debug logging to use PrintTree
* clean up docs and PrintTree output
* don't panic unless cfg!(debug_assertions) is true
* update expectations
* Take forced line breaks into account for intrinsic size
Fixes#30350.
* Don't linebreak on collapsible whitespace
This whitespace can hang off the end of the line, because it will be
trimmed LineItem layout.
* Update float placement after line breakage
Also don't ever line break for collapsible whitespace.
* Fix a few more test cases and clean up
* Renaming according to review comments
PlacementAmongFloats would stop iterating when current_bands would be
empty, even if next_band wasn't at infinity.
Then the BFC root or replaced block was placed after all the floats,
even if it could fit next to some of them.
This patch moves the next_band into current_bands so that the loop
keeps considering bands.
This implements the rest of the bulk of float support. Now inline
element flow around floats and floats can be pushed down by inline
elements before them.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
In the first phase, we gather LineItems and then when we have enough to
form a line we turn them into Fragments. This will make it possible to
more simply implement `vertical-align` and `text-align: justify` because
we need to measure the different aspects of the candidate line and then
produce a Fragments.
This is a general refactor of the way that inline layout works, so comes
with some progressions. In addition there are some new failures.
New failures:
Some tests are now failing because only the test or reference is getting
proper line height when it wasn't before. These should be fixed in a
followup change that properly calculate line-height in more cases:
- /_mozilla/css/list_style_position_a.html
- /css/CSS2/floats/float-no-content-beside-001.html
- /css/css-content/pseudo-element-inline-box.html
- /css/css-flexbox/flexbox_flex-none-wrappable-content.html
Some tests are now failing because floats are now placed properly, but
are no longer in their inline box stacking contexts. These will be fixed
by a followup change which properly parents them:
- /css/filter-effects/filtered-inline-applies-to-float.html.ini
- /css/css-color/inline-opacity-float-child.html.ini
One test is failing due to floating point precision errors:
- /css/CSS2/floats-clear/floats-141.xht.ini
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>