aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/formatting_contexts.rs
Commit message (Collapse)AuthorAgeFilesLines
* Refactor computation of preferred aspect ratios (#34416)Oriol Brufau2024-11-291-16/+23
| | | | | | | | | | | | | | | | | | | * 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>
* Use an AtomicRefCell instead of a RwLock for caching intrinsic sizes (#34384)Oriol Brufau2024-11-261-13/+9
| | | | | | It panics if the value is mutably borrowed concurrently, but this allows it to perform better. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Remove unnecessary clone in layout (#34350)Nico Burns2024-11-231-1/+1
| | | Signed-off-by: Nico Burns <nico@nicoburns.com>
* Layout: Implement CSS Grid using `taffy` (#32619)Nico Burns2024-11-211-0/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Add layout.grid.enabled pref Signed-off-by: Nico Burns <nico@nicoburns.com> * Add taffy dependency Signed-off-by: Nico Burns <nico@nicoburns.com> * Import taffy <-> stylo conversion code from taffy_stylo crate Signed-off-by: Nico Burns <nico@nicoburns.com> * Add `Grid` variant to DisplayInside Signed-off-by: Nico Burns <nico@nicoburns.com> * Implement CSS Grid using Taffy Signed-off-by: Nico Burns <nico@nicoburns.com> Import full stylo_taffy crate Signed-off-by: Nico Burns <nico@nicoburns.com> Squashed PR feedback changes Deduplicate is_document_only_whitespace Signed-off-by: Nico Burns <nico@nicoburns.com> Import taffy::AvailableSpace Signed-off-by: Nico Burns <nico@nicoburns.com> Rename FlexContext to TaffyContainerContext Signed-off-by: Nico Burns <nico@nicoburns.com> Eliminate references to flexbox in taffy/layout module Signed-off-by: Nico Burns <nico@nicoburns.com> Use constructors for geom types Signed-off-by: Nico Burns <nico@nicoburns.com> Remove comment about abspos elements splitting contiguous text runs Signed-off-by: Nico Burns <nico@nicoburns.com> Remove reference to flexbox in taffy/construct Signed-off-by: Nico Burns <nico@nicoburns.com> Deduplicate construction of flexbox/grid containers Signed-off-by: Nico Burns <nico@nicoburns.com> Make anonymous text runs InFlow Signed-off-by: Nico Burns <nico@nicoburns.com> Remove commented code Signed-off-by: Nico Burns <nico@nicoburns.com> Update comments Signed-off-by: Nico Burns <nico@nicoburns.com> Inline/vendor the stylo/taffy interop code Signed-off-by: Nico Burns <nico@nicoburns.com> * Update test expectations Signed-off-by: Nico Burns <nico@nicoburns.com> * Fix nits from PR review Signed-off-by: Nico Burns <nico@nicoburns.com> --------- Signed-off-by: Nico Burns <nico@nicoburns.com>
* Use a RwLock to cache inline_content_sizes() (#34232)Oriol Brufau2024-11-131-17/+22
| | | | | | | | | | | 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>
* Fix inline content sizes of intrinsic element with indefinite block size ↵Oriol Brufau2024-11-111-27/+18
| | | | | | | | | | | | | | | | | (#34152) To compute the min-content and max-content inline sizes of a replaced element, we were only using the aspect ratio to transfer definite block sizes resulting from clamping the preferred block size between the min and max block sizes. However, if the preferred block size is indefinite, then we weren't transfering the min and max through the aspect ratio. This patch adds a `SizeConstraint` enum that can represent these cases, and a `ConstraintSpace` struct analogous to `IndefiniteContainingBlock` but with no inline size, and a `SizeConstraint` block size. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* layout: Avoid layout sometimes when stretching (#33967)Martin Robinson2024-10-241-0/+3
| | | | | | | | | | | | | | | | | | | | This is the second flexbox caching change. It seeks to detect when a relayout can be avoided in the case of a stretching flex item. This heuristic can be combined, because currently we still do relayout sometimes when we do not need to. For instance currently we always relayout when a flex child is itself a column flex. This only needs to happen when the grandchildren themselves grow or shrink. That optimization is perhaps a lower priority as `flex-grow: 0 / flex-shrink: 1` is the default behavior for flex. Since this change means we more consistenly zero out the percentage part of `calc` expressions when they have circular dependencies, this causes one test to start failing (`/css/css-values/calc-min-height-block-1.html`). This is related to w3c/csswg-drafts#10969, which is pending on further discussion in the working group. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* Avoid recomputing inline_content_sizes() when not needed (#33806)Oriol Brufau2024-10-141-11/+13
| | | | | | | | | | | The result of `inline_content_sizes()` may depend on the block size of the containing block, so we were always recomputing in case we got a different block size. However, if no content has a vertical percentage or stretches vertically, then we don't need to recompute: the result will be the same anyways. Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Unify logic for laying out floats and atomic inlines (#33802)Oriol Brufau2024-10-111-1/+8
| | | Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* Simplify the computation of CAPMIN (#33577)Oriol Brufau2024-09-281-5/+20
| | | | | | | | | | | | CAPMIN is the largest min-content contribution of the table captions. In Servo, the standard way to compute min/max-content contributions is `outer_inline_content_sizes()`, so just use that instead of reinventing the wheel. This also fixes cyclic percentages to resolve consistently with normal block boxes. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* layout: Use `Au` in `ComputedValuesExt` (#33396)atbrakhi2024-09-101-1/+1
| | | | | | | | | | | | | | | | | | | | * Use app unit in `ComputedValuesExt` Co-authored-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: atbrakhi <atbrakhi@igalia.com> * Some miscellaneous fixes Signed-off-by: Martin Robinson <mrobinson@igalia.com> * remove redundant defination of `containing_block_inline_size` Signed-off-by: atbrakhi <atbrakhi@igalia.com> --------- Signed-off-by: atbrakhi <atbrakhi@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Fix various issues with replaced elements in flex layout (#33263)Oriol Brufau2024-08-301-0/+13
| | | | | | | | 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>
* Handle aspect ratios in `ReplacedContent::inline_content_sizes` (#33240)Oriol Brufau2024-08-291-17/+10
| | | | | | | 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>
* layout: Add an indefinite containing block for intrinsic sizing (#33204)Oriol Brufau2024-08-291-44/+83
| | | | | | | | | | | | | | | | | | 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>
* Allow caching `IndependentFormattingContext::inline_content_sizes()` (#33207)Oriol Brufau2024-08-271-3/+1
| | | | | | | | | | | | For non-replaced formatting contexts, this method redirected directly to `NonReplacedFormattingContextContents::inline_content_sizes()`, which has the actual logic for the computation. Thus it was bypassing the cache, which is handled in `NonReplacedFormattingContext::inline_content_sizes()`. Therefore, this patch redirects to the latter. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
* layout: Prepare for bidi by guarding all access to `writing-mode` (#33082)Martin Robinson2024-08-161-4/+4
| | | | | | | | | 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>
* layout: Initial implementation of `flex-direction: column` and ↵Martin Robinson2024-08-141-15/+31
| | | | | | | | | | | | | | | | | | | | | | `column-reverse` (#33031) 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>
* layout: Compute intrinsic sizes for flex items and flex containers (#32854)Delan Azabani2024-08-021-1/+1
| | | | | Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* layout: Properly handle min/max cross container size (#32785)Delan Azabani2024-07-161-0/+1
| | | | | Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
* layout: Add support for table captions (#32657)Martin Robinson2024-07-031-4/+25
| | | | | | | | | | | | | This adds initial support for table captions. To do this, the idea of the table wrapper becomes a bit more concrete. Even so, the wrapper is still reponsible for allocating space for the grid's border and padding, as those properties are specified on the wrapper and not grid in CSS. In order to account for this weirdness of HTML/CSS captions and grid are now laid out and placed with a negative offset in the table wrapper content rect. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
* layout: Simplify `Contents` a little (#32487)Martin Robinson2024-06-211-5/+3
| | | | | | | Instead of duplicating some of `NonReplacedContents` in `Contents`, divide it into either replaced and non-replaced content, since this is how the layout system processes `Contents` always. In addition, stop using `TryInto` to match replaced or non-replaced contents, as it is quite confusing to handle an `Err` as a success case.
* layout: Allow transforming inline replaced elements (#31833)Martin Robinson2024-03-271-6/+10
| | | | | | | | | | This requires passing through information about whether or not the element in question is replaced when checking to see if it's transformable and transitively all functions that make decisions about containing blocks. A new FragmentFlag is added to help track this -- it will be set on both the replaced items BoxFragment container as well as the Fragment for the replaced item itself. Fixes #31806.
* rustdoc: Fix two warnings in `components/layout_2020` (#31712)Rhea-Eve2024-03-181-2/+2
| | | | | | | | | | | | | | | | | | * Fix BoxFragment reference. Signed-off-by: Rhea Karty <rheakarty@gmail.com> * Fix reference to InlineFormattingContext. Signed-off-by: Rhea Karty <rheakarty@gmail.com> * Rewrap lines to avoid long length * Remove trailing whitesapce --------- Signed-off-by: Rhea Karty <rheakarty@gmail.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
* Fix size of tables in flow layout (#31455)Oriol Brufau2024-03-021-9/+22
| | | | | | | | | | | | | | | | | | | | | | * 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>
* layout: Start work on table row height and vertical-align (#31246)Martin Robinson2024-02-101-1/+1
| | | | | | | | | 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>
* layout: Collect both start and end baselines for fragments (#31230)Martin Robinson2024-02-051-1/+9
| | | | | | | | 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>
* Lint layout_2020 with clippy (#31196)Oriol Brufau2024-01-261-7/+5
| | | cargo clippy --fix -p layout_2020 --allow-dirty --broken-code
* layout: Shape text only once (#31146)Martin Robinson2024-01-251-15/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | Shape text during InlineFormattingContext construction rather than doing it twice during fragment tree construction. This is a step on the way toward proper font fallback. This also moves all `TextRun` related code into `text_run.rs` to try to trim down the size of `inline.rs`. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes do not require tests because this should only have performance impacts. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
* Lint layout_2020 with clippy (#31169)Oriol Brufau2024-01-251-1/+1
| | | cargo clippy --fix -p layout_2020 --allow-dirty --broken-code
* rustdoc: Fix many rustdoc errors (#31147)Martin Robinson2024-01-221-2/+2
| | | | 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: Add *very* basic support for table layout (#31121)Martin Robinson2024-01-191-5/+5
| | | | | | | | | | | | | | | | | | | | | * 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: Switch `IndependentLayout` to use `Au` instead of `Length` (#31083)atbrakhi2024-01-151-3/+3
| | | | | | | * use au in layout * fmt * review fix
* layout: Implement support for `line-height` and `vertical-align` (#30902)Martin Robinson2024-01-081-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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 initial support for table box tree construction (#30799)Martin Robinson2023-12-051-3/+17
| | | | | | | | | | | | 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>
* Strict import formatting (grouping and granularity) (#30325)Samson2023-09-111-7/+9
| | | | | * strict imports formatting * Reformat all imports
* remove `extern crate` (#30311)Samson2023-09-081-0/+1
| | | | | | | | | | | * 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>
* Resolve cyclic margin and padding percentages against zero (#30085)Oriol Brufau2023-08-101-20/+7
| | | | | | | 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.
* Simplify layout of absolutes with static insetsMartin Robinson2023-06-201-13/+6
| | | | | | | | | | | | | | | | | | | Absolutes with static insets need to be laid out at their ancestor containing blocks, but their position is dependent on their parent's layout. The static layout position is passed up the tree during hoisting and ancestors each add their own offset to the position until it is relative to the containing block that contains the absolute. This is currently done with a closure and a fairly tricky "tree rank" numbering system that needs to be threaded through the entire layout. This change replaces that system. Every time a child is laid out we create a positioning context to hold any absolute children (this can be optimized away at a later time). At each of these moments, we call a method to aggregate offsets to the static insets of hoisted absolutes. This makes the logic easier to follow and will also allow implementing this behavior for inline-blocks, which was impossible with the old system.
* Layout 2020: Move all Fragment code to the `fragment_tree` directoryMartin Robinson2023-06-041-2/+1
| | | | | | | | This is a simple code organization change with no behavior change with the idea of making Layout 2020 easier to understand by new folks to the project. The idea is that we will have a cleaner separation between the different parts of layout ie one directory for the fragment tree and one (currently multiple) directory for the box tree.
* layout_2020: Implement automatic minimum size of flex itemsPu Xingyu2023-06-021-1/+1
| | | | | Implement the algorithm described in https://drafts.csswg.org/css-flexbox/#min-size-auto.
* Combine DOM-related concepts in Layout 2020 into dom.rsMartin Robinson2023-05-131-1/+2
|
* Detect body elements during layoutMartin Robinson2023-05-041-16/+17
| | | | | | | | | | | | | | | | | During layout it is often useful, for various specification reasons, to know if an element is the `<body>` element of an `<html>` element root. There are a couple places where a brittle heuristic is used to detect `<body>` elements. This information is going to be even more important to properly handle `<html>` elements that inherit their overflow property from their `<body>` children. Implementing this properly requires updating the DOM wrapper interface. This check does reach up to the parent of thread-safe nodes, but this is essentially the same kind of operation that `parent_style()` does, so is ostensibly safe. This change should not change any behavior and is just a preparation step for properly handle `<body>` overflow.
* Make a bool for `display: list-item` available to flow box constructionSimon Sapin2020-07-231-1/+3
|
* First pass at implementing the Flex Layout AlgorithmSimon Sapin2020-06-231-1/+12
| | | | https://drafts.csswg.org/css-flexbox/#layout-algorithm
* An element establishing a formatting context *is* the containing block for ↵Simon Sapin2020-06-231-5/+3
| | | | its contents
* Rename outer_inline* outside of sizing.rs to outer_inline_content_sizes*Simon Sapin2020-06-191-4/+6
|
* Compute content sizes lazily in layout 2020Anthony Ramine2020-06-181-47/+90
|
* Make IndependentFormattingContext an enumAnthony Ramine2020-06-151-61/+55
|
* Move IndependentFormattingContext::as_replaced to ↵Anthony Ramine2020-06-151-9/+22
| | | | IndependentFormattingContextContents
* layout_2020: Tag fragments with their pseudo content typeMartin Robinson2020-06-061-21/+17
| | | | | This will allow us to answer queries and properly handle animations in the future for fragments generated for pseudo content.