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::context::LayoutContext;
|
||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||
use layout::display_list_builder::{FlowDisplayListBuilderMethods};
|
||||
use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow, FloatFlow};
|
||||
use layout::inline::InlineLayout;
|
||||
use layout::model::{MaybeAuto, Specified, Auto};
|
||||
|
@ -327,11 +326,17 @@ impl BlockFlowData {
|
|||
pub fn build_display_list_block<E:ExtraDisplayListData>(@mut self,
|
||||
builder: &DisplayListBuilder,
|
||||
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
|
||||
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
|
||||
let flow = BlockFlow(self);
|
||||
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::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 newcss;
|
||||
use servo_util::tree::TreeNodeRef;
|
||||
|
||||
/// 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).
|
||||
|
@ -49,54 +42,6 @@ pub struct DisplayListBuilder<'self> {
|
|||
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
|
||||
//
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
use layout::box::{RenderBox};
|
||||
use layout::context::LayoutContext;
|
||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||
use layout::display_list_builder::{FlowDisplayListBuilderMethods};
|
||||
use layout::flow::{FloatFlow, FlowData};
|
||||
use layout::model::{MaybeAuto};
|
||||
use layout::float_context::{FloatContext, PlacementInfo, FloatType};
|
||||
|
@ -226,20 +225,33 @@ impl FloatFlowData {
|
|||
pub fn build_display_list_float<E:ExtraDisplayListData>(@mut self,
|
||||
builder: &DisplayListBuilder,
|
||||
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| {
|
||||
box.build_display_list(builder, dirty, &offset, list)
|
||||
});
|
||||
|
||||
|
||||
// TODO: handle any out-of-flow elements
|
||||
|
||||
// go deeper into the flow tree
|
||||
let flow = FloatFlow(self);
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
|
@ -162,6 +175,7 @@ pub struct FlowData {
|
|||
floats_in: FloatContext,
|
||||
floats_out: FloatContext,
|
||||
num_floats: uint,
|
||||
abs_position: Point2D<Au>
|
||||
}
|
||||
|
||||
impl TreeNode<FlowContext> for FlowData {
|
||||
|
@ -225,6 +239,7 @@ impl FlowData {
|
|||
floats_in: Invalid,
|
||||
floats_out: Invalid,
|
||||
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,
|
||||
dirty: &Rect<Au>,
|
||||
offset: &Point2D<Au>,
|
||||
list: &Cell<DisplayList<E>>) {
|
||||
do self.with_base |info| {
|
||||
debug!("FlowContext::build_display_list at %?: %s", info.position, self.debug_str());
|
||||
}
|
||||
list: &Cell<DisplayList<E>>)
|
||||
-> bool {
|
||||
|
||||
|
||||
match *self {
|
||||
BlockFlow(info) => info.build_display_list_block(builder, dirty, offset, list),
|
||||
InlineFlow(info) => info.build_display_list_inline(builder, dirty, offset, list),
|
||||
FloatFlow(info) => info.build_display_list_float(builder, dirty, offset, list),
|
||||
_ => fail!(fmt!("Tried to build_display_list_recurse of flow: %?", self))
|
||||
BlockFlow(info) => info.build_display_list_block(builder, dirty, list),
|
||||
InlineFlow(info) => info.build_display_list_inline(builder, dirty, list),
|
||||
FloatFlow(info) => info.build_display_list_float(builder, dirty, list),
|
||||
_ => {
|
||||
fail!("Tried to build_display_list_recurse of flow: %?", self)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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 {
|
||||
match *self {
|
||||
|
|
|
@ -745,8 +745,14 @@ impl InlineFlowData {
|
|||
pub fn build_display_list_inline<E:ExtraDisplayListData>(&self,
|
||||
builder: &DisplayListBuilder,
|
||||
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
|
||||
// not recurse on a line if nothing in it can intersect the dirty region.
|
||||
debug!("FlowContext[%d]: building display list for %u inline boxes",
|
||||
|
@ -754,11 +760,12 @@ impl InlineFlowData {
|
|||
self.boxes.len());
|
||||
|
||||
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
|
||||
// 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_builder::LayoutTreeBuilder;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
||||
use layout::display_list_builder::{DisplayListBuilder};
|
||||
use layout::flow::FlowContext;
|
||||
|
||||
use std::cast::transmute;
|
||||
|
@ -241,7 +241,9 @@ impl LayoutTask {
|
|||
|
||||
// TODO: Set options on the builder before building.
|
||||
// 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| {
|
||||
base.position.size
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue