mirror of
https://github.com/servo/servo.git
synced 2025-06-24 00:54:32 +01:00
Auto merge of #5782 - Adenilson:fixInlineFiltered01, r=pcwalton
It will create a StackingContext for inline elements that may need it, I'm looking for feedback on this. Not for commit, as there are some tests failing. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/5782) <!-- Reviewable:end -->
This commit is contained in:
commit
e66f761cba
5 changed files with 112 additions and 70 deletions
|
@ -230,6 +230,14 @@ pub trait FragmentDisplayListBuilding {
|
|||
display_list: &mut DisplayList,
|
||||
stacking_relative_border_box: &Rect<Au>,
|
||||
clip: &ClippingRegion);
|
||||
|
||||
/// Creates a stacking context for associated fragment.
|
||||
fn create_stacking_context(&self,
|
||||
base_flow: &BaseFlow,
|
||||
display_list: Box<DisplayList>,
|
||||
layer: Option<Arc<PaintLayer>>)
|
||||
-> Arc<StackingContext>;
|
||||
|
||||
}
|
||||
|
||||
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
|
||||
|
@ -1017,6 +1025,52 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_stacking_context(&self,
|
||||
base_flow: &BaseFlow,
|
||||
display_list: Box<DisplayList>,
|
||||
layer: Option<Arc<PaintLayer>>)
|
||||
-> Arc<StackingContext> {
|
||||
|
||||
let border_box = self.stacking_relative_border_box(&base_flow.stacking_relative_position,
|
||||
&base_flow.absolute_position_info
|
||||
.relative_containing_block_size,
|
||||
base_flow.absolute_position_info
|
||||
.relative_containing_block_mode,
|
||||
CoordinateSystem::Parent);
|
||||
|
||||
let transform_origin = self.style().get_effects().transform_origin;
|
||||
let transform_origin =
|
||||
Point2D(model::specified(transform_origin.horizontal,
|
||||
border_box.size.width).to_frac32_px(),
|
||||
model::specified(transform_origin.vertical,
|
||||
border_box.size.height).to_frac32_px());
|
||||
let transform = self.style().get_effects().transform
|
||||
.unwrap_or(ComputedMatrix::identity()).to_gfx_matrix(&border_box.size);
|
||||
|
||||
let transform = Matrix2D::identity().translate(transform_origin.x, transform_origin.y)
|
||||
.mul(&transform).translate(-transform_origin.x, -transform_origin.y);
|
||||
|
||||
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
|
||||
let margin = self.margin.to_physical(base_flow.writing_mode);
|
||||
let overflow = base_flow.overflow.translate(&-Point2D(margin.left, Au(0)));
|
||||
|
||||
// Create the filter pipeline.
|
||||
let effects = self.style().get_effects();
|
||||
let mut filters = effects.filter.clone();
|
||||
if effects.opacity != 1.0 {
|
||||
filters.push(Filter::Opacity(effects.opacity))
|
||||
}
|
||||
|
||||
Arc::new(StackingContext::new(display_list,
|
||||
&border_box,
|
||||
&overflow,
|
||||
self.style().get_box().z_index.number_or_zero(),
|
||||
&transform,
|
||||
filters,
|
||||
self.style().get_effects().mix_blend_mode,
|
||||
layer))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn finalize_position_and_size_of_iframe(&self,
|
||||
iframe_fragment: &IframeFragmentInfo,
|
||||
|
@ -1222,10 +1276,6 @@ pub trait BlockFlowDisplayListBuilding {
|
|||
fn build_display_list_for_block(&mut self,
|
||||
display_list: Box<DisplayList>,
|
||||
layout_context: &LayoutContext);
|
||||
fn create_stacking_context(&self,
|
||||
display_list: Box<DisplayList>,
|
||||
layer: Option<Arc<PaintLayer>>)
|
||||
-> Arc<StackingContext>;
|
||||
}
|
||||
|
||||
impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||
|
@ -1268,8 +1318,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
background_border_level);
|
||||
|
||||
self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
|
||||
DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list,
|
||||
None))
|
||||
DisplayListBuildingResult::StackingContext(self.fragment.create_stacking_context(&self.base, display_list, None))
|
||||
} else {
|
||||
DisplayListBuildingResult::Normal(display_list)
|
||||
}
|
||||
|
@ -1286,9 +1335,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
!self.base.flags.contains(NEEDS_LAYER) {
|
||||
// We didn't need a layer.
|
||||
self.base.display_list_building_result =
|
||||
DisplayListBuildingResult::StackingContext(self.create_stacking_context(
|
||||
display_list,
|
||||
None));
|
||||
DisplayListBuildingResult::StackingContext(self.fragment
|
||||
.create_stacking_context(&self.base, display_list, None));
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1299,9 +1347,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
ScrollPolicy::Scrollable
|
||||
};
|
||||
|
||||
|
||||
let transparent = color::transparent();
|
||||
let stacking_context =
|
||||
self.create_stacking_context(display_list,
|
||||
let stacking_context = self.fragment.create_stacking_context(&self.base, display_list,
|
||||
Some(Arc::new(PaintLayer::new(self.layer_id(0),
|
||||
transparent,
|
||||
scroll_policy))));
|
||||
|
@ -1318,8 +1366,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
display_list.form_float_pseudo_stacking_context();
|
||||
|
||||
self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
|
||||
DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list,
|
||||
None))
|
||||
DisplayListBuildingResult::StackingContext(self.fragment
|
||||
.create_stacking_context(&self.base, display_list, None))
|
||||
} else {
|
||||
DisplayListBuildingResult::Normal(display_list)
|
||||
}
|
||||
|
@ -1340,58 +1388,6 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
BackgroundAndBorderLevel::Block);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_stacking_context(&self,
|
||||
display_list: Box<DisplayList>,
|
||||
layer: Option<Arc<PaintLayer>>)
|
||||
-> Arc<StackingContext> {
|
||||
debug_assert!(self.fragment.establishes_stacking_context());
|
||||
let border_box = self.fragment
|
||||
.stacking_relative_border_box(&self.base.stacking_relative_position,
|
||||
&self.base
|
||||
.absolute_position_info
|
||||
.relative_containing_block_size,
|
||||
self.base
|
||||
.absolute_position_info
|
||||
.relative_containing_block_mode,
|
||||
CoordinateSystem::Parent);
|
||||
|
||||
let transform_origin = self.fragment.style().get_effects().transform_origin;
|
||||
let transform_origin =
|
||||
Point2D(model::specified(transform_origin.horizontal,
|
||||
border_box.size.width).to_frac32_px(),
|
||||
model::specified(transform_origin.vertical,
|
||||
border_box.size.height).to_frac32_px());
|
||||
let transform = self.fragment
|
||||
.style()
|
||||
.get_effects()
|
||||
.transform
|
||||
.unwrap_or(ComputedMatrix::identity())
|
||||
.to_gfx_matrix(&border_box.size);
|
||||
let transform = Matrix2D::identity().translate(transform_origin.x, transform_origin.y)
|
||||
.mul(&transform)
|
||||
.translate(-transform_origin.x, -transform_origin.y);
|
||||
|
||||
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
|
||||
let margin = self.fragment.margin.to_physical(self.base.writing_mode);
|
||||
let overflow = self.base.overflow.translate(&-Point2D(margin.left, Au(0)));
|
||||
|
||||
// Create the filter pipeline.
|
||||
let effects = self.fragment.style().get_effects();
|
||||
let mut filters = effects.filter.clone();
|
||||
if effects.opacity != 1.0 {
|
||||
filters.push(Filter::Opacity(effects.opacity))
|
||||
}
|
||||
|
||||
Arc::new(StackingContext::new(display_list,
|
||||
&border_box,
|
||||
&overflow,
|
||||
self.fragment.style().get_box().z_index.number_or_zero(),
|
||||
&transform,
|
||||
filters,
|
||||
self.fragment.style().get_effects().mix_blend_mode,
|
||||
layer))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait InlineFlowDisplayListBuilding {
|
||||
|
@ -1405,7 +1401,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
debug!("Flow: building display list for {} inline fragments", self.fragments.len());
|
||||
|
||||
let mut display_list = box DisplayList::new();
|
||||
|
||||
let mut has_stacking_context = false;
|
||||
for fragment in self.fragments.fragments.iter_mut() {
|
||||
fragment.build_display_list(&mut *display_list,
|
||||
layout_context,
|
||||
|
@ -1418,6 +1414,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
.relative_containing_block_mode,
|
||||
BackgroundAndBorderLevel::Content,
|
||||
&self.base.clip);
|
||||
|
||||
has_stacking_context = fragment.establishes_stacking_context();
|
||||
match fragment.specific {
|
||||
SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
|
||||
let block_flow = &mut *block_flow.flow_ref;
|
||||
|
@ -1438,7 +1436,14 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
self.fragments.fragments[0].node);
|
||||
}
|
||||
|
||||
// FIXME(Savago): fix Fragment::establishes_stacking_context() for absolute positioned item
|
||||
// and remove the check for filter presence. Further details on #5812.
|
||||
if has_stacking_context && !self.fragments.fragments[0].style().get_effects().filter.is_empty() {
|
||||
self.base.display_list_building_result =
|
||||
DisplayListBuildingResult::StackingContext(self.fragments.fragments[0].create_stacking_context(&self.base, display_list, None));
|
||||
} else {
|
||||
self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list);
|
||||
}
|
||||
|
||||
if opts::get().validate_display_list_geometry {
|
||||
self.base.validate_display_list_geometry();
|
||||
|
|
|
@ -108,6 +108,7 @@ flaky_cpu == append_style_a.html append_style_b.html
|
|||
== empty_cells_a.html empty_cells_ref.html
|
||||
== external_media_query_link.html external_media_query_ref.html
|
||||
== external_media_query_style.html external_media_query_ref.html
|
||||
== filter_inline_a.html filter_inline_ref.html
|
||||
== filter_opacity_a.html filter_opacity_ref.html
|
||||
== filter_sepia_a.html filter_sepia_ref.html
|
||||
== first_child_pseudo_a.html first_child_pseudo_b.html
|
||||
|
|
18
tests/ref/filter_inline_a.html
Normal file
18
tests/ref/filter_inline_a.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
|
||||
.ex {
|
||||
<!-- display: block; -->
|
||||
-webkit-filter: opacity(25%);
|
||||
-moz-filter: opacity(25%);
|
||||
filter: opacity(25%);
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img class="ex" src="rust.png">
|
||||
</body>
|
||||
</html>
|
18
tests/ref/filter_inline_ref.html
Normal file
18
tests/ref/filter_inline_ref.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
|
||||
.ex {
|
||||
display: block;
|
||||
-webkit-filter: opacity(25%);
|
||||
-moz-filter: opacity(25%);
|
||||
filter: opacity(25%);
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img class="ex" src="rust.png">
|
||||
</body>
|
||||
</html>
|
BIN
tests/ref/rust.png
Normal file
BIN
tests/ref/rust.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Loading…
Add table
Add a link
Reference in a new issue