aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flow
Commit message (Collapse)AuthorAgeFilesLines
...
* Lint layout_2020 with clippy (#31169)Oriol Brufau2024-01-256-85/+82
| | | cargo clippy --fix -p layout_2020 --allow-dirty --broken-code
* layout: Count word separators as justification opportunities when trimming ↵Martin Robinson2024-01-232-16/+22
| | | | | | | | | | | | | | | | | whitespace (#31161) Before counting whitepsace-only `GlyphStore`s where counted as a single justification opportunity when trimming whitespace from the front and back of lines. This isn't correct, instead count the actual number of word seperators of the trimmed `GlyphStore`s. These two counts can be different in the case where whitespace collapse isn't happening yet (flexbox). In addition, using word seperators means the code is making less assumptions about the contents of the line and is more robust. This fixes some crashes in flexbox tests on debug builds. Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
* Layout: use `Au` in `ContentSizes` (#31135)atbrakhi2024-01-232-15/+16
| | | | | | | | | | | | | * use app_units * resolve errors in table layout * fmt * add back current_line.min_content * update expectation * review fix
* rustdoc: Fix many rustdoc errors (#31147)Martin Robinson2024-01-224-25/+27
| | | | This fixes many rustdoc errors that occur due to raw URLs in rustdoc comments as well as unescaped Rust code that should be in backticks.
* Layout: Clean up `Au` conversion helper functions in the flexbox (#31137)atbrakhi2024-01-221-1/+2
| | | | | * cleanup helper functions in flexbox * fmt
* layout: Convert all inline iteration to a new `foreach` function (#31117)Martin Robinson2024-01-191-230/+243
| | | | | | | | | | | | | | | | Instead of a tricky stack of enum iterators expose a `foreach()` function on InlineFormattingContext, which takes a `FnMut`. This prevents callers wanting to iterate from keeping a stack of iterators and will potentially allow a future version of this function to avoid borrowing the ArcRefCell<...> of inline boxes for every iteration (presumably using something like OwnedRef). Convert `inline_content_sizes` to use this new `foreach()` function and move the `Computation` out of the function body to `ContentSizesComputation`. This reduces the stack depth of inline size computation, because `foreach()` is iterative and not recursive. This is a preliminary change to removing the second round of text shaping during layout, because shaping will use this new iterator.
* Use App units in flow layout (#30894)atbrakhi2024-01-193-161/+185
| | | | | | | | | | | | | | | * use app_unit in flow layout * fmt * Avoid crash * Drop assert that doesn't hold anymore * update expectation --------- Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* layout: Switch `IndependentLayout` to use `Au` instead of `Length` (#31083)atbrakhi2024-01-153-13/+28
| | | | | | | * use au in layout * fmt * review fix
* layout: Split `LineItem` layout into a new file (#31039)Martin Robinson2024-01-103-602/+643
| | | | | This is just a bit of code movement that trims down the size of the `inline.rs` file in order to make it a bit more manageable. It leads the way to more refactoring and cleanup in the future.
* layout: Implement support for `line-height` and `vertical-align` (#30902)Martin Robinson2024-01-083-234/+834
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Add support for table fixups (#30868)Martin Robinson2023-12-222-46/+161
| | | | | | | | | | | | | | | | This adds support for fixing up tables so that internal table elements that are not properly parented in the DOM have the correct box tree structure according to the CSS Table specification [1]. Note that this only comes into play when building the DOM via script, as HTML 5 has its own table fixups that mean that the box tree construction fixups here are not necessary. There are no tests for this change. In general, it's hard to write tests against the shape of the box tree, because it depends on the DOM. We plan to test this via WPT tests once layout is complete. 1. https://drafts.csswg.org/css-tables/#table-internal-element Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* layout: Make all word separators justification opportunities (#30866)Martin Robinson2023-12-211-7/+3
| | | | | This change adapts both layout and legacy layout to the specification which gives a list of word separators to use as justification opportunities.
* layout: Add support for `text-align-last` (#30905)Martin Robinson2023-12-211-19/+32
| | | | | | | | 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
* Fix crash caused by arithmetic underflow in layout2020 (#30897)atbrakhi2023-12-211-8/+8
| | | | | | | | | | | * fix crash caused by arithmetic underflow * add WPT crash test to avoid regressions * update manifest * apply martin's patch * remove wpt test
* Add basic support for `text-align: justify` (#30807)Martin Robinson2023-12-151-50/+140
| | | | This also enables parsing of `text-justify` for non-legacy layout, though only None is supported (disabling justification).
* Re-use the TextMetrics data structure in the Layout 2020 fragment tree (#30823)Martin Robinson2023-12-061-10/+11
| | | | | | | This data structure has all of the metrics needed to render a font and is in `Au`. We'll need more of these metrics for implementing `vertical-align` and its use doesn't increase the size of the Fragment tree (as the BoxFragment is still larger). In addition, this will be helpful when switching layout to `Au`.
* Add initial support for table box tree construction (#30799)Martin Robinson2023-12-053-1/+9
| | | | | | | | | | | | This is the first part of constructing the box tree for table layout. No layout is actually done and the construction of tables is now hidden behind a flag (in order to not regress WPT). Notably, this does not handle anonymous table part construction, when the DOM does not reflect a fully-formed table. That's part two. Progress toward #27459. Co-authored-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Manish Goregaokar <manishsmail@gmail.com>
* Remove a comment that is no longer valid (#30806)Martin Robinson2023-12-011-2/+0
| | | The update of `max_block_size` here no longer happens.
* Extend character-based soft wrap prevention to before atomics (#30800)Martin Robinson2023-12-011-14/+41
| | | | | | The changes in #30740, fixed an issue where certain characters should prevent line break opportunity after atomics. This change extends that to also apply to before atomics, which is what the specification says should happen.
* Stop sending " " to linebreaker for replaced content (#30740)Martin Robinson2023-11-301-4/+40
| | | | | | | | | | | We previously sent a " " to the linebreaker in order to ensure that the next text had a soft wrap opportunity at the start. Calling `next(" ")` without waiting until the returned index was 1, violated some invariants of linebreaker ultimately causing a panic. Instead of using the linebreaker for this, simply keep a flag in the IFC layout state, which avoids the problem entirely. Fixes #30703.
* Further changes required by ServoOriol Brufau2023-11-041-1/+1
|
* Add better support for line breaking across inline box boundaries (#30628)Martin Robinson2023-11-011-279/+554
| | | | | | | | | | 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>
* Make LineItems a token stream on the root (#30608)Martin Robinson2023-10-252-142/+128
| | | | | | | | | 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>
* Consider trailing_whitespace_advance when calling place_line_among_floats() ↵Oriol Brufau2023-10-201-3/+4
| | | | | | | | | | | | | | | | | | | | (#30586) 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
* Don't panic when no font is found for a TextRun (#30581)Martin Robinson2023-10-191-18/+37
| | | | Instead of panicking when no found is found for a TextRun, instead print a warning. This prevents panics on pages with very large font sizes.
* Anonymous boxes that wrap inlines should not inherit overflow (#30579)Martin Robinson2023-10-191-2/+2
| | | | | | | | | | | | | | In legacy layout, anonymous text wrappers were inheriting the `overflow` and `text-overflow` properties. This results in the creation of extra clipping for these anonymous wrappers which could clip away floats. We will likely implement `text-overflow` differently in non-legacy layout. This change marks all legacy layout pseudo elements as "legacy" and also adds a new pseudo element for non-legacy layout that does not inherit `overflow`. Fixes #30562. Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* Improve line box block size calculation (#30519)Martin Robinson2023-10-181-76/+162
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Allow raising FloatContext ceiling after processing box with overflow (#30539)Martin Robinson2023-10-172-11/+34
| | | | | | | | | | | | | | | 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.
* Improve intrinsic sizing and white-space handling around forced line breaks ↵Martin Robinson2023-09-151-50/+93
| | | | | | | | | | | | | | | | | | | | (#30351) * 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
* Layout 2020: Rename `flow_relative` types to `Logical...` (#30324)Martin Robinson2023-09-124-83/+88
| | | | | | This makes the names of flow relative geometry consistent with what is used in the style crate and removes them from a module. With this change it's more obvious what makes these types different from the ones in `euclid`.
* Strict import formatting (grouping and granularity) (#30325)Samson2023-09-115-59/+64
| | | | | * strict imports formatting * Reformat all imports
* remove `extern crate` (#30311)Samson2023-09-084-0/+4
| | | | | | | | | | | * remove extern crate * Update components/script_plugins/lib.rs Co-authored-by: Martin Robinson <mrobinson@igalia.com> --------- Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Refactor inline layout nesting (#30289)Martin Robinson2023-09-051-138/+204
| | | | | | | | | | | | | | | | | | | | This makes the nesting architecture of inline layout a lot simpler. Now PartialInlineBoxFragment and InlineNestingLevelState are replaced by two structs: - InlineContainerState - InlineBoxContainerState InlineContainerState holds state for the root of the inline formatting context, while InlineBoxContainerState holds state for inline boxes. InlineBoxContainerState has an InlineContainerState as the first element, thus "extends" it. Now the inline iterators are stack variables directly in the `layout()` method. They are no longer stored in the state. This avoids the weird nesting of state and instead relies on a normal vector to hold the stack of state. Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
* Fix handling of `white-space` property for wrapping (#30259)Martin Robinson2023-09-041-45/+95
| | | | This still fails some tests because on element boundaries we want the `white-space` property of the first shared ancestor.
* Fix PlacementAmongFloats to avoid missing some bands (#30280)Oriol Brufau2023-09-011-2/+18
| | | | | | | | | | 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.
* Flow inlines around floats (#30243)Martin Robinson2023-08-311-95/+384
| | | | | | | 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>
* Avoid crash in PlacementAmongFloats (#30235)Oriol Brufau2023-08-291-1/+1
| | | | | | | | | | | PlacementAmongFloats was assuming that there would always be a FloatBand at a position smaller than or equal to the given ceiling, but this was not the case for negative ceilings. The reason is that the FloatContext initialized the FloatBandTree with a band at 0, and another at +∞. This patch changes the initial bands to −∞ and +∞. This seems more consistent and matches the expectation of PlacementAmongFloats.
* Layout floats as children of their inline ancestors (#30130)Martin Robinson2023-08-221-91/+163
| | | | | | | | | | | | | | | When layout was split into two phases, floats were laid out as direct children of the inline formatting context. This meant that they were positioned properly, but not properly made children of their inline ancestors' stacking contexts. This change maintains the proper positioning of floats, but positions them relatively to their inline ancestors. The big change here is that `text-align` needs to be taken into account before actually laying out LineItems. This has the added benefit of setting inline layout for the implementation of `text-align: full`. Now all line items are laid out at the real final position and we can adjust the `start_corner` property of float `BoxFragments` when their ancestors are laid out.
* Split line layout into two phases (#30089)Martin Robinson2023-08-112-620/+740
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Resolve cyclic margin and padding percentages against zero (#30085)Oriol Brufau2023-08-101-19/+9
| | | | | | | From https://drafts.csswg.org/css-sizing-3/#min-percentage-contribution > For the min size properties, as well as for margins and paddings > (and gutters), a cyclic percentage is resolved against zero > for determining intrinsic size contributions.
* Handle inline margins when avoiding floats (#30072)Oriol Brufau2023-08-092-62/+135
|
* Handle BFC roots with auto width next to floats (#30057)Oriol Brufau2023-08-082-30/+154
| | | Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Avoid bad calls to ↵Oriol Brufau2023-08-071-60/+116
| | | | | | | | | | | | | | | solve_containing_block_padding_border_and_margin_for_in_flow_box (#30073) Avoid solve_containing_block_padding_border_and_margin_for_in_flow_box() for a block-level box that establishes an independent formatting context (or is replaced) in the presence of floats, since the margins and inline size could then be incorrect. No actual change in behavior: this patch still resolves the margins incorrectly with solve_block_margins_for_in_flow_block_level(), and also keeps the old logic for width:auto. However, this refactoring prepares the terrain to address these issues in #30072 and #30057.
* Refactor PlacementAmongFloats (#30068)Oriol Brufau2023-08-041-30/+65
| | | | | | | | | | | | | | - Add explanatory comments. - Rename some methods. - Store the ceiling instead of relying on the first band, this allows calling place() when current_bands is empty. - Make current_bands_height() work when current_bands is empty. - Add add_one_band() helper method. - Make place() return a Rect. Follow-up patches will need to know the size of the area shrunk by floats. This will be useful for #30057 and #30050. Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Never resolve margin-left:auto to a negative amount (#30065)Oriol Brufau2023-08-031-6/+9
| | | | | | | | With direction:ltr (and we don't support direction:rtl yet), the rules from https://drafts.csswg.org/css2/#blockwidth imply that margin-left shouldn't resolve auto to a negative amount. This aligns Servo with Gecko and Blink. WebKit may resolve to a negative amount in some cases.
* Make fewer PositioningContexts when descending (#30061)Martin Robinson2023-08-032-24/+18
| | | | | | When descending and we have the option, don't create new PositioningContexts just to update the static position of laid out abspos descendants. Instead, use the new PositioningContextLength to only update the newly added hoisted abspos boxes.
* Simplify solve_containing_block_padding_border_and_margin_for_in_flow_box() ↵Oriol Brufau2023-08-021-26/+12
| | | | | | | | (#30060) Just use clamp_between_extremums() to resolve the inline size, and then only call solve_inline_margins_for_in_flow_block_level() once. There should be no change in behavior.
* Minor refactoring for PlacementAmongFloats (#30055)Oriol Brufau2023-08-011-20/+17
| | | | | | | | | | | | No difference in behavior, just these changes: - PlacementAmongFloats::new() initializes the top of the 1st band to the ceiling, so that other methods can just refer to the former without having to floor by the later. - In fact, the 'ceiling' field becomes unnecessary, and is removed. - top_of_placement_for_current_bands() is renamed to current_ceiling(). - try_place_once() is reorganized to reduce indentation. - The condition 'len() > 0' becomes '!is_empty()'. - The 1st band is now popped in place() instead of try_place_once(), then it's easier to see why the loop will end.
* Fix interaction of margins and clearance for PlacementAmongFloats (#30038)Oriol Brufau2023-07-312-145/+118
| | | | | | | | | Consumers of PlacementAmongFloats weren't handling margins properly. They were assuming that they would either get a positive adjustment, or zero for no-op. However, just like the regular clearance triggered by 'clear', the clearance added onto blocks that establish an independent FC can be zero or negative, and the effect is different than having no clearance.
* Floor child sizes in calculate_inline_content_size_for_block_level_boxes ↵Oriol Brufau2023-07-271-3/+7
| | | | | | | | | | | | | | | | (#30034) Calculating the max-content size of a block container may add the outer max-content sizes of multiple children. The problem is that the outer size may be negative (due to margins), producing an incorrect result. In particular, it could happen that the max-content size was 50-25=25, but the min-content size would just take the maximum and be 50, which doesn't make sense. Therefore, this patch floors the size of all children by 0. This seems to match Blink. Firefox and WebKit don't floor in some cases, but then the result seems suboptimal to me. Note that there is no spec for this, see https://github.com/w3c/csswg-drafts/issues/9120 for details.