Commit Graph

13 Commits

Author SHA1 Message Date
Jelle Raaijmakers
90a211bf47 LibWeb: Use device-pixel coordinates in display list and AVC
Stop converting between CSS and device pixels as part of rendering - the
display list should be as simple as possible, so convert to DevicePixels
once when constructing the display list.
2026-02-26 07:43:00 +01:00
Tim Ledbetter
73d948a028 LibWeb: Pre-allocate visual context chain vectors for hit testing
Also use inline storage for typical hit testing depths.
2026-02-23 17:30:25 +01:00
Aliaksandr Kalenik
55f4009163 LibWeb: Walk linked list directly in transform_rect_to_viewport()
The chain is already in element→root order, which matches the linked
list's natural traversal via parent pointers. No need to collect into
a Vector first.
2026-02-22 16:09:15 +01:00
Psychpsyo
6ea528f0ec LibWeb: Do not create a layer when CSS isolation is set to isolate
This is entirely unnecessary. All that this property does is create a
stacking context.
2026-02-13 11:02:32 +00:00
Aliaksandr Kalenik
24c08b7d42 LibWeb: Fix mouse event offset computation with nested CSS transforms
compute_mouse_event_offset() only inverted the target element's own CSS
transform, ignoring ancestor transforms. This caused incorrect offsetX/
offsetY values when elements were nested inside transformed parents.

Use AccumulatedVisualContext::inverse_transform_point() to invert the
full ancestor transform chain instead.
2026-01-31 16:56:05 +01:00
Aliaksandr Kalenik
8b411ff8c6 LibWeb: Account for border-radius in hit testing
This change adds border-radius awareness to hit testing in two places:
1. ClipData::contains() now uses BorderRadiiData::contains() to properly
   check if a point is inside a rounded clip rect. This handles overflow
   clips from ancestor elements that have border-radius.
2. PaintableBox::hit_test() now directly checks the element's own
   border-radius before reporting a hit.
2026-01-22 11:30:17 +01:00
Aliaksandr Kalenik
96a39aeaa6 LibWeb: Move effects application into AccumulatedVisualContext
Effects (opacity, blend mode, filters) must be applied in the parent's
coordinate space, before the element's transform. Previously this was
handled by manually switching to the parent's visual context when
applying effects at paint time.

By adding EffectsData to AccumulatedVisualContext and positioning it
before TransformData in the chain, effects are now naturally applied in
the correct order during display list replay, eliminating the special
case in StackingContext::paint().

For SVG filters that can generate content from empty elements (feFlood,
feImage, feTurbulence), a transparent FillRect command is emitted to
trigger the filter through the same AVC pipeline.
2026-01-21 16:19:18 +01:00
Jelle Raaijmakers
f966750d2c LibWeb: Use local coordinates for overflow clip hit testing 2026-01-21 12:57:22 +01:00
Aliaksandr Kalenik
23a74ddc2a LibWeb: Use AccumulatedVisualContext in Element::get_client_rects()
The previous implementation had a bug: it composed all ancestor
transforms but applied them around only the innermost element's
transform origin. The correct behavior is to apply each transform
around its own origin.

AccumulatedVisualContext already tracks all visual transformations
(transforms, scroll offsets, perspective) correctly for hit testing.
This change adds a new transform_rect_to_viewport() method that performs
the forward transformation (element coordinates to viewport
coordinates), which is the inverse direction of
transform_point_for_hit_test().

This fixes getBoundingClientRect() returning incorrect coordinates for
elements inside transformed ancestors with non-default
transform-origins.
2026-01-19 08:53:30 +01:00
Aliaksandr Kalenik
a468d06289 LibWeb: Include path string in AccumulatedVisualContext::dump()
This adds the actual SVG path data to the ClipPathData dump output,
making it easier to debug clip-path issues.
2026-01-19 04:01:37 +01:00
Aliaksandr Kalenik
98afd82491 LibWeb: Integrate clip-path into AccumulatedVisualContext
Previously, clip-path was applied only during painting in
StackingContext::paint(), which meant hit testing did not respect
clip-path boundaries. Clicks outside the visible clipped region but
inside the element's bounding box would incorrectly register as hits.

By moving clip-path into AccumulatedVisualContext, it becomes part of
the same system that handles transforms, clips, and scroll offsets for
both painting and hit testing, ensuring consistent behavior.
2026-01-16 13:39:02 +01:00
Aliaksandr Kalenik
a87b5c722d LibWeb: Add AccumulatedVisualContext debugging infrastructure 2026-01-15 19:50:53 +01:00
Aliaksandr Kalenik
10833640b1 LibWeb: Introduce AccumulatedVisualContext
Introduce AccumulatedVisualContext, a tree structure that tracks the
cumulative visual state (scroll offsets, clip regions, transforms,
perspective) for each paintable box.

Motivation:

Before this change, visual state was fragmented across multiple
mechanisms:
- ClipFrame: Tracked clip rectangles, each storing its own
  enclosing_scroll_frame_id to handle scroll offset adjustments
- scroll_frame_id: Passed separately to each display list command
- PushStackingContext: Stored transform matrices directly in the command
- Every display list command implemented translate_by() (45 methods
  total) to allow scroll offset adjustment during playback

This fragmentation led to:
- Complex, error-prone coordinate transformation logic scattered
  throughout the codebase
- Commands being mutated during playback to apply scroll offsets
- Duplicate logic between painting and hit testing for coordinate
  transformations

Solution:

AccumulatedVisualContext builds a tree where each node represents a
single visual operation:
- ScrollData: A scroll frame with its ID
- ClipData: A clip rectangle with optional border radii
- TransformData: A 4x4 transform matrix with its origin
- PerspectiveData: A perspective projection matrix

Each PaintableBox stores a reference to its accumulated context node.
The tree structure naturally captures the parent-child relationships,
so traversing from any node to the root gives the complete chain of
visual transformations.

Benefits this enables (in subsequent commits):
- Display list commands become immutable - no more translate_by()
- Single RefPtr<AccumulatedVisualContext> replaces separate
  scroll_frame_id and ClipFrame on commands
- LCA-based tree traversal during playback for efficient save/restore
- transform_point_for_hit_test() provides coordinate transformation for
  hit testing using the same structure
2026-01-15 19:50:53 +01:00