mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Fix fixed position items with parents with CSS clips
In order to properly handle CSS clipping, we need to keep track of what the different kinds of clips that we have. On one hand, clipping due to overflow rules should respect the containing block hierarchy, while CSS clipping should respect the flow tree hierarchy. In order to represent the complexity of items that are scrolled via one clip/scroll frame and clipped by another we keep track of that status with a ClipAndScrollInfo.
This commit is contained in:
parent
46f6e68bad
commit
daf638bc3f
11 changed files with 214 additions and 106 deletions
|
@ -33,8 +33,8 @@ use style::values::computed::Filter;
|
|||
use style_traits::cursor::Cursor;
|
||||
use text::TextRun;
|
||||
use text::glyph::ByteIndex;
|
||||
use webrender_api::{self, ClipId, ColorF, GradientStop, LocalClip, MixBlendMode, ScrollPolicy};
|
||||
use webrender_api::{ScrollSensitivity, TransformStyle, WebGLContextId};
|
||||
use webrender_api::{self, ClipAndScrollInfo, ClipId, ColorF, GradientStop, LocalClip};
|
||||
use webrender_api::{MixBlendMode, ScrollPolicy, ScrollSensitivity, TransformStyle, WebGLContextId};
|
||||
|
||||
pub use style::dom::OpaqueNode;
|
||||
|
||||
|
@ -152,7 +152,7 @@ impl DisplayList {
|
|||
match item {
|
||||
&DisplayItem::PushStackingContext(ref context_item) => {
|
||||
self.text_index_stacking_context(&context_item.stacking_context,
|
||||
item.base().scroll_root_id,
|
||||
item.scroll_node_id(),
|
||||
node,
|
||||
traversal,
|
||||
point,
|
||||
|
@ -229,7 +229,7 @@ impl DisplayList {
|
|||
match item {
|
||||
&DisplayItem::PushStackingContext(ref context_item) => {
|
||||
self.hit_test_stacking_context(&context_item.stacking_context,
|
||||
item.base().scroll_root_id,
|
||||
item.scroll_node_id(),
|
||||
traversal,
|
||||
point,
|
||||
offset_lookup,
|
||||
|
@ -286,10 +286,10 @@ impl DisplayList {
|
|||
pub fn print_with_tree(&self, print_tree: &mut PrintTree) {
|
||||
print_tree.new_level("Items".to_owned());
|
||||
for item in &self.list {
|
||||
print_tree.add_item(format!("{:?} StackingContext: {:?} ScrollRoot: {:?}",
|
||||
print_tree.add_item(format!("{:?} StackingContext: {:?} {:?}",
|
||||
item,
|
||||
item.base().stacking_context_id,
|
||||
item.scroll_root_id()));
|
||||
item.clip_and_scroll_info()));
|
||||
}
|
||||
print_tree.end_level();
|
||||
}
|
||||
|
@ -438,8 +438,8 @@ pub struct StackingContext {
|
|||
/// The scroll policy of this layer.
|
||||
pub scroll_policy: ScrollPolicy,
|
||||
|
||||
/// The id of the parent scrolling area that contains this StackingContext.
|
||||
pub parent_scroll_id: ClipId,
|
||||
/// The clip and scroll info for this StackingContext.
|
||||
pub parent_clip_and_scroll_info: ClipAndScrollInfo,
|
||||
}
|
||||
|
||||
impl StackingContext {
|
||||
|
@ -456,7 +456,7 @@ impl StackingContext {
|
|||
transform_style: TransformStyle,
|
||||
perspective: Option<Transform3D<f32>>,
|
||||
scroll_policy: ScrollPolicy,
|
||||
parent_scroll_id: ClipId)
|
||||
parent_clip_and_scroll_info: ClipAndScrollInfo)
|
||||
-> StackingContext {
|
||||
StackingContext {
|
||||
id: id,
|
||||
|
@ -470,7 +470,7 @@ impl StackingContext {
|
|||
transform_style: transform_style,
|
||||
perspective: perspective,
|
||||
scroll_policy: scroll_policy,
|
||||
parent_scroll_id: parent_scroll_id,
|
||||
parent_clip_and_scroll_info: parent_clip_and_scroll_info,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,13 +487,13 @@ impl StackingContext {
|
|||
TransformStyle::Flat,
|
||||
None,
|
||||
ScrollPolicy::Scrollable,
|
||||
pipeline_id.root_scroll_node())
|
||||
pipeline_id.root_clip_and_scroll_info())
|
||||
}
|
||||
|
||||
pub fn to_display_list_items(self, pipeline_id: PipelineId) -> (DisplayItem, DisplayItem) {
|
||||
let mut base_item = BaseDisplayItem::empty(pipeline_id);
|
||||
base_item.stacking_context_id = self.id;
|
||||
base_item.scroll_root_id = self.parent_scroll_id;
|
||||
base_item.clip_and_scroll_info = self.parent_clip_and_scroll_info;
|
||||
|
||||
let pop_item = DisplayItem::PopStackingContext(Box::new(
|
||||
PopStackingContextItem {
|
||||
|
@ -631,8 +631,8 @@ pub struct BaseDisplayItem {
|
|||
/// The id of the stacking context this item belongs to.
|
||||
pub stacking_context_id: StackingContextId,
|
||||
|
||||
/// The id of the scroll root this item belongs to.
|
||||
pub scroll_root_id: ClipId,
|
||||
/// The clip and scroll info for this item.
|
||||
pub clip_and_scroll_info: ClipAndScrollInfo,
|
||||
}
|
||||
|
||||
impl BaseDisplayItem {
|
||||
|
@ -642,7 +642,7 @@ impl BaseDisplayItem {
|
|||
local_clip: LocalClip,
|
||||
section: DisplayListSection,
|
||||
stacking_context_id: StackingContextId,
|
||||
scroll_root_id: ClipId)
|
||||
clip_and_scroll_info: ClipAndScrollInfo)
|
||||
-> BaseDisplayItem {
|
||||
BaseDisplayItem {
|
||||
bounds: *bounds,
|
||||
|
@ -650,7 +650,7 @@ impl BaseDisplayItem {
|
|||
local_clip: local_clip,
|
||||
section: section,
|
||||
stacking_context_id: stacking_context_id,
|
||||
scroll_root_id: scroll_root_id,
|
||||
clip_and_scroll_info: clip_and_scroll_info,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,7 +665,7 @@ impl BaseDisplayItem {
|
|||
local_clip: LocalClip::from(max_rect().to_rectf()),
|
||||
section: DisplayListSection::Content,
|
||||
stacking_context_id: StackingContextId::root(),
|
||||
scroll_root_id: pipeline_id.root_scroll_node(),
|
||||
clip_and_scroll_info: pipeline_id.root_clip_and_scroll_info(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1265,8 +1265,12 @@ impl DisplayItem {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn scroll_root_id(&self) -> ClipId {
|
||||
self.base().scroll_root_id
|
||||
pub fn scroll_node_id(&self) -> ClipId {
|
||||
self.base().clip_and_scroll_info.scroll_node_id
|
||||
}
|
||||
|
||||
pub fn clip_and_scroll_info(&self) -> ClipAndScrollInfo {
|
||||
self.base().clip_and_scroll_info
|
||||
}
|
||||
|
||||
pub fn stacking_context_id(&self) -> StackingContextId {
|
||||
|
@ -1297,7 +1301,7 @@ impl DisplayItem {
|
|||
// test elements with `border-radius`, for example.
|
||||
let base_item = self.base();
|
||||
|
||||
let scroll_offset = offset_lookup.full_offset_for_scroll_root(&base_item.scroll_root_id);
|
||||
let scroll_offset = offset_lookup.full_offset_for_scroll_root(&self.scroll_node_id());
|
||||
let point = Point2D::new(point.x - Au::from_f32_px(scroll_offset.x),
|
||||
point.y - Au::from_f32_px(scroll_offset.y));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue