Commit Graph

104 Commits

Author SHA1 Message Date
Oriol Brufau
d5c82150e0 layout: Add testing API for counting restyled and rebuilt fragments (#42817)
Now `ServoTestUtils.forceLayout()` will provide the number of fragments
that have been restyled and rebuilt. This will be useful to test that
incremental layout works well.

Testing: Adds a test using this new API

---------

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2026-02-25 21:25:32 +00:00
shuppy
c07682f222 libservo: Allow the embedder to activate accessibility (#42336)
this patch adds a Servo::set_accessibility_active() method that
embedders can use to tell Servo to start building and sending
accessibility trees to the platform, as long as the pref is enabled
(#42333). doing so sets a global flag in the constellation, which is
then propagated to the layout of all existing and future pipelines.

Testing: none yet, no functional change
Fixes: part of #4344

---------

Signed-off-by: delan azabani <dazabani@igalia.com>
Signed-off-by: Alice Boxhall <alice@igalia.com>
Co-authored-by: Alice Boxhall <alice@igalia.com>
2026-02-20 05:56:15 +00:00
Martin Robinson
042d95220a layout: Replace dirty root approach with flexible box tree layout (#42700)
Replace the old dirty root box tree layout approach with one that works
based on independent formatting contexts. Instead of just allowing a
single dirty root to be the source of box tree reconstruction, allow box
tree reconstruction to happen anywhere in the tree that can isolate box
tree damage from ancestors. This essentially combines damage propagation
and box tree construction into a single step.

There is currently one downside to this approach compared to the dirty
root approach which is that we currently cannot detect and start box
tree layout when the dirty has a compatible `display` and `position`
value. This can mean the scope of box tree layout extends further up the
tree. We will address this in a followup -- but have not noticed any
major performance implications (currently fragment tree layout is much
more expensive than box tree layout).

Benefits:
 1. Damage propagation now only happens under the dirty root.
 2. Future changes can limit the scope of damage up the tree and perhaps
    preserve the inline content size cache between box tree rebuilds.

Testing: This should not change behavior in a testable way (we currently
do
not have robust performance tests), so WPT test results should not
change.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
2026-02-19 14:31:13 +00:00
Martin Robinson
150f767b19 layout: Store a fallback cache in the FontGroup (#42466)
Store a list of recently used fallbacks in the `FontGroups`, keyed by
`lang` property and the detected `UnicodeBlock` and `Script` of the
character in question. This should mean that less work is done when
switching between falling back and not falling back. In addition, this
will allow better caching of `FontRef`s that come directly from the
platform font backend -- something necessary for the next generation
font fallback code.

Testing: This should not change rendering output so is covered by
existing
tests. It might have a minor affect on performance.
Fixes: This is part of #41426.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-02-13 17:01:41 +00:00
Shubham Gupta
0c2962e2c2 layout: Introduce PaintTimingHandler (#42541)
This PR aims to open doors for common handler for all `PaintTiming`
protocols.
Will add more logic related to `PaintTiming` here targeting completeness
of it.

Changes included in this PR.
1. Ports existing `LargestContentfulPaintCandidateCollector` to
`PaintTimingHandler`.
2. Aligns more close to **W3C** specs, added few steps as well.
3. Adding helper functions.

Testing: No change in behavior expected.
- `components/servo/tests/largest_contentful_paint.rs`

Signed-off-by: Shubham Gupta <shubham13297@gmail.com>
2026-02-13 07:09:33 +00:00
Mukilan Thiyagarajan
b682f03394 layout: Move UserAgentStylesheets struct from stylo to layout. (#42499)
This struct is only ever used by Servo so there is not reason to have it
defined in stylo. A follow-up PR in stylo will remove the struct.


Testing: This change simply moves an existing struct from stylo, so
shouldn't have any behavioral changes.

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
2026-02-10 08:02:34 +00:00
Oriol Brufau
2a3f23c78d Upgrade Stylo to 2026-02-02 (#42361)
This continues #41916

Changelog:
- Upstream:
360787fff5...7cd2a178d3
- Servo fixups:
e4d50e905e...d9831d464b

Stylo tracking issue: https://github.com/servo/stylo/issues/305

In particular, this adds support for `alignment-baseline` and
`baseline-shift`, and turns `vertical-align` into a shorthand of them.
This also introduces `vertical-align: center`.

Testing: Various tests improve. Some internal tests are updated because
they were wrong. And some fail because we don't support presentation
attributes on SVG elements.

---------

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2026-02-09 11:16:42 +00:00
webbeef
86403fa4e5 layout: get rid of some collect() calls (#42327)
Profiling a speedometer run showed significant time spent in some layout
function in vector allocations. The main change is to switch the result
of `query_box_areas()` from a Vec<T> to and iterator.

Testing: refactoring with no expected test changes

Signed-off-by: webbeef <me@webbeef.org>
2026-02-06 09:38:49 +00:00
Mukilan Thiyagarajan
79ed814ec1 libservo: Expand the UserContentManager API. (#42288)
The patch adds the following functionality to the per-WebView
`UserContentManager` API.
- Removing a `UserScript` at that was previously added.
- Adding a new `UserStyleSheet` representing a user-origin style sheet.
allow removing user script
- Removing a previously added `UserStyleSheet`.

There might be scope for some improvements in the API:
- `UserScript` and `UserStyleSheet` have different ways of representing
the source location - a `PathBuf` and `Url` respectively. This is due to
how those values are used by the underlying evaluation APIs in script
and stylo. More investigation is needed here and could be addressed in
future patches.

Testing: New unit tests are added for the user stylesheet APIs. Existing
tests have been updated to test the removal of user scripts.
2026-02-05 13:26:54 +00:00
Martin Robinson
2a7d2780b3 fonts: Store shaping output per-character rather than per-code point (#42105)
This change is a reworking of the shaping code and simplification of the
`GlyphRun` data structure.

The shaper was written between 2012 and 2014 against an early version of
Rust. It was originally written to have a single glyph entry per UTF-8
code point. This is useful when you always need to iterate through
glyphs based on UTF-8 code points. Unfortunately, this required a
tri-level data structure to hold detailed glyphs and meant that CJK
characters took over 3x the memory usage of ASCII characters. In
addition, iterating through glyphs (the most common and basic operation
on shaped text) required doing a lookup involving a binary search for
detailed glyphs (ones that had large advances or mapped to more or less
than a single UTF-8 code point).

The new design of the `GlyphStore` is instead based on `chars` in the
input string. These are tracked during layout so that the resulting
glyph output can be interpreted relatively to its original character
offset in the containing IFC. We are already dealing with IFC text on a
per-character basis for a variety of reasons (such as text
transformation and whitespace collapse). In addition, we will now able
to
implement mapping between the character offsets before and after layout
transformations of the original DOM string.

Now the penalty of more complex glyph iteration is only paid when
transforming glyph offsets to character offsets. Currently this is only
done for selections and clicking in text boxes, both of which are much
less common than layout.

This change does not properly handle selections in RTL text, though
rendering and basic selection and visual movement works (though buggy).

It does not seem like this affects the performance of shaping based on
measurement using the text shaping performance counters. This likely
means that the performance of shaping is dominated on our machines by
HarfBuzz. We noticed no performance degradation in Speedometer when run
on a M3 Mac.

Followup work:
 - Properly handle selection in RTL text.
 - Support mapping from original DOM character offsets to offsets in
   layout after text transformation and whitespace collapse. This is now
   possible.

Testing: This causes some tests to pass and a few to fail. This is
likely
due to the fact that we are handling glyphs more consistently while
shaping. Of the new failures:
- `letter-spacing-bengali-yaphala-001.html`,
`letter-spacing-cursive-001.html`, `font-feature-settings-tibetan.html`
where passing before probably because we were not applying letter
spacing to detailed glyphs. These scripts should not have letter spacing
applied to them, because they are cursive -- which we never implemented
properly. It will be handled in a a followup.
- `shaping-arabic-diacritics-001.html`: This was a false pass. The tests
verifies that Arabic diacritics are applied to NBSP. This wasn't
happening before nor after this change, but the results matched anyway.
Now they don't, but before and after are equally broken.
 - 
Fixes: #216
Part of #35540.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-26 12:38:04 +00:00
Thomas Cummings
ffb91ac4b1 script: Evict stale SVGs from image cache (#41675)
Parsed and vectorized representations of SVGs in the image cache are
never evicted when SVGs are updated, leading to stale SVGs staying in
the image cache alongside updated ones. This PR:
- adds a stringified uuid field to SVGSVGElement
- adds a map of `SVGSVGElement` uuid to `PendingImageId` in
`ImageCacheImpl`
- adds an optional argument for the uuid to
`ImageCacheImpl::rasterize_vector_image`, which, if provided, removes
any existing parsed svgs associated with the uuid and stores a new entry
of uuid -> `PendingImageId`
- implements `unbind_from_tree` on SVGSVGElement, which clears the
associated images/representations from the image_cache (from
`vector_images`, `rasterized_vector_images`, and `completed_loads`) as
well as from the layout image resolver image cache.

Testing: Each of the following documents should display their (very
flashy) content correctly and memory usage should stay constant
<details>
<summary>Changing SVGSVGElement</summary>

```

<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg">
  <circle id="c" r="1" cx="50" cy="50" fill="red" />
</svg>
<script>
let c = document.querySelector("#c");
let r = 1;
setInterval(() => {
  r += 1;
  c.setAttribute("r", r.toString());
  let tmp = document.createTextNode("ignored");
  c.parentNode.appendChild(tmp);
  tmp.remove();
}, 100);
</script>

```

</details>
<details>
<summary>Unbinding SVGSVGElements</summary>

```

<div id="parent_div">
  <svg id="test" height="100" width="100" xmlns="http://www.w3.org/2000/svg">
    <circle id="c" r="10" cx="50" cy="50" fill="red" />
  </svg>
</div>
<script>
  let div = document.querySelector("#parent_div");
  let svg_html_string = div.innerHTML;
  let svg = document.querySelector("#test");
  let r = 10;
  setInterval(() => {
    svg.remove();
    div.innerHTML = svg_html_string;
    svg = document.querySelector("#test");
    let circle = document.querySelector("#c");
    r += 1;
    circle.setAttribute("r", r.toString());
  }, 100);
</script>

```

</details>
<details>
<summary>Unbinding SVGSVGElements (and rebinding the same SVG)</summary>

This didn't work until I also evicted the associated image from the
layout image resolver image cache and the image cache's
`completed_loads` on SVGSVGElement unbind, so it seems like a useful, if
a bit redundant, test.

```

<div id="parent_div">
  <svg id="test" height="100" width="100" xmlns="http://www.w3.org/2000/svg">
    <circle id="c" r="10" cx="50" cy="50" fill="red" />
  </svg>
</div>
<script>
  let div = document.querySelector("#parent_div");
  let svg_html_string = div.innerHTML;
  let svg = document.querySelector("#test");
  let r = 10;
  setInterval(() => {
    svg.remove();
    div.innerHTML = svg_html_string;
    svg = document.querySelector("#test");
  }, 100);
</script>

```

</details>

Fixes: #41070

---------

Signed-off-by: Tom Cummings <cummings.t287@gmail.com>
2026-01-26 06:02:50 +00:00
Martin Robinson
9c9d9c863f Rename compositing and compositing_traits to paint and paint_api (#42066)
This change finishes the big rename associated with the old
`compositing` crates. Long ago, these crates managed a compositor, like
you might find in a traditional web engine. These days, compositing is
done in WebRender so the name has stopped making much sense. Various
structs inside the crates have already been renamed and this is the
final big change necessary for the rename

Testing: This is just a rename so existing tests should cover it.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-24 09:17:35 +00:00
Martin Robinson
5d0db1fa6a layout: Add unit types to most layout queries (#42002)
This change makes it so that the euclid types returned from layout
queries use the `CSSPixel` unit type when appropriate. The minimal set
of changes are also made to avoid having to convert these types to the
`UnknownUnit` in other places. There is still some casting that has to
happen to deal with the difference between Stylo's `CSSPixel` and
WebRender's `LayoutPixel`, but a followup changes will try to switch to
using one or the other.

Testing: This should not change behavior, so is covered by existing
tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2026-01-23 15:38:57 +00:00
Martin Robinson
93fa5d3e0a layout: Properly account for transforms when finding glyph index (#41931)
This change makes it so that tranforms (including CSS transform and
scrolling) are properly accounted for when calculating glyph indices.
Containing block sizes are moved to `BaseFragment`. This should reduce
the size of the StackingContextTree a little.

Testing: A Servo-specific WPT-style test is added for this change.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-18 13:07:25 +00:00
Oriol Brufau
a5752da7d6 Upgrade Stylo to 2026-01-01 (#41916)
This continues #41696

Changelog:
- Upstream:
ab77635ba3...360787fff5
- Servo fixups:
0c47f9cb52...71737ad5c8

Stylo tracking issue: https://github.com/servo/stylo/issues/286

Testing: Various tests are now passing

---------

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2026-01-15 10:58:48 +00:00
Martin Robinson
5c76c529e1 layout: Add support for clicking past the end of multiline inputs (#41909)
Make it so that clicking past the end of the text of a multiline input,
moves the edit point to the end of that line. Now we evaluate all
potential target `TextFragment`s and find the most appropriate one,
putting the edit point there.

Testing: This updates expected test results for the `<textarea>`
clicking tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-15 08:11:12 +00:00
Martin Robinson
d5dcdd6e06 script: Add support for setting the edit point with the mouse in <input> and <textarea> (#41906)
This change updates and implements the old `query_text_index` layout
query to properly look for the glyph index of a point within a node's
`Fragment`s. This should work properly with the shadow DOM of both
`<input>` and `<textarea>` elements. In particular, multiple lines are
supported.

Caveats:
 - `<input>` and `<textarea>` that are transformed are currently not
   supported. This will happen in a followup.
 - For multi-line inputs, we should be finding the text offset of the
   nearest line that is within the block range of the click. This will
   happen in a followup.

Testing: This change adds two Servo-specific WPT-style tests. These are
Servo-specific because the behavior of clicking in text fields isn't
fully specified.

Fixes: #35432
Fixes: #10083

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2026-01-14 13:23:43 +00:00
Martin Robinson
55c4f579c9 fonts: Refactor the font fallback code a little bit and remove RwLock around FontGroup (#41449)
This change reworks the logic for finding font fallbacks to make it
simpler. I was involved with writing the code for `FontGroupFamily` and
`FontGroupFamilyMember` and I still struggle a bit with understanding
it, so I've chosen to do this. In addition, the change is in preparation
for more flexible font fallback (#41426).

The main changes here are:
 1. Move the logic for creating a new descriptor with variations into
    the Font constructor.
 2. Add some more general methods to `FontGroupFamily` such as a
    template iterator.
 3. Use `OnceLock` to avoid a convoluted code structure because of
    mutability and also having boolean "loaded" members. This is what
    `OnceLock` and `OnceCell` are for!
 4. Rename `FontGroupFamilyMember` to `FontGroupFamilyTemplate` to
    stress that it is one template of a particular `FontGroupFamily`.

Testing: This should not change behavior so is covered by existing WPT
tests.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-12-22 15:06:25 +00:00
WaterWhisperer
85c33a9dcc net: Track fontdb allocations from SVG images by about:memory (#41254)
- make `ImageCache::memory_report` return `Vec<Report>` and rename
`memory_report` to `memory_reports`
- update `ImageCacheImpl::memory_report` to return a new Report for the
fontdb member
- add an implementation of `MallocSizeOf` for `fontdb::FaceInfo` which
sums the result of calling malloc_size_of on each of the string/vector
members
- add an implementation of `MallocSizeOf` for `fontdb::Database` which
sums the result of malloc_size_of on each of the faces

Testing: `./mach check` `./mach clippy`
`grep fontdb::Database::load_fonts_from_file untracked | wc -l` results:
2390 -> 545
- before:
<img width="1536" height="108" alt="截图 2025-12-14 13-53-32"
src="https://github.com/user-attachments/assets/422ce9d4-e962-45af-a072-7d1c0c9e80aa"
/>

- now:
<img width="1536" height="108" alt="截图 2025-12-14 13-58-26"
src="https://github.com/user-attachments/assets/363f933d-8ab0-4354-b8ae-89f6de46ca7b"
/>

Fixes: #38730

Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
2025-12-14 06:46:37 +00:00
Martin Robinson
824f551f03 Rename IOCompositor to Paint (#41176)
For a long time, the "Compositor" hasn't done any compositing. This is
handled by WebRender. In addition the "Compositor" does many other
tasks. This change renames `IOCompositor` to `Paint`.

`Paint` is Servo's paint subsystem and contains multiple `Painter`s.
This change does not rename the crate; that will be done in a
followup change.

Testing: This just renames types and updates comments, so no new tests
are necessary.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-12-10 15:09:49 +00:00
atbrakhi
f0490926b5 config: Rename DebugOpts to DiagnosticsLogging and get rid of dump terminology (#40960)
In this PR, we rename `DebugOpts` to `DiagnosticsLogging`, add some
documentation and rename variables to get rid of dump terminology.

Testing: 
Fixes: part of https://github.com/servo/servo/issues/40863

Signed-off-by: atbrakhi <atbrakhi@igalia.com>
2025-12-01 12:14:02 +00:00
d-kraus
0a0a20a9c6 Replace some #[allow] with #[expect] (#40865)
Replaces some #[allow] with #[expect]. In case where the lint
expectation was unfulfilled, I removed it.


Testing: Refactor
Part of: https://github.com/servo/servo/issues/40383

Signed-off-by: Dennis Kraus <kraus@posteo.de>
2025-11-24 22:41:45 +00:00
Josh Matthews
bbbfe6d299 fonts: Add WebFontDocumentContext for CSS Fonts 4 font fetching (#40301)
Rebase of #37021 with review comments applied. These changes bundle up
the required information from the relevant global when a stylesheet is
added so that any requests for web fonts match the specification.

Testing: Newly passing tests.
Fixes: #36590

---------

Signed-off-by: Uthman Yahaya Baba <uthmanyahayababa@gmail.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Uthman Yahaya Baba <uthmanyahayababa@gmail.com>
2025-11-23 07:45:24 +00:00
Mukilan Thiyagarajan
90595e3570 compositing: Support per-Painter operations and message handling (#40788)
Currently, only the first `Painter` is used for all operations in the
`Compositor`. This change modifies the compositor API and message
handling to allow routing the operations to the correct `Painter` via a
provided `PainterId` or `WebViewId`.

This change is to enable support for per-`WebView`s `RenderingContext`s.

Testing: This change shouldn't change behavior, so existing WPT tests
should cover it.

---------

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-11-21 13:15:55 +00:00
Jonathan Schwender
2028dabd2f profiling: Add abstraction over tracing-rs (#40160)
There are multiple motivating factors for this change:

1. `tracing-rs` can and is commonly used for structured logging, to gain
understanding in what is happening in concurrent code. We would like to
attempt to make a distinction of the performance tracing related usage
and the logging related usage.
2. This reduces boilerplate code. We don't have to feature guard every
span anymore, since the macro will do it for us.
3. This makes it easier to add multiple options for the trace backend
(i.e. exchanging tracing-rs for hitrace on OpenHarmony or System Tracing
in Android), or something entirely custom.
4. This makes it easier to add further compile-time options to control
the amount of tracing. E.g. a future PR could add options to enable
tracing based on environment variables set at compile time. Tracing adds
runtime overhead, even if the runtime switch is disabled, so having more
fine-grained options to partially enabled tracing could be useful.

Testing: Tested manually by building with and without the `tracing`
feature. In CI we also build with the tracing feature in the HarmonyOS
build. We don't have any automated tests for the correctness / presence
of the traced entries.

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2025-11-18 10:47:56 +00:00
Oriol Brufau
1d0a8b05fb Upgrade Stylo to 2025-11-01 (#40522)
This continues #39612

Changelog:
- Upstream:
b98470a5cb...d71fd89b78
- Servo fixups:
4714bab122...7481d7f7af

Stylo tracking issue: https://github.com/servo/stylo/issues/264

---------

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2025-11-11 02:59:38 +00:00
Martin Robinson
f08460cded script: Handle broken image icon in HTMLImageElement (#40429)
Instead of having the `ImageCache` return the broken image icon for
failed loads, have `HTMLImageElement` explicitly request it. This means
that the image is loaded on demand (reducing the usage of resources) and
also simplifying the interface of the `ImageCache` greatly.

In addition, the display of the broken image icon is improved, more
closely matching other browsers. A test for this display (which was
falsely passing before) is updated to reflect the new display of the
broken image icon.

Testing: There is a Servo-specific test for this change. Some WPT tests
start to fail as well. Before these were not properly loading the broken
image icon so they were failing before, just in a hidden way.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
2025-11-06 09:36:21 +00:00
Martin Robinson
fd54ce9059 script: Eagerly update the Device in Layout when it changes (#40432)
Instead of waiting for a reflow to update the `Device` in layout, update
it eagerly. This ensures that media queries can be answered correctly in
script before the next reflow. Also, it ensure that a new reflow is
triggered and reflects the change to the theme or viewport.

In addition, an unused viewport-related message from the Constellation
is removed. This would have needed to be updated by change, but since
it's unused I've just removed it.

This depends on https://github.com/servo/stylo/pull/260.

Testing: This fixes a WebView API test and improves

`/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html`.

Fixes: #40395.
Fixes: #40129.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-11-05 21:17:23 +00:00
WaterWhisperer
a90dff6919 script/layout: Implement Element.currentCSSZoom attribute (#40304)
Implements the `currentCSSZoom` readonly attribute on the Element
interface as
[spec](https://drafts.csswg.org/cssom-view/#dom-element-currentcsszoom).
- Adds a new layout query (`CurrentCSSZoomQuery`) that traverses from
the target element up through its ancestors
- Accumulates the product of all `zoom` CSS property values to compute
the effective zoom
- Returns 1.0 for elements that are not being rendered (display: none or
no layout data)

Testing: Updated WPT (removed 4 FAIL expectations from
`idlharness.html.ini`). Behavior tests in Element-currentCSSZoom.html
remain as expected FAIL because the underlying CSS `zoom` property
implementation in Servo does not yet apply zoom values to layout (the
zoom property is parsed but computed values remain 1.0).
Fixes: #40256

Signed-off-by: WaterWhisperer <waterwhisperer24@qq.com>
2025-11-05 14:25:53 +00:00
Martin Robinson
320da376e4 layout: Have ServoRestyleDamage immediately update flags on LayoutImpl (#40400)
Instead of passing a `damage` variable around during a single layout,
have the
damage update flags immediately on the `LayoutImpl`. This ensure that
damage from a restyle are not lost event when a layout query doesn't
need a display list or stacking context tree. In addition, it makes it
so that this is handled consistently across all different kinds of
layout (from queries or for display lists).

Testing: This should fix the test case from #40367.
Fixes: #40367.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-11-05 01:36:23 +00:00
Josh Matthews
61f98c510f script: Do not include transforms and inline boxes in ResizeObserver box area queries (#40323)
These changes implement the restrictions for content rects required by
the ResizeObserver specification: inline boxes must return empty rects,
and any transforms must be ignored.

Testing: Newly passing tests.
Fixes: #40259
Fixes: #40258

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
2025-11-03 15:19:34 +00:00
Josh Matthews
b3868c28e9 script: Report target padding and desired sizes for ResizeObserver notifications (#40254)
We were not following the specification for computing the values of the
content rect. Additionally, any non-content-box observer would get
confused because we never stored the correct size, leading to infinite
notifications when the latest size didn't match the last observed size.

Testing: Various tests now pass.
Fixes: #32549
Fixes: #40107

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
2025-10-31 18:11:34 +00:00
Mukilan Thiyagarajan
07cf9a9175 compositor: Rename RenderingGroupId to PainterId (#40307)
And let the Compositor create the `PainterId` when it creates a new
`Painter`. Also make inline formatting code take `LayoutContext` rather
than threading it via the `InlineFormattingContextBuilder`.


Testing: Should preserve existing behavior, so covered by existing
tests.

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-10-31 11:49:24 +00:00
Shubham Gupta
9eb3a973ae Add support for LargestContentfulPaint PaintMetric (#39384)
Steps for calculating LCP:
1. When the pref for `largest_contentful_paint_enabled` is enabled,
`LargestContentfulPaintCandidateCollector` is created once per
LayoutThread using `viewport_size`.
2. While building the `display_list`, it send the pre-calculated
`clip_rect` and `bounds` to `LCPCollector` along with `transform` and
`LCPCandidateType` for `visual_rect` calculation for `LCPCandidates`.
3. After `visual_rect` calculation, update the `lcp_candidate` based on
`area` of `visual_rect` and send it to `compositor`.
4. Then among `lcp_candidates`, we find out the
`largest_contentful_paint` and send it to `paint_metric`
5. In addition to above `LCP` also uses `PaintMetricState` to save
console from spamming with duplicate entries.



This PR includes following commits better segregation of code
1. Add `LargestContentfulPaintCandidate` struct
2. Add `LargestContentfulPaintCandidateCollector`
6. Collect the `LargestContentfulPaintCandidates`when feature is
enabled.
7. Send the `LargestContentfulPaintCandidates` to compositor
8. Add `LargestContentfulPaintCalculator`
9. Calculates the `LargestContentfulPaint`
10. Send `LCP` to `PaintMetrics`
11. Disable `LCP` feature on user interaction


Elements considered for LCP in this PR:
- Image element
- An element with background image

Reference: https://github.com/servo/servo/pull/38041
Testing: Tested using
[perf-analysis-tools](https://github.com/servo/perf-analysis-tools) See
attached screenshot.
Fixes: None

Perfetto
<img width="2566" height="1151" alt="Screenshot from 2025-10-16
11-37-41"
src="https://github.com/user-attachments/assets/96e4f933-b39c-4ac7-833c-46dcc0c1671e"
/>


Console Output of Metric
<img width="1784" height="282" alt="Screenshot from 2025-10-16 11-33-16"
src="https://github.com/user-attachments/assets/441746a5-92ae-47c6-9022-f49114f23a2d"
/>

---------

Signed-off-by: Shubham Gupta <shubham.gupta@chromium.org>
Co-authored-by: boluochoufeng <1355990831@qq.com>
2025-10-31 08:58:22 +00:00
Martin Robinson
4551e9dfe3 script: Have the renderer process root viewport handle keyboard scrolling (#40108)
When scrolling the root viewport of a WebView (the top level frame),
ask the renderer to process that event. This allows keyboard scrolling
to pan the pinch zoom viewport. This is important for moving around a
pinch zoomed WebView via the keyboard.

Testing: The changes this makes to panning are hard to test, since we
have no way of retrieving the pinch zoom viewport values from Servo,
but the normal scrolling is tested by a servodriver test which is still
passing with these changes.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
2025-10-24 12:28:50 +00:00
araya
6880af31f6 fonts: Do not fall back to non-Japanese fonts for Han in Japanese language documents (#39608)
## Motivations

This PR improves fallback font algorithm for Japanese documents on macos
and Linux.

For Japanese documents, we generally use a same font for
Hiragana/Katakana/Kanji(Han).
Since their is a fallback algorithm to render serif fonts for
`Script::Han`in current implementation, it gives unnatural reading
experience for Japanese users.

## Changes
To achieve above, 
- added `lang` field to `FallbackFontSelectionOptions` struct
- pass `_x_lang` from text_run in layout component

## Screenshots
rendering https://ja.wikipedia.org/wiki/Servo

<table>
<thead>
<tr>
<th>before fixed</th>
<th>after fixed</th>

</tr>
</thead>
<tbody>
<tr>
<td>
<!-- before fixed -->
<img width="545" height="168" alt="CleanShot 2025-10-01 at 23 08 24"
src="https://github.com/user-attachments/assets/9ad7ccb0-729a-49ad-b8ce-88b1d78a2705"
/>



</td>
<td>
<!-- after fixed -->

<img width="474" height="139" alt="CleanShot 2025-10-01 at 23 07 16"
src="https://github.com/user-attachments/assets/010e8052-5a10-48e1-8367-ff29a5632d0f"
/>


</td>

</tr>
</tbody>
</table>

---------

Signed-off-by: araya <araya@araya.dev>
2025-10-11 09:07:14 +00:00
Oriol Brufau
613dc1ab0e Stylo: Let Stylesheet::from_bytes() take a Arc<Locked<MediaList>> parameter (#39731)
For `@import` we already had a `Arc<Locked<MediaList>>`, so now we will
no longer pointlessly clone it into a `MediaList` in order to pass it to
`Stylesheet::from_bytes()`, just for it to be wrapped again into an
`Arc<Locked<MediaList>>`.

Testing: Unneeded, no change in behavior

Stylo PR: https://github.com/servo/stylo/pull/251

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2025-10-09 21:21:16 +00:00
Oriol Brufau
7b60bd7f51 script: Refactor imported stylesheets (#39719)
We were previously using the unsound `StylesheetContents::from_data()`
to create a dummy stylesheet, which we were later replacing with the
actual imported stylesheet once it loaded.

This patch changes that to use `ImportSheet::Pending` instead. But then:
- We need to store the `MediaList` in `StylesheetContextSource`.
Previosuly we stored it in the dummy stylesheet.
- We also need to store an Arc pointer to the `ImportRule`, in order to
update its stylesheet to `ImportSheet::Sheet(stylesheet)` later on.

Testing: Unnecessary, there should be no behavior change
Fixes: #39710

Stylo PR: https://github.com/servo/stylo/pull/250

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2025-10-09 09:38:33 +00:00
Martin Robinson
9808973467 script: Do not root nodes with animating images (#38996)
Now that we do not need to call `Node::dirty` when an image frame
changes, we no longer have to keep a map of rooted nodes. Instead,
expose a new `AnimatingImages` type that also tracks when the set of
animating images is diryt and new image animation update should maybe be
scheduled.

In addition, cancel any ongoing image animations eagerly when they are
removed from the DOM like we do for CSS animations.

Testing: This should not change behavior and thus is covered by existing
WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
2025-10-09 07:28:38 +00:00
Martin Robinson
949981163a script: Share Epoch between canvas and layout and update the renderer separately (#39627)
Before both canvas updates and layout had their own `Epoch`. This change
makes it so the `Epoch` is shared. This means that display lists might
have non-consecutive `Epoch`s, but will also allow for the `Epoch` in
the renderer to update even when no new display list is produced. This
is important for #38991. In that PR the display list step can be skipped
for canvas-only updates, but the `Epoch` in the renderer must still
advance.

Testing: This shouldn't change the user-observable behavior and is thus
covered
by existing tests. It should prevent flakiness once #38991 lands.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-10-03 07:22:48 +00:00
Oriol Brufau
df9902e4d0 Upgrade Stylo to 2025-10-01 (#39612)
This continues #39150

Changelog:
- Upstream:
fd700321cc...b98470a5cb
- Servo fixups:
1040a20611...4ba7bdb404

Stylo tracking issue: https://github.com/servo/stylo/issues/247

---------

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2025-10-02 01:23:05 +00:00
Martin Robinson
6a2a9a6e33 layout: Ensure that the Epoch stored in layout is accurate (#39568)
The first epoch is 0 as that is the one used in the initial transaction,
but the code was setting the first `Epoch` to `Epoch(1)`. This means
that
when layout advanced the epoch, the `Epoch` of the first produced
display list was `Epoch(2)`.

This change makes the value reflected in `current_epoch` actually match
the index of the display list produced. In addition, we always store
this epoch in `PipelineDetails` in the renderer. This will be important
when adding the `WebView::take_screenshot` API.

Testing: This should not change behavior, so is covered by existing
tests which
rely on proper `Epoch` advancement.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-09-30 06:42:58 +00:00
Narfinger
e64f021550 Allow WebViews and fonts to have a RenderingGroupId. (#39140)
Motivation: The font cache currently has to store a cache of Keys which
need to be given by the webrender instance.
Having a cache for every WebViewId in the future when we have every
webview have the different webrender::DocumentId might be too wasteful
to store this key cache per DocumentId. This proposes to include in the
WebViewId another id, the RenderingGroupId. This id can be easily
changed
to be equivalent to the DocumentId when we support multiple DocumentIds
for a unique Webrender instance.
Additionally this will keep it easier to integrate the currently out of
tree patches for multiple rendering contexts with different webrenders.


Change:
We introduce the RenderingGroupId in the WebViewId and allow a method to
extract it. The font key cache uses this cache
and forwards it to the Compositor when requesting new changes. The
compositor currently ignores this id.
Additionally, the WebView can return the RenderingGroupId. The WebViewId
also has an appropiate constructor for specifying a RenderingGroupId.
Because there currently will be only one RenderingGroupId the
performance will be minimal.


Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>

Testing: This should be covered by WPT tests and normal browsing
behavior works fine.

---------

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-09-29 10:01:56 +00:00
Martin Robinson
ffdb7d3663 script: Chain up keyboard scrolling to parent <iframe>s (#39469)
When an `<iframe>` cannot scroll because the size of the frame is
greater than or
equal to the size of page contents, chain up the keyboard scroll
operation to the parent frame.

Testing: A new Servo-only WPT tests is added, though needs to be
manually
run with `--product servodriver`.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
2025-09-25 11:16:41 +00:00
shuppy
ac8895c3ae script: Move keyboard scrolling to script (#39371)
Instead of having every single embedder implement keyboard scrolling,
handle it in script in the default key event handler. This allows
properly targeting the scroll events to their scroll containers as well
as appropriately sizing "page up" and "page down" scroll deltas.

This change means that when you use the keyboard to scroll, the focused
or most recently clicked `<iframe>` or overflow scroll container is
scrolled, rather than the main frame.

In addition, when a particular scroll frame is larger than its content
in the axis of the scroll, the scrolling operation is chained to
the parent (as in other browsers). One exception is for `<iframe>`s,
which will be implemented in a followup change.

Testing: automated tests runnable locally with `mach test-wpt --product
servodriver`

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-09-23 20:35:08 +00:00
Oriol Brufau
2c3d580ef1 layout: Take sticky offsets into account for offset queries (#39385)
`offsetLeft` and `offsetTop` were ignoring that sticky positioned boxes
can be shifted out of their normal position.

Testing: Various test improvements.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-09-19 14:20:15 +00:00
Narfinger
84465e7768 Removed FnvHash and transformed the rest to FxHashmap (#39233)
This should be the final PR for the Hash Function series that is
trivial.

Of note: I decided to transform `HashMapTracedValues<Atom,..>` to use
FxBuildHasher. This is likely not going to improve performance as Atom's
already have a unique u32 that is used as the Hash but it safes a few
bytes for the RandomState that is normally in the HashMap.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>

Testing: Hash function changes should not change functionality, we
slightly decrease the size and unit tests still work.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-09-10 13:34:54 +00:00
JoeDow
30d3706a2b layout: allow only repaint when css background and border image loaded (#39201)
This change allows that only new display list is built when css
background and border image loaded.

Testing: This change should not change any behaviors so covered by
existing WPT tests.

Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
2025-09-08 13:23:11 +00:00
Martin Robinson
9f4f598f44 script: Use HTMLElement.scrollParent to implement Element.scrollIntoView (#39144)
To find scrolling ancestors, we need to walk up the flat tree and only
consider the elements that are in the chain of containing block
ancestors of an element. `scrollParent` now does this so we can use it
to properly implement `scrollIntoView`.

Testing: There are WPT tests for this change.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2025-09-07 21:44:11 +00:00
Martin Robinson
2c7866eb24 script/layout: Implement HTMLElement.scrollParent (#39110)
This new API allows getting the element which establishes an element's
scroll container. This will be used to properly implement
`scrollIntoView`. There is still work to do for this API and
`offsetParent` to properly handle ancestors which are
closed-shadow-hidden from the original query element.

In addition, fix an issue where inline boxes were establishing scrolling
containers (they shouldn't do that).

Testing: There are tests for this change.
Fixes: #39096.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2025-09-03 18:52:15 +00:00