mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Implement basic overflow: scroll
functionality.
Known issues: * Display list optimization can sometimes optimize out elements that should be shown. This affects the Enyo demo. * The `overflow: scroll` container doesn't clip the inner layer properly when borders, border radius, etc. are present. * `overflow-x: scroll` and `overflow-y: scroll` don't work individually; elements are scrolled all at once. * Scrolling only works on absolutely-positioned elements.
This commit is contained in:
parent
fc13dd1169
commit
df4acbac04
8 changed files with 221 additions and 72 deletions
|
@ -629,6 +629,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
transform: Matrix4::identity(),
|
||||
perspective: Matrix4::identity(),
|
||||
establishes_3d_context: true,
|
||||
scrolls_overflow_area: false,
|
||||
};
|
||||
|
||||
let root_layer = CompositorData::new_layer(pipeline.id,
|
||||
|
@ -740,10 +741,21 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
|
||||
if let Some(parent_layer) = self.find_layer_with_pipeline_and_layer_id(pipeline_id,
|
||||
parent_id) {
|
||||
let wants_scroll_events = if layer_properties.scrolls_overflow_area {
|
||||
WantsScrollEventsFlag::WantsScrollEvents
|
||||
} else {
|
||||
WantsScrollEventsFlag::DoesntWantScrollEvents
|
||||
};
|
||||
|
||||
let new_layer = CompositorData::new_layer(pipeline_id,
|
||||
layer_properties,
|
||||
WantsScrollEventsFlag::DoesntWantScrollEvents,
|
||||
wants_scroll_events,
|
||||
parent_layer.tile_size);
|
||||
|
||||
if layer_properties.scrolls_overflow_area {
|
||||
*new_layer.masks_to_bounds.borrow_mut() = true
|
||||
}
|
||||
|
||||
parent_layer.add_child(new_layer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,6 +252,9 @@ pub struct StackingContext {
|
|||
|
||||
/// Whether this stacking context creates a new 3d rendering context.
|
||||
pub establishes_3d_context: bool,
|
||||
|
||||
/// Whether this stacking context scrolls its overflow area.
|
||||
pub scrolls_overflow_area: bool,
|
||||
}
|
||||
|
||||
impl StackingContext {
|
||||
|
@ -266,7 +269,8 @@ impl StackingContext {
|
|||
layer: Option<PaintLayer>,
|
||||
transform: Matrix4,
|
||||
perspective: Matrix4,
|
||||
establishes_3d_context: bool)
|
||||
establishes_3d_context: bool,
|
||||
scrolls_overflow_area: bool)
|
||||
-> StackingContext {
|
||||
StackingContext {
|
||||
display_list: display_list,
|
||||
|
@ -279,6 +283,7 @@ impl StackingContext {
|
|||
transform: transform,
|
||||
perspective: perspective,
|
||||
establishes_3d_context: establishes_3d_context,
|
||||
scrolls_overflow_area: scrolls_overflow_area,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -342,29 +342,27 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
|
|||
transform: &Matrix4,
|
||||
perspective: &Matrix4,
|
||||
parent_id: Option<LayerId>) {
|
||||
|
||||
let transform = transform.mul(&stacking_context.transform);
|
||||
let perspective = perspective.mul(&stacking_context.perspective);
|
||||
|
||||
let (next_parent_id, page_position, transform, perspective) =
|
||||
match stacking_context.layer {
|
||||
Some(ref paint_layer) => {
|
||||
// Layers start at the top left of their overflow rect, as far as the info we
|
||||
// give to the compositor is concerned.
|
||||
let overflow_size =
|
||||
Size2D::new(stacking_context.overflow.size.width.to_nearest_px() as f32,
|
||||
stacking_context.overflow.size.height.to_nearest_px() as f32);
|
||||
let establishes_3d_context = stacking_context.establishes_3d_context;
|
||||
let scrolls_overflow_area = stacking_context.scrolls_overflow_area;
|
||||
|
||||
// Layers start at the top left of their overflow rect, as far as the info
|
||||
// we give to the compositor is concerned.
|
||||
let overflow_relative_page_position = *page_position +
|
||||
stacking_context.bounds.origin +
|
||||
stacking_context.overflow.origin;
|
||||
let layer_position =
|
||||
Rect::new(Point2D::new(overflow_relative_page_position.x.to_nearest_px() as
|
||||
f32,
|
||||
overflow_relative_page_position.y.to_nearest_px() as
|
||||
f32),
|
||||
Size2D::new(stacking_context.overflow.size.width.to_nearest_px()
|
||||
as f32,
|
||||
stacking_context.overflow.size.height.to_nearest_px()
|
||||
as f32));
|
||||
|
||||
let establishes_3d_context = stacking_context.establishes_3d_context;
|
||||
let layer_position = Rect::new(
|
||||
Point2D::new(overflow_relative_page_position.x.to_nearest_px() as f32,
|
||||
overflow_relative_page_position.y.to_nearest_px() as f32),
|
||||
overflow_size);
|
||||
|
||||
properties.push(LayerProperties {
|
||||
id: paint_layer.id,
|
||||
|
@ -375,6 +373,7 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
|
|||
transform: transform,
|
||||
perspective: perspective,
|
||||
establishes_3d_context: establishes_3d_context,
|
||||
scrolls_overflow_area: scrolls_overflow_area,
|
||||
});
|
||||
|
||||
// When there is a new layer, the transforms and origin
|
||||
|
|
|
@ -1756,6 +1756,17 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
|
||||
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
// `overflow: auto` and `overflow: scroll` force creation of layers, since we can only
|
||||
// scroll layers.
|
||||
match (self.fragment.style().get_box().overflow_x,
|
||||
self.fragment.style().get_box().overflow_y.0) {
|
||||
(overflow_x::T::auto, _) | (overflow_x::T::scroll, _) |
|
||||
(_, overflow_x::T::auto) | (_, overflow_x::T::scroll) => {
|
||||
self.base.flags.insert(NEEDS_LAYER);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let position_start = self.base.position.start.to_physical(self.base.writing_mode,
|
||||
container_size);
|
||||
|
||||
|
@ -1892,8 +1903,10 @@ impl Flow for BlockFlow {
|
|||
.absolute_position_info
|
||||
.relative_containing_block_mode,
|
||||
CoordinateSystem::Own);
|
||||
let clip = self.fragment.clipping_region_for_children(&clip_in_child_coordinate_system,
|
||||
&stacking_relative_border_box);
|
||||
let clip = self.fragment.clipping_region_for_children(
|
||||
&clip_in_child_coordinate_system,
|
||||
&stacking_relative_border_box,
|
||||
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
|
||||
|
||||
// Process children.
|
||||
for kid in self.base.child_iter() {
|
||||
|
|
|
@ -62,6 +62,11 @@ use util::geometry::{Au, ZERO_POINT};
|
|||
use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
||||
use util::opts;
|
||||
|
||||
/// The fake fragment ID we use to indicate the inner display list for `overflow: scroll`.
|
||||
///
|
||||
/// FIXME(pcwalton): This is pretty ugly. Consider modifying `LayerId` somehow.
|
||||
const FAKE_FRAGMENT_ID_FOR_OVERFLOW_SCROLL: u32 = 1000000;
|
||||
|
||||
/// A possible `PaintLayer` for an stacking context
|
||||
pub enum StackingContextLayer {
|
||||
Existing(PaintLayer),
|
||||
|
@ -208,10 +213,11 @@ pub trait FragmentDisplayListBuilding {
|
|||
offset: Point2D<Au>,
|
||||
layout_context: &LayoutContext);
|
||||
|
||||
/// Returns the appropriate clipping region for descendants of this flow.
|
||||
/// Returns the appropriate clipping region for descendants of this fragment.
|
||||
fn clipping_region_for_children(&self,
|
||||
current_clip: &ClippingRegion,
|
||||
stacking_relative_border_box: &Rect<Au>)
|
||||
stacking_relative_border_box: &Rect<Au>,
|
||||
is_absolutely_positioned: bool)
|
||||
-> ClippingRegion;
|
||||
|
||||
/// Calculates the clipping rectangle for a fragment, taking the `clip` property into account
|
||||
|
@ -253,7 +259,8 @@ pub trait FragmentDisplayListBuilding {
|
|||
base_flow: &BaseFlow,
|
||||
display_list: Box<DisplayList>,
|
||||
layout_context: &LayoutContext,
|
||||
layer: StackingContextLayer)
|
||||
layer: StackingContextLayer,
|
||||
mode: StackingContextCreationMode)
|
||||
-> Arc<StackingContext>;
|
||||
|
||||
}
|
||||
|
@ -1129,17 +1136,37 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
base_flow: &BaseFlow,
|
||||
display_list: Box<DisplayList>,
|
||||
layout_context: &LayoutContext,
|
||||
layer: StackingContextLayer)
|
||||
layer: StackingContextLayer,
|
||||
mode: StackingContextCreationMode)
|
||||
-> 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);
|
||||
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
|
||||
let margin = self.margin.to_physical(base_flow.writing_mode);
|
||||
|
||||
let border_box = match mode {
|
||||
StackingContextCreationMode::Normal |
|
||||
StackingContextCreationMode::OuterScrollWrapper => {
|
||||
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)
|
||||
}
|
||||
StackingContextCreationMode::InnerScrollWrapper => {
|
||||
Rect::new(ZERO_POINT, base_flow.overflow.size)
|
||||
}
|
||||
};
|
||||
let overflow = match mode {
|
||||
StackingContextCreationMode::Normal => {
|
||||
base_flow.overflow.translate(&-Point2D::new(margin.left, Au(0)))
|
||||
}
|
||||
StackingContextCreationMode::InnerScrollWrapper |
|
||||
StackingContextCreationMode::OuterScrollWrapper => {
|
||||
Rect::new(ZERO_POINT, border_box.size)
|
||||
}
|
||||
};
|
||||
|
||||
let mut transform = Matrix4::identity();
|
||||
|
||||
if let Some(ref operations) = self.style().get_effects().transform.0 {
|
||||
let transform_origin = self.style().get_effects().transform_origin;
|
||||
let transform_origin =
|
||||
|
@ -1213,10 +1240,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
};
|
||||
|
||||
// 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::new(margin.left, Au(0)));
|
||||
|
||||
// Create the filter pipeline.
|
||||
let effects = self.style().get_effects();
|
||||
let mut filters = effects.filter.clone();
|
||||
|
@ -1247,7 +1270,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
let scrolls_overflow_area = mode == StackingContextCreationMode::OuterScrollWrapper;
|
||||
let transform_style = self.style().get_used_transform_style();
|
||||
let establishes_3d_context = scrolls_overflow_area ||
|
||||
transform_style == transform_style::T::flat;
|
||||
|
||||
Arc::new(StackingContext::new(display_list,
|
||||
&border_box,
|
||||
|
@ -1258,7 +1284,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
layer,
|
||||
transform,
|
||||
perspective,
|
||||
transform_style == transform_style::T::flat))
|
||||
establishes_3d_context,
|
||||
scrolls_overflow_area))
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
@ -1284,7 +1311,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
|
||||
fn clipping_region_for_children(&self,
|
||||
current_clip: &ClippingRegion,
|
||||
stacking_relative_border_box: &Rect<Au>)
|
||||
stacking_relative_border_box: &Rect<Au>,
|
||||
is_absolutely_positioned: bool)
|
||||
-> ClippingRegion {
|
||||
// Don't clip if we're text.
|
||||
if self.is_scanned_text_fragment() {
|
||||
|
@ -1297,12 +1325,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
|
||||
// Clip according to the values of `overflow-x` and `overflow-y`.
|
||||
//
|
||||
// TODO(pcwalton): Support scrolling.
|
||||
// TODO(pcwalton): Support scrolling of non-absolutely-positioned elements.
|
||||
// FIXME(pcwalton): This may be more complex than it needs to be, since it seems to be
|
||||
// impossible with the computed value rules as they are to have `overflow-x: visible` with
|
||||
// `overflow-y: <scrolling>` or vice versa!
|
||||
match self.style.get_box().overflow_x {
|
||||
overflow_x::T::hidden | overflow_x::T::auto | overflow_x::T::scroll => {
|
||||
match (self.style.get_box().overflow_x, is_absolutely_positioned) {
|
||||
(overflow_x::T::hidden, _) |
|
||||
(overflow_x::T::auto, false) |
|
||||
(overflow_x::T::scroll, false) => {
|
||||
let mut bounds = current_clip.bounding_rect();
|
||||
let max_x = cmp::min(bounds.max_x(), stacking_relative_border_box.max_x());
|
||||
bounds.origin.x = cmp::max(bounds.origin.x, stacking_relative_border_box.origin.x);
|
||||
|
@ -1311,8 +1341,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
match self.style.get_box().overflow_y.0 {
|
||||
overflow_x::T::hidden | overflow_x::T::auto | overflow_x::T::scroll => {
|
||||
match (self.style.get_box().overflow_y.0, is_absolutely_positioned) {
|
||||
(overflow_x::T::hidden, _) |
|
||||
(overflow_x::T::auto, false) |
|
||||
(overflow_x::T::scroll, false) => {
|
||||
let mut bounds = current_clip.bounding_rect();
|
||||
let max_y = cmp::min(bounds.max_y(), stacking_relative_border_box.max_y());
|
||||
bounds.origin.y = cmp::max(bounds.origin.y, stacking_relative_border_box.origin.y);
|
||||
|
@ -1527,17 +1559,21 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
|
||||
let paint_layer = PaintLayer::new(self.layer_id(0), color::transparent(), scroll_policy);
|
||||
let layer = StackingContextLayer::Existing(paint_layer);
|
||||
let stacking_context = self.fragment.create_stacking_context(&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
layer);
|
||||
let stacking_context = self.fragment.create_stacking_context(
|
||||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
layer,
|
||||
StackingContextCreationMode::Normal);
|
||||
DisplayListBuildingResult::StackingContext(stacking_context)
|
||||
} else {
|
||||
DisplayListBuildingResult::StackingContext(
|
||||
self.fragment.create_stacking_context(&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0))))
|
||||
self.fragment.create_stacking_context(
|
||||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0)),
|
||||
StackingContextCreationMode::Normal))
|
||||
}
|
||||
} else {
|
||||
match self.fragment.style.get_box().position {
|
||||
|
@ -1560,19 +1596,57 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
mut display_list: Box<DisplayList>,
|
||||
layout_context: &LayoutContext,
|
||||
border_painting_mode: BorderPaintingMode) {
|
||||
self.build_display_list_for_block_base(&mut *display_list,
|
||||
layout_context,
|
||||
border_painting_mode,
|
||||
BackgroundAndBorderLevel::RootOfStackingContext);
|
||||
// If `overflow: scroll` is in effect, we add this fragment's display items to a new
|
||||
// stacking context.
|
||||
let outer_display_list_for_overflow_scroll =
|
||||
match (self.fragment.style().get_box().overflow_x,
|
||||
self.fragment.style().get_box().overflow_y.0) {
|
||||
(overflow_x::T::auto, _) |
|
||||
(overflow_x::T::scroll, _) |
|
||||
(_, overflow_x::T::auto) |
|
||||
(_, overflow_x::T::scroll) => {
|
||||
// Create a separate display list for our own fragment.
|
||||
let mut outer_display_list_for_overflow_scroll = box DisplayList::new();
|
||||
let clip = self.base.clip.translate(&-self.base.stacking_relative_position);
|
||||
self.fragment.build_display_list(
|
||||
&mut outer_display_list_for_overflow_scroll,
|
||||
layout_context,
|
||||
&self.base.stacking_relative_position,
|
||||
&self.base.absolute_position_info.relative_containing_block_size,
|
||||
self.base.absolute_position_info.relative_containing_block_mode,
|
||||
border_painting_mode,
|
||||
BackgroundAndBorderLevel::RootOfStackingContext,
|
||||
&clip,
|
||||
&self.base.stacking_relative_position_of_display_port);
|
||||
|
||||
// Add the fragments of our children to the display list we'll use for the inner
|
||||
// stacking context.
|
||||
for kid in self.base.children.iter_mut() {
|
||||
flow::mut_base(kid).display_list_building_result.add_to(&mut *display_list);
|
||||
}
|
||||
|
||||
Some(outer_display_list_for_overflow_scroll)
|
||||
}
|
||||
_ => {
|
||||
self.build_display_list_for_block_base(
|
||||
&mut *display_list,
|
||||
layout_context,
|
||||
border_painting_mode,
|
||||
BackgroundAndBorderLevel::RootOfStackingContext);
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if !self.will_get_layer() {
|
||||
// We didn't need a layer.
|
||||
self.base.display_list_building_result =
|
||||
DisplayListBuildingResult::StackingContext(
|
||||
self.fragment.create_stacking_context(&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0))));
|
||||
self.fragment.create_stacking_context(
|
||||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0)),
|
||||
StackingContextCreationMode::Normal));
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1583,13 +1657,44 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
ScrollPolicy::Scrollable
|
||||
};
|
||||
|
||||
let paint_layer = PaintLayer::new(self.layer_id(0), color::transparent(), scroll_policy);
|
||||
let stacking_context = self.fragment.create_stacking_context(&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::Existing(paint_layer));
|
||||
let stacking_context_creation_mode = if outer_display_list_for_overflow_scroll.is_some() {
|
||||
StackingContextCreationMode::InnerScrollWrapper
|
||||
} else {
|
||||
StackingContextCreationMode::Normal
|
||||
};
|
||||
|
||||
let layer_id = if outer_display_list_for_overflow_scroll.is_some() {
|
||||
self.layer_id(FAKE_FRAGMENT_ID_FOR_OVERFLOW_SCROLL)
|
||||
} else {
|
||||
self.layer_id(0)
|
||||
};
|
||||
let paint_layer = PaintLayer::new(layer_id, color::transparent(), scroll_policy);
|
||||
let stacking_context = self.fragment.create_stacking_context(
|
||||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::Existing(paint_layer),
|
||||
stacking_context_creation_mode);
|
||||
|
||||
let outermost_stacking_context = match outer_display_list_for_overflow_scroll {
|
||||
Some(mut outer_display_list_for_overflow_scroll) => {
|
||||
outer_display_list_for_overflow_scroll.children.push_back(stacking_context);
|
||||
|
||||
let paint_layer = PaintLayer::new(self.layer_id(0),
|
||||
color::transparent(),
|
||||
scroll_policy);
|
||||
self.fragment.create_stacking_context(
|
||||
&self.base,
|
||||
outer_display_list_for_overflow_scroll,
|
||||
layout_context,
|
||||
StackingContextLayer::Existing(paint_layer),
|
||||
StackingContextCreationMode::OuterScrollWrapper)
|
||||
}
|
||||
None => stacking_context,
|
||||
};
|
||||
|
||||
self.base.display_list_building_result =
|
||||
DisplayListBuildingResult::StackingContext(stacking_context)
|
||||
DisplayListBuildingResult::StackingContext(outermost_stacking_context)
|
||||
}
|
||||
|
||||
fn build_display_list_for_floating_block(&mut self,
|
||||
|
@ -1604,10 +1709,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
|
||||
self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
|
||||
DisplayListBuildingResult::StackingContext(
|
||||
self.fragment.create_stacking_context(&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0))))
|
||||
self.fragment.create_stacking_context(
|
||||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0)),
|
||||
StackingContextCreationMode::Normal))
|
||||
} else {
|
||||
DisplayListBuildingResult::Normal(display_list)
|
||||
}
|
||||
|
@ -1702,10 +1809,12 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
|
||||
self.base.display_list_building_result = if has_stacking_context {
|
||||
DisplayListBuildingResult::StackingContext(
|
||||
self.fragments.fragments[0].create_stacking_context(&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0))))
|
||||
self.fragments.fragments[0].create_stacking_context(
|
||||
&self.base,
|
||||
display_list,
|
||||
layout_context,
|
||||
StackingContextLayer::IfCanvas(self.layer_id(0)),
|
||||
StackingContextCreationMode::Normal))
|
||||
} else {
|
||||
DisplayListBuildingResult::Normal(display_list)
|
||||
};
|
||||
|
@ -1895,3 +2004,10 @@ pub enum BorderPaintingMode<'a> {
|
|||
Hidden,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum StackingContextCreationMode {
|
||||
Normal,
|
||||
OuterScrollWrapper,
|
||||
InnerScrollWrapper,
|
||||
}
|
||||
|
||||
|
|
|
@ -1627,7 +1627,8 @@ impl Flow for InlineFlow {
|
|||
.relative_containing_block_mode,
|
||||
CoordinateSystem::Parent);
|
||||
let clip = fragment.clipping_region_for_children(&self.base.clip,
|
||||
&stacking_relative_border_box);
|
||||
&stacking_relative_border_box,
|
||||
false);
|
||||
match fragment.specific {
|
||||
SpecificFragmentInfo::InlineBlock(ref mut info) => {
|
||||
flow::mut_base(&mut *info.flow_ref).clip = clip;
|
||||
|
|
|
@ -1046,7 +1046,8 @@ impl LayoutTask {
|
|||
Some(paint_layer),
|
||||
Matrix4::identity(),
|
||||
Matrix4::identity(),
|
||||
true));
|
||||
true,
|
||||
false));
|
||||
|
||||
if opts::get().dump_display_list {
|
||||
println!("#### start printing display list.");
|
||||
|
|
|
@ -88,6 +88,8 @@ pub struct LayerProperties {
|
|||
pub perspective: Matrix4,
|
||||
/// Whether this layer establishes a new 3d rendering context.
|
||||
pub establishes_3d_context: bool,
|
||||
/// Whether this layer scrolls its overflow area.
|
||||
pub scrolls_overflow_area: bool,
|
||||
}
|
||||
|
||||
/// The interface used by the painter to acquire draw targets for each paint frame and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue