This includes the Cargo.lock file changes and regenerated bindings.
4.2 KiB
Clipping in WebRender
The WebRender display list allows defining clips in two different ways. The
first is specified directly on each display item and cannot be reused between
items. The second is specified using the SpecificDisplayItem::Clip
display item
and can be reused between items as well as used to define scrollable regions.
Clips
Clips are defined using the ClipRegion in both cases.
pub struct ClipRegion {
pub main: LayoutRect,
pub complex: ItemRange<ComplexClip>,
pub image_mask: Option<ImageMask>,
}
main
defines a rectangular clip, while the other members make that rectangle
smaller. complex
, if it is not empty, defines the boundaries of a rounded
rectangle. While image_mask
defines the positioning, repetition, and data of
a masking image.
Item Clips
Item clips are simply a ClipRegion
structure defined directly on the
DisplayItem
. The important thing to note about these clips is that all the
coordinate in ClipRegion
are in the same coordinate space as the item
itself. This different than for clips defined by SpecificDisplayItem::Clip
.
Clip Display Items
Clip display items allow items to share clips in order to increase performance
(shared clips are only rasterized once) and to allow for scrolling regions.
Display items can be assigned a clip display item using the clip_id
field. An item can be assigned any clip that is defined by its parent stacking
context or any of the ancestors. The behavior of assigning an id outside of
this hierarchy is undefined, because that situation does not occur in CSS
The clip display item has a ClipRegion
as well as several other fields:
pub struct ClipDisplayItem {
pub id: ClipId,
pub parent_id: ClipId,
}
A ClipDisplayItem
also gets a clip and bounds from the BaseDisplayItem
. The
clip is shared among all items that use this ClipDisplayItem
. Critically,
coordinates in this ClipRegion are defined relative to the bounds of the
ClipDisplayItem itself. Additionally, WebRender only supports clip rectangles
that start at the origin of the BaseDisplayItem
bounds.
The BaseDisplayItem
bounds are known as the content rectangle of the clip. If
the content rectangle is larger than main clipping rectangle, the clip will
be a scrolling clip and participate in scrolling event capture and
transformation.
ClipDisplayItems
are positioned, like all other items, relatively to their
containing stacking context, yet they also live in a parallel tree defined by
their parent_id
. Child clips also include any clipping and scrolling that
their ancestors do. In this way, a clip is positioned by a stacking context,
but that position may be adjusted by any scroll offset of its parent clips.
Clip ids
All clips defined by a ClipDisplayItem
have an id. It is useful to associate
an external id with WebRender id in order to allow for tracking and updating
scroll positions using the WebRender API. In order to make this as cheap as
possible and to avoid having to create a HashMap
to map between the two types
of ids, the WebRender API provides an optional id argument in
DisplayListBuilder::define_clip
. The only types of ids that are supported
here are those created with ClipId::new(...)
. If this argument is not
provided define_clip
will return a uniquely generated id. Thus, the following
should always be true:
let id = ClipId::new(my_internal_id, pipeline_id);
let generated_id = define_clip(content_rect, clip, id);
assert!(id == generated_id);
Note that calling define_clip
multiple times with the same clip_id
value
results in undefined behaviour, and should be avoided. There is a debug mode
assertion to catch this.
Pending changes
-
Normalize the way that clipping coordinates are defined. Having them specified in two different ways makes for a confusing API. This should be fixed. (github issue)
-
It should be possible to specify more than one predefined clip for an item. This is necessary for items that live in a scrolling frame, but are also clipped by a clip that lives outside that frame. (github issue)