Place item clipping_and_scrolling inside closure

A utility function assures that if the clipping and scrolling are changed
for a display item the old value is later restored.
This commit is contained in:
Pyfisch 2018-04-22 19:29:32 +02:00
parent c0be925bed
commit aada975dea
5 changed files with 108 additions and 104 deletions

View file

@ -17,7 +17,7 @@ use context::LayoutContext;
use display_list::ToLayout; use display_list::ToLayout;
use display_list::background::{build_border_radius, build_image_border_details}; use display_list::background::{build_border_radius, build_image_border_details};
use display_list::background::{calculate_inner_border_radii, compute_background_placement}; use display_list::background::{calculate_inner_border_radii, compute_background_placement};
use display_list::background::{convert_radial_gradient, convert_linear_gradient}; use display_list::background::{convert_linear_gradient, convert_radial_gradient};
use display_list::background::{get_cyclic, simple_normal_border}; use display_list::background::{get_cyclic, simple_normal_border};
use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR}; use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
use display_list::items::{BoxShadowDisplayItem, ClipScrollNode}; use display_list::items::{BoxShadowDisplayItem, ClipScrollNode};
@ -547,6 +547,13 @@ impl<'a> DisplayListBuildState<'a> {
list.push(item); list.push(item);
} }
} }
fn clipping_and_scrolling_scope<R, F: FnOnce(&mut Self) -> R>(&mut self, function: F) -> R {
let previous_clipping_and_scrolling = self.current_clipping_and_scrolling;
let ret = function(self);
self.current_clipping_and_scrolling = previous_clipping_and_scrolling;
ret
}
} }
/// The logical width of an insertion point: at the moment, a one-pixel-wide line. /// The logical width of an insertion point: at the moment, a one-pixel-wide line.
@ -858,25 +865,24 @@ impl FragmentDisplayListBuilding for Fragment {
}, },
} }
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling; state.clipping_and_scrolling_scope(|state| {
if !border_radii.is_zero() { if !border_radii.is_zero() {
let clip_id = state.add_late_clip_node(bounds.to_layout(), border_radii); let clip_id = state.add_late_clip_node(bounds.to_layout(), border_radii);
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id); state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
} }
let base = state.create_base_display_item( let base = state.create_base_display_item(
&bounds, &bounds,
&bounds, &bounds,
self.node, self.node,
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem {
base: base, base: base,
color: background_color.to_layout(), color: background_color.to_layout(),
}))); })));
});
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
// The background image is painted on top of the background color. // The background image is painted on top of the background color.
// Implements background image, per spec: // Implements background image, per spec:
@ -984,32 +990,31 @@ impl FragmentDisplayListBuilding for Fragment {
index, index,
); );
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling; state.clipping_and_scrolling_scope(|state| {
if !placement.clip_radii.is_zero() { if !placement.clip_radii.is_zero() {
let clip_id = let clip_id =
state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii); state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii);
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id); state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
} }
// Create the image display item. // Create the image display item.
let base = state.create_base_display_item( let base = state.create_base_display_item(
&placement.bounds, &placement.bounds,
&placement.clip_rect, &placement.clip_rect,
self.node, self.node,
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
debug!("(building display list) adding background image."); debug!("(building display list) adding background image.");
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
base: base, base: base,
id: webrender_image.key.unwrap(), id: webrender_image.key.unwrap(),
stretch_size: placement.tile_size.to_layout(), stretch_size: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
image_rendering: style.get_inheritedbox().image_rendering.to_layout(), image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
}))); })));
});
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
} }
fn get_webrender_image_for_paint_worklet( fn get_webrender_image_for_paint_worklet(
@ -1092,54 +1097,54 @@ impl FragmentDisplayListBuilding for Fragment {
index, index,
); );
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling; state.clipping_and_scrolling_scope(|state| {
if !placement.clip_radii.is_zero() { if !placement.clip_radii.is_zero() {
let clip_id = let clip_id =
state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii); state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii);
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id); state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
} }
let base = state.create_base_display_item( let base = state.create_base_display_item(
&placement.bounds, &placement.bounds,
&placement.clip_rect, &placement.clip_rect,
self.node, self.node,
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
let display_item = match gradient.kind { let display_item = match gradient.kind {
GradientKind::Linear(angle_or_corner) => { GradientKind::Linear(angle_or_corner) => {
let gradient = convert_linear_gradient( let gradient = convert_linear_gradient(
placement.tile_size, placement.tile_size,
&gradient.items[..], &gradient.items[..],
angle_or_corner, angle_or_corner,
gradient.repeating, gradient.repeating,
); );
DisplayItem::Gradient(Box::new(GradientDisplayItem { DisplayItem::Gradient(Box::new(GradientDisplayItem {
base: base, base: base,
gradient: gradient, gradient: gradient,
tile: placement.tile_size.to_layout(), tile: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
})) }))
}, },
GradientKind::Radial(shape, center, _angle) => { GradientKind::Radial(shape, center, _angle) => {
let gradient = convert_radial_gradient( let gradient = convert_radial_gradient(
placement.tile_size, placement.tile_size,
&gradient.items[..], &gradient.items[..],
shape, shape,
center, center,
gradient.repeating, gradient.repeating,
); );
DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem { DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem {
base: base, base: base,
gradient: gradient, gradient: gradient,
tile: placement.tile_size.to_layout(), tile: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
})) }))
}, },
}; };
state.add_display_item(display_item); state.add_display_item(display_item);
state.current_clipping_and_scrolling = previous_clipping_and_scrolling; });
} }
fn build_display_list_for_box_shadow_if_applicable( fn build_display_list_for_box_shadow_if_applicable(
@ -1677,7 +1682,13 @@ impl FragmentDisplayListBuilding for Fragment {
debug!("Fragment::build_display_list: intersected. Adding display item..."); debug!("Fragment::build_display_list: intersected. Adding display item...");
// Create special per-fragment-type display items. // Create special per-fragment-type display items.
self.build_fragment_type_specific_display_items(state, &stacking_relative_border_box, clip); state.clipping_and_scrolling_scope(|state| {
self.build_fragment_type_specific_display_items(
state,
&stacking_relative_border_box,
clip,
);
});
if opts::get().show_debug_fragment_borders { if opts::get().show_debug_fragment_borders {
self.build_debug_borders_around_fragment(state, &stacking_relative_border_box, clip) self.build_debug_borders_around_fragment(state, &stacking_relative_border_box, clip)
@ -1690,8 +1701,6 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_border_box: &Rect<Au>, stacking_relative_border_box: &Rect<Au>,
clip: &Rect<Au>, clip: &Rect<Au>,
) { ) {
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
// Compute the context box position relative to the parent stacking context. // Compute the context box position relative to the parent stacking context.
let stacking_relative_content_box = let stacking_relative_content_box =
self.stacking_relative_content_box(stacking_relative_border_box); self.stacking_relative_content_box(stacking_relative_border_box);
@ -1860,8 +1869,6 @@ impl FragmentDisplayListBuilding for Fragment {
panic!("Shouldn't see table column fragments here.") panic!("Shouldn't see table column fragments here.")
}, },
} }
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
} }
fn create_stacking_context( fn create_stacking_context(

View file

@ -71,10 +71,7 @@ impl ClippingAndScrolling {
} }
} }
pub fn new( pub fn new(scrolling: ClipScrollNodeIndex, clipping: ClipScrollNodeIndex) -> Self {
scrolling: ClipScrollNodeIndex,
clipping: ClipScrollNodeIndex,
) -> ClippingAndScrolling {
ClippingAndScrolling { ClippingAndScrolling {
scrolling, scrolling,
clipping: Some(clipping), clipping: Some(clipping),

View file

@ -483718,7 +483718,7 @@
"support" "support"
], ],
"css/css-backgrounds/background-rounded-image-clip.html": [ "css/css-backgrounds/background-rounded-image-clip.html": [
"c22edf865829fea1d69a54e34396b4462250585f", "1f3a33ee141f0bf0186875d376bc95414db8dd18",
"reftest" "reftest"
], ],
"css/css-backgrounds/background-size-001.html": [ "css/css-backgrounds/background-size-001.html": [
@ -485926,7 +485926,7 @@
"support" "support"
], ],
"css/css-backgrounds/reference/background-rounded-image-clip.html": [ "css/css-backgrounds/reference/background-rounded-image-clip.html": [
"f5c1af4d9e5b415e762c921c6d93355b2861946c", "0f98f9c82627977b11cde5f7c8ba536104cccdd2",
"support" "support"
], ],
"css/css-backgrounds/reference/background-size-002-ref.html": [ "css/css-backgrounds/reference/background-size-002-ref.html": [

View file

@ -28,7 +28,5 @@
border-color: transparent; border-color: transparent;
} }
</style> </style>
<body> <div id="a"></div>
<div id="a"></div> <div id="b"></div>
<div id="b"></div>
</body>

View file

@ -1,4 +1,6 @@
<!doctype html> <!doctype html>
<meta charset="utf-8">
<title>Corner Clipped Background Color</title>
<style> <style>
html { html {
background-color: green; background-color: green;