mirror of
https://github.com/servo/servo.git
synced 2025-06-24 09:04:33 +01:00
auto merge of #589 : eric93/servo/diplaylist-refactor, r=pcwalton
This commit is contained in:
commit
45e6873f80
6 changed files with 74 additions and 83 deletions
|
@ -7,7 +7,6 @@
|
||||||
use layout::box::{RenderBox};
|
use layout::box::{RenderBox};
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||||
use layout::display_list_builder::{FlowDisplayListBuilderMethods};
|
|
||||||
use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow, FloatFlow};
|
use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow, FloatFlow};
|
||||||
use layout::inline::InlineLayout;
|
use layout::inline::InlineLayout;
|
||||||
use layout::model::{MaybeAuto, Specified, Auto};
|
use layout::model::{MaybeAuto, Specified, Auto};
|
||||||
|
@ -327,11 +326,17 @@ impl BlockFlowData {
|
||||||
pub fn build_display_list_block<E:ExtraDisplayListData>(@mut self,
|
pub fn build_display_list_block<E:ExtraDisplayListData>(@mut self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
offset: &Point2D<Au>,
|
list: &Cell<DisplayList<E>>)
|
||||||
list: &Cell<DisplayList<E>>) {
|
-> bool {
|
||||||
|
|
||||||
|
let abs_rect = Rect(self.common.abs_position, self.common.position.size);
|
||||||
|
if !abs_rect.intersects(dirty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// add box that starts block context
|
// add box that starts block context
|
||||||
self.box.map(|&box| {
|
self.box.map(|&box| {
|
||||||
box.build_display_list(builder, dirty, offset, list)
|
box.build_display_list(builder, dirty, &self.common.abs_position, list)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -340,8 +345,12 @@ impl BlockFlowData {
|
||||||
// go deeper into the flow tree
|
// go deeper into the flow tree
|
||||||
let flow = BlockFlow(self);
|
let flow = BlockFlow(self);
|
||||||
for flow.each_child |child| {
|
for flow.each_child |child| {
|
||||||
flow.build_display_list_for_child(builder, child, dirty, offset, list)
|
do child.with_mut_base |base| {
|
||||||
}
|
base.abs_position = self.common.abs_position + base.position.origin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,9 @@
|
||||||
|
|
||||||
use layout::box::RenderBox;
|
use layout::box::RenderBox;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::flow::FlowContext;
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
|
||||||
use geom::point::Point2D;
|
|
||||||
use geom::rect::Rect;
|
|
||||||
use gfx::display_list::DisplayList;
|
|
||||||
use gfx::geometry::Au;
|
|
||||||
use gfx;
|
use gfx;
|
||||||
use newcss;
|
use newcss;
|
||||||
use servo_util::tree::TreeNodeRef;
|
|
||||||
|
|
||||||
/// Extra display list data is either nothing (if the display list is to be rendered) or the
|
/// Extra display list data is either nothing (if the display list is to be rendered) or the
|
||||||
/// originating render box (if the display list is generated for hit testing).
|
/// originating render box (if the display list is generated for hit testing).
|
||||||
|
@ -49,54 +42,6 @@ pub struct DisplayListBuilder<'self> {
|
||||||
ctx: &'self LayoutContext,
|
ctx: &'self LayoutContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FlowDisplayListBuilderMethods {
|
|
||||||
fn build_display_list<E:ExtraDisplayListData>(&self,
|
|
||||||
a: &DisplayListBuilder,
|
|
||||||
b: &Rect<Au>,
|
|
||||||
c: &Cell<DisplayList<E>>);
|
|
||||||
fn build_display_list_for_child<E:ExtraDisplayListData>(&self,
|
|
||||||
a: &DisplayListBuilder,
|
|
||||||
b: FlowContext,
|
|
||||||
c: &Rect<Au>,
|
|
||||||
d: &Point2D<Au>,
|
|
||||||
e: &Cell<DisplayList<E>>);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FlowDisplayListBuilderMethods for FlowContext {
|
|
||||||
fn build_display_list<E:ExtraDisplayListData>(&self,
|
|
||||||
builder: &DisplayListBuilder,
|
|
||||||
dirty: &Rect<Au>,
|
|
||||||
list: &Cell<DisplayList<E>>) {
|
|
||||||
let zero = gfx::geometry::zero_point();
|
|
||||||
self.build_display_list_recurse(builder, dirty, &zero, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_display_list_for_child<E:ExtraDisplayListData>(&self,
|
|
||||||
builder: &DisplayListBuilder,
|
|
||||||
child_flow: FlowContext,
|
|
||||||
dirty: &Rect<Au>,
|
|
||||||
offset: &Point2D<Au>,
|
|
||||||
list: &Cell<DisplayList<E>>) {
|
|
||||||
// Adjust the dirty rect to child flow context coordinates.
|
|
||||||
do child_flow.with_base |child_node| {
|
|
||||||
let abs_flow_bounds = child_node.position.translate(offset);
|
|
||||||
let adj_offset = offset.add(&child_node.position.origin);
|
|
||||||
|
|
||||||
debug!("build_display_list_for_child: rel=%?, abs=%?",
|
|
||||||
child_node.position,
|
|
||||||
abs_flow_bounds);
|
|
||||||
debug!("build_display_list_for_child: dirty=%?, offset=%?", dirty, offset);
|
|
||||||
|
|
||||||
if dirty.intersects(&abs_flow_bounds) {
|
|
||||||
debug!("build_display_list_for_child: intersected. recursing into child flow...");
|
|
||||||
child_flow.build_display_list_recurse(builder, dirty, &adj_offset, list);
|
|
||||||
} else {
|
|
||||||
debug!("build_display_list_for_child: Did not intersect...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Miscellaneous useful routines
|
// Miscellaneous useful routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
use layout::box::{RenderBox};
|
use layout::box::{RenderBox};
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||||
use layout::display_list_builder::{FlowDisplayListBuilderMethods};
|
|
||||||
use layout::flow::{FloatFlow, FlowData};
|
use layout::flow::{FloatFlow, FlowData};
|
||||||
use layout::model::{MaybeAuto};
|
use layout::model::{MaybeAuto};
|
||||||
use layout::float_context::{FloatContext, PlacementInfo, FloatType};
|
use layout::float_context::{FloatContext, PlacementInfo, FloatType};
|
||||||
|
@ -226,20 +225,33 @@ impl FloatFlowData {
|
||||||
pub fn build_display_list_float<E:ExtraDisplayListData>(@mut self,
|
pub fn build_display_list_float<E:ExtraDisplayListData>(@mut self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
offset: &Point2D<Au>,
|
list: &Cell<DisplayList<E>>)
|
||||||
list: &Cell<DisplayList<E>>) {
|
-> bool {
|
||||||
|
|
||||||
let offset = *offset + self.rel_pos;
|
let abs_rect = Rect(self.common.abs_position, self.common.position.size);
|
||||||
|
if !abs_rect.intersects(dirty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let offset = self.common.abs_position + self.rel_pos;
|
||||||
|
// add box that starts block context
|
||||||
self.box.map(|&box| {
|
self.box.map(|&box| {
|
||||||
box.build_display_list(builder, dirty, &offset, list)
|
box.build_display_list(builder, dirty, &offset, list)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: handle any out-of-flow elements
|
||||||
|
|
||||||
// go deeper into the flow tree
|
// go deeper into the flow tree
|
||||||
let flow = FloatFlow(self);
|
let flow = FloatFlow(self);
|
||||||
for flow.each_child |child| {
|
for flow.each_child |child| {
|
||||||
flow.build_display_list_for_child(builder, child, dirty, &offset, list)
|
do child.with_mut_base |base| {
|
||||||
}
|
base.abs_position = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,19 @@ impl FlowContext {
|
||||||
InlineFlow(data) => data.teardown()
|
InlineFlow(data) => data.teardown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like traverse_preorder, but don't end the whole traversal if the callback
|
||||||
|
/// returns false.
|
||||||
|
fn partially_traverse_preorder(&self, callback: &fn(FlowContext) -> bool) {
|
||||||
|
if !callback((*self).clone()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for self.each_child |kid| {
|
||||||
|
// FIXME: Work around rust#2202. We should be able to pass the callback directly.
|
||||||
|
kid.partially_traverse_preorder(|a| callback(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlowData {
|
impl FlowData {
|
||||||
|
@ -162,6 +175,7 @@ pub struct FlowData {
|
||||||
floats_in: FloatContext,
|
floats_in: FloatContext,
|
||||||
floats_out: FloatContext,
|
floats_out: FloatContext,
|
||||||
num_floats: uint,
|
num_floats: uint,
|
||||||
|
abs_position: Point2D<Au>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeNode<FlowContext> for FlowData {
|
impl TreeNode<FlowContext> for FlowData {
|
||||||
|
@ -225,6 +239,7 @@ impl FlowData {
|
||||||
floats_in: Invalid,
|
floats_in: Invalid,
|
||||||
floats_out: Invalid,
|
floats_out: Invalid,
|
||||||
num_floats: 0,
|
num_floats: 0,
|
||||||
|
abs_position: Point2D(Au(0), Au(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,23 +311,24 @@ impl<'self> FlowContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_display_list_recurse<E:ExtraDisplayListData>(&self,
|
pub fn build_display_list<E:ExtraDisplayListData>(&self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
offset: &Point2D<Au>,
|
list: &Cell<DisplayList<E>>)
|
||||||
list: &Cell<DisplayList<E>>) {
|
-> bool {
|
||||||
do self.with_base |info| {
|
|
||||||
debug!("FlowContext::build_display_list at %?: %s", info.position, self.debug_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
BlockFlow(info) => info.build_display_list_block(builder, dirty, offset, list),
|
BlockFlow(info) => info.build_display_list_block(builder, dirty, list),
|
||||||
InlineFlow(info) => info.build_display_list_inline(builder, dirty, offset, list),
|
InlineFlow(info) => info.build_display_list_inline(builder, dirty, list),
|
||||||
FloatFlow(info) => info.build_display_list_float(builder, dirty, offset, list),
|
FloatFlow(info) => info.build_display_list_float(builder, dirty, list),
|
||||||
_ => fail!(fmt!("Tried to build_display_list_recurse of flow: %?", self))
|
_ => {
|
||||||
|
fail!("Tried to build_display_list_recurse of flow: %?", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Actual methods that do not require much flow-specific logic
|
// Actual methods that do not require much flow-specific logic
|
||||||
pub fn foldl_all_boxes<B:Clone>(&self, seed: B, cb: &fn(a: B, b: RenderBox) -> B) -> B {
|
pub fn foldl_all_boxes<B:Clone>(&self, seed: B, cb: &fn(a: B, b: RenderBox) -> B) -> B {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
@ -745,8 +745,14 @@ impl InlineFlowData {
|
||||||
pub fn build_display_list_inline<E:ExtraDisplayListData>(&self,
|
pub fn build_display_list_inline<E:ExtraDisplayListData>(&self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
offset: &Point2D<Au>,
|
list: &Cell<DisplayList<E>>)
|
||||||
list: &Cell<DisplayList<E>>) {
|
-> bool {
|
||||||
|
|
||||||
|
let abs_rect = Rect(self.common.abs_position, self.common.position.size);
|
||||||
|
if !abs_rect.intersects(dirty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and
|
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and
|
||||||
// not recurse on a line if nothing in it can intersect the dirty region.
|
// not recurse on a line if nothing in it can intersect the dirty region.
|
||||||
debug!("FlowContext[%d]: building display list for %u inline boxes",
|
debug!("FlowContext[%d]: building display list for %u inline boxes",
|
||||||
|
@ -754,11 +760,12 @@ impl InlineFlowData {
|
||||||
self.boxes.len());
|
self.boxes.len());
|
||||||
|
|
||||||
for self.boxes.iter().advance |box| {
|
for self.boxes.iter().advance |box| {
|
||||||
box.build_display_list(builder, dirty, offset, list)
|
box.build_display_list(builder, dirty, &self.common.abs_position, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(#225): Should `inline-block` elements have flows as children of the inline flow or
|
// TODO(#225): Should `inline-block` elements have flows as children of the inline flow or
|
||||||
// should the flow be nested inside the box somehow?
|
// should the flow be nested inside the box somehow?
|
||||||
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use layout::aux::{LayoutData, LayoutAuxMethods};
|
||||||
use layout::box::RenderBox;
|
use layout::box::RenderBox;
|
||||||
use layout::box_builder::LayoutTreeBuilder;
|
use layout::box_builder::LayoutTreeBuilder;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
use layout::display_list_builder::{DisplayListBuilder};
|
||||||
use layout::flow::FlowContext;
|
use layout::flow::FlowContext;
|
||||||
|
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
|
@ -241,7 +241,9 @@ impl LayoutTask {
|
||||||
|
|
||||||
// TODO: Set options on the builder before building.
|
// TODO: Set options on the builder before building.
|
||||||
// TODO: Be smarter about what needs painting.
|
// TODO: Be smarter about what needs painting.
|
||||||
layout_root.build_display_list(&builder, &layout_root.position(), display_list);
|
for layout_root.traverse_preorder |flow| {
|
||||||
|
flow.build_display_list(&builder, &layout_root.position(), display_list);
|
||||||
|
}
|
||||||
|
|
||||||
let root_size = do layout_root.with_base |base| {
|
let root_size = do layout_root.with_base |base| {
|
||||||
base.position.size
|
base.position.size
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue