diff --git a/servo/Makefile.in b/servo/Makefile.in index 4ab6cf56aacc..9bf8fe98b488 100644 --- a/servo/Makefile.in +++ b/servo/Makefile.in @@ -225,14 +225,14 @@ DONE_gfx = $(B)src/components/gfx/libgfx.dummy DEPS_gfx = $(CRATE_gfx) $(SRC_gfx) $(DONE_SUBMODULES) $(DONE_util) $(DONE_style) $(DONE_net) $(DONE_msg) -RFLAGS_script = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L $(B)src/components/style -L $(B)src/components/net -L $(B)src/components/gfx -L $(B)src/components/msg +RFLAGS_script = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L $(B)src/components/style -L $(B)src/components/net -L $(B)src/components/msg WEBIDL_script = $(call rwildcard,$(S)src/components/script/,*.webidl) AUTOGEN_SRC_script = $(patsubst %.webidl, %Binding.rs, $(WEBIDL_script)) SRC_script = $(call rwildcard,$(S)src/components/script/,*.rs) $(AUTOGEN_SRC_script) CRATE_script = $(S)src/components/script/script.rc DONE_script = $(B)src/components/script/libscript.dummy -DEPS_script = $(CRATE_script) $(SRC_script) $(DONE_SUBMODULES) $(DONE_util) $(DONE_style) $(DONE_net) $(DONE_gfx) $(DONE_msg) +DEPS_script = $(CRATE_script) $(SRC_script) $(DONE_SUBMODULES) $(DONE_util) $(DONE_style) $(DONE_net) $(DONE_msg) RFLAGS_style = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util MAKO_ZIP = $(S)src/components/style/Mako-0.8.1.zip diff --git a/servo/src/components/main/css/matching.rs b/servo/src/components/main/css/matching.rs index eb754d6259a1..2067d4679295 100644 --- a/servo/src/components/main/css/matching.rs +++ b/servo/src/components/main/css/matching.rs @@ -14,6 +14,7 @@ use extra::arc::RWArc; use css::node_style::StyledNode; use css::node_util::NodeUtil; use layout::incremental; +use layout::util::LayoutDataAccess; use script::dom::node::{AbstractNode, LayoutView}; use style::Stylist; @@ -37,10 +38,7 @@ impl MatchMethods for AbstractNode { }; stylist.get_applicable_declarations(self, style_attribute, None) }; - let cell = Cell::new(applicable_declarations); - do self.write_layout_data |data| { - data.applicable_declarations = cell.take(); - } + self.layout_data().applicable_declarations.set(applicable_declarations) } fn match_subtree(&self, stylist: RWArc) { let num_tasks = default_sched_threads() * 2; @@ -84,22 +82,21 @@ impl MatchMethods for AbstractNode { Some(parent) => Some(parent.style()), None => None }; - let computed_values = do self.read_layout_data |data| { - cascade(data.applicable_declarations, parent_style) - }; - let cell = Cell::new(computed_values); - do self.write_layout_data |data| { - let style = cell.take(); - - - match data.style { - None => (), - Some(ref previous_style) => self.set_restyle_damage( - incremental::compute_damage(previous_style, &style)) + + let layout_data = self.layout_data(); + let computed_values = cascade(*layout_data.applicable_declarations.borrow().ptr, + parent_style); + let style = layout_data.style.mutate(); + match *style.ptr { + None => (), + Some(ref previous_style) => { + self.set_restyle_damage(incremental::compute_damage(previous_style, + &computed_values)) } - data.style = Some(style); } + *style.ptr = Some(computed_values) } + fn cascade_subtree(&self, parent: Option>) { self.cascade_node(parent); diff --git a/servo/src/components/main/css/node_util.rs b/servo/src/components/main/css/node_util.rs index 7b5aeed64dc5..4c1a23544ac1 100644 --- a/servo/src/components/main/css/node_util.rs +++ b/servo/src/components/main/css/node_util.rs @@ -3,14 +3,13 @@ use layout::incremental::RestyleDamage; +use layout::util::LayoutDataAccess; use std::cast; -use std::cell::Cell; use style::ComputedValues; use script::dom::node::{AbstractNode, LayoutView}; use servo_util::tree::TreeNodeRef; - pub trait NodeUtil<'self> { fn get_css_select_results(self) -> &'self ComputedValues; fn set_css_select_results(self, decl: ComputedValues); @@ -29,23 +28,21 @@ impl<'self> NodeUtil<'self> for AbstractNode { fn get_css_select_results(self) -> &'self ComputedValues { - do self.read_layout_data |layout_data| { - match layout_data.style { - None => fail!(~"style() called on node without a style!"), - Some(ref style) => unsafe { cast::transmute_region(style) } - } + let layout_data = self.layout_data(); + match *layout_data.style.borrow().ptr { + None => fail!(~"style() called on node without a style!"), + Some(ref style) => unsafe { cast::transmute_region(style) } } } fn have_css_select_results(self) -> bool { - self.read_layout_data(|data| data.style.is_some()) + self.layout_data().style.borrow().ptr.is_some() } fn set_css_select_results(self, decl: ComputedValues) { - let cell = Cell::new(decl); - self.write_layout_data(|data| data.style = Some(cell.take())); + *self.layout_data().style.mutate().ptr = Some(decl) } @@ -59,15 +56,17 @@ impl<'self> NodeUtil<'self> for AbstractNode { RestyleDamage::none() }; - do self.read_layout_data |layout_data| { - layout_data.restyle_damage - .map(|x| RestyleDamage::from_int(x)) - .unwrap_or(default) - } + self.layout_data() + .restyle_damage + .borrow() + .ptr + .map(|x| RestyleDamage::from_int(x)) + .unwrap_or(default) } fn set_restyle_damage(self, damage: RestyleDamage) { - self.write_layout_data(|data| data.restyle_damage = Some(damage.to_int())); + *self.layout_data().restyle_damage.mutate().ptr = Some(damage.to_int()) } } + diff --git a/servo/src/components/main/layout/aux.rs b/servo/src/components/main/layout/aux.rs index 716180f857f0..a363baf3dcd6 100644 --- a/servo/src/components/main/layout/aux.rs +++ b/servo/src/components/main/layout/aux.rs @@ -4,8 +4,11 @@ +use layout::util::{DisplayBoxes, LayoutData, LayoutDataAccess}; + use script::dom::node::{AbstractNode, LayoutView}; use servo_util::tree::TreeNodeRef; +use std::cast; pub trait LayoutAuxMethods { @@ -15,10 +18,16 @@ pub trait LayoutAuxMethods { impl LayoutAuxMethods for AbstractNode { + + fn initialize_layout_data(self) { - do self.write_layout_data |data| { - data.boxes.display_list = None; - data.boxes.range = None; + unsafe { + let node = cast::transmute_mut(self.node()); + if node.layout_data.is_none() { + node.layout_data = Some(~LayoutData::new() as ~Any) + } else { + self.layout_data().boxes.set(DisplayBoxes::init()); + } } } diff --git a/servo/src/components/main/layout/layout_task.rs b/servo/src/components/main/layout/layout_task.rs index af76d8e49d7b..660956a9ec2b 100644 --- a/servo/src/components/main/layout/layout_task.rs +++ b/servo/src/components/main/layout/layout_task.rs @@ -15,10 +15,11 @@ use layout::flow::{FlowContext, ImmutableFlowUtils, MutableFlowUtils, PreorderFl use layout::flow::{PostorderFlowTraversal}; use layout::flow; use layout::incremental::{RestyleDamage, BubbleWidths}; +use layout::util::LayoutDataAccess; use std::cast::transmute; use std::cell::Cell; -use std::comm::{Port}; +use std::comm::Port; use std::task; use extra::arc::{Arc, RWArc}; use geom::point::Point2D; @@ -419,22 +420,23 @@ impl LayoutTask { transmute(display_list.get().list[i].base().extra) }; - do node.write_layout_data |layout_data| { - layout_data.boxes.display_list = Some(display_list.clone()); - - if layout_data.boxes.range.is_none() { - debug!("Creating initial range for node"); - layout_data.boxes.range = Some(Range::new(i,1)); - } else { - debug!("Appending item to range"); - unsafe { - let old_node: AbstractNode<()> = transmute(node); - assert!(old_node == display_list.get().list[i-1].base().extra, - "Non-contiguous arrangement of display items"); - } - - layout_data.boxes.range.unwrap().extend_by(1); + // FIXME(pcwalton): Why are we cloning the display list here?! + let layout_data = node.layout_data(); + let boxes = layout_data.boxes.mutate(); + boxes.ptr.display_list = Some(display_list.clone()); + + if boxes.ptr.range.is_none() { + debug!("Creating initial range for node"); + boxes.ptr.range = Some(Range::new(i,1)); + } else { + debug!("Appending item to range"); + unsafe { + let old_node: AbstractNode<()> = transmute(node); + assert!(old_node == display_list.get().list[i-1].base().extra, + "Non-contiguous arrangement of display items"); } + + boxes.ptr.range.unwrap().extend_by(1); } } @@ -469,34 +471,35 @@ impl LayoutTask { }; fn box_for_node(node: AbstractNode) -> Option> { - do node.read_layout_data |layout_data| { - match (layout_data.boxes.display_list.clone(), layout_data.boxes.range) { - (Some(display_list), Some(range)) => { - let mut rect: Option> = None; - for i in range.eachi() { - rect = match rect { - Some(acc) => { - Some(acc.union(&display_list.get().list[i].bounds())) - } - None => Some(display_list.get().list[i].bounds()) + // FIXME(pcwalton): Why are we cloning the display list here?! + let boxes = node.layout_data().boxes.borrow(); + let boxes = boxes.ptr; + match (boxes.display_list.clone(), boxes.range) { + (Some(display_list), Some(range)) => { + let mut rect: Option> = None; + for i in range.eachi() { + rect = match rect { + Some(acc) => { + Some(acc.union(&display_list.get().list[i].bounds())) } + None => Some(display_list.get().list[i].bounds()) } - rect } - _ => { - let mut acc: Option> = None; - for child in node.children() { - let rect = box_for_node(child); - match rect { - None => continue, - Some(rect) => acc = match acc { - Some(acc) => Some(acc.union(&rect)), - None => Some(rect) - } + rect + } + _ => { + let mut acc: Option> = None; + for child in node.children() { + let rect = box_for_node(child); + match rect { + None => continue, + Some(rect) => acc = match acc { + Some(acc) => Some(acc.union(&rect)), + None => Some(rect) } } - acc } + acc } } } @@ -511,25 +514,23 @@ impl LayoutTask { transmute(node) }; - fn boxes_for_node(node: AbstractNode, - boxes: ~[Rect]) -> ~[Rect] { - let boxes = Cell::new(boxes); - do node.read_layout_data |layout_data| { - let mut boxes = boxes.take(); - match (layout_data.boxes.display_list.clone(), layout_data.boxes.range) { - (Some(display_list), Some(range)) => { - for i in range.eachi() { - boxes.push(display_list.get().list[i].bounds()); - } + fn boxes_for_node(node: AbstractNode, mut box_accumulator: ~[Rect]) + -> ~[Rect] { + let boxes = node.layout_data().boxes.borrow(); + let boxes = boxes.ptr; + match (boxes.display_list.clone(), boxes.range) { + (Some(display_list), Some(range)) => { + for i in range.eachi() { + box_accumulator.push(display_list.get().list[i].bounds()); } - _ => { - for child in node.children() { - boxes = boxes_for_node(child, boxes); - } + } + _ => { + for child in node.children() { + box_accumulator = boxes_for_node(child, box_accumulator); } } - boxes } + box_accumulator } let mut boxes = ~[]; diff --git a/servo/src/components/main/layout/util.rs b/servo/src/components/main/layout/util.rs index dd26093b7b4e..3467dc4d876d 100644 --- a/servo/src/components/main/layout/util.rs +++ b/servo/src/components/main/layout/util.rs @@ -3,11 +3,33 @@ use layout::box::{RenderBox, RenderBoxUtils}; + +use extra::arc::Arc; +use gfx::display_list::DisplayList; use script::dom::node::{AbstractNode, LayoutView}; use servo_util::range::Range; - +use servo_util::slot::Slot; +use servo_util::tree::TreeNodeRef; +use std::any::AnyRefExt; use std::iter::Enumerate; use std::vec::VecIterator; +use style::{ComputedValues, PropertyDeclaration}; + + +pub struct DisplayBoxes { + display_list: Option>>>, + range: Option, +} + +impl DisplayBoxes { + pub fn init() -> DisplayBoxes { + DisplayBoxes { + display_list: None, + range: None, + } + } +} + pub struct NodeRange { node: AbstractNode, @@ -16,7 +38,10 @@ pub struct NodeRange { impl NodeRange { pub fn new(node: AbstractNode, range: &Range) -> NodeRange { - NodeRange { node: node, range: (*range).clone() } + NodeRange { + node: node, + range: (*range).clone() + } } } @@ -111,3 +136,51 @@ impl ElementMapping { debug!("----------------------------------"); } } + + +pub struct LayoutData { + + applicable_declarations: Slot<~[Arc<~[PropertyDeclaration]>]>, + + + style: Slot>, + + + restyle_damage: Slot>, + + + + boxes: Slot, +} + +impl LayoutData { + + pub fn new() -> LayoutData { + LayoutData { + applicable_declarations: Slot::init(~[]), + style: Slot::init(None), + restyle_damage: Slot::init(None), + boxes: Slot::init(DisplayBoxes::init()), + } + } +} + + + +fn assert_is_sendable(_: T) {} +fn assert_layout_data_is_sendable() { + assert_is_sendable(LayoutData::new()) +} + + +pub trait LayoutDataAccess { + fn layout_data<'a>(&'a self) -> &'a LayoutData; +} + +impl LayoutDataAccess for AbstractNode { + #[inline(always)] + fn layout_data<'a>(&'a self) -> &'a LayoutData { + self.node().layout_data.as_ref().unwrap().as_ref().unwrap() + } +} + diff --git a/servo/src/components/script/dom/node.rs b/servo/src/components/script/dom/node.rs index 8e9f123b8618..b6e48f3c915a 100644 --- a/servo/src/components/script/dom/node.rs +++ b/servo/src/components/script/dom/node.rs @@ -21,12 +21,8 @@ use dom::text::Text; use std::cast; use std::cast::transmute; use std::unstable::raw::Box; -use extra::arc::Arc; use js::jsapi::{JSObject, JSContext}; -use style::{ComputedValues, PropertyDeclaration}; use servo_util::tree::{TreeNode, TreeNodeRef, TreeNodeRefAsElement}; -use servo_util::range::Range; -use gfx::display_list::DisplayList; @@ -93,7 +89,7 @@ pub struct Node { child_list: Option<@mut NodeList>, /// Layout information. Only the layout task may touch this data. - priv layout_data: LayoutData, + layout_data: Option<~Any>, } /// The different types of nodes. @@ -543,7 +539,7 @@ impl Node { owner_doc: doc, child_list: None, - layout_data: LayoutData::new(), + layout_data: None, } } } @@ -1093,61 +1089,40 @@ impl Reflectable for Node { } - - -pub struct DisplayBoxes { - display_list: Option>>>, - range: Option, -} - - -pub struct LayoutData { +pub trait PostorderNodeTraversal { - applicable_declarations: ~[Arc<~[PropertyDeclaration]>], + fn process(&mut self, node: AbstractNode) -> bool; - style: Option, - - restyle_damage: Option, - - - boxes: DisplayBoxes, -} - -impl LayoutData { - - pub fn new() -> LayoutData { - LayoutData { - applicable_declarations: ~[], - style: None, - restyle_damage: None, - boxes: DisplayBoxes { - display_list: None, - range: None, - }, - } + fn should_prune(&mut self, _node: AbstractNode) -> bool { + false } } - - -fn assert_is_sendable(_: T) {} -fn assert_layout_data_is_sendable() { - assert_is_sendable(LayoutData::new()) -} - impl AbstractNode { - - pub fn read_layout_data(self, blk: &fn(data: &LayoutData) -> R) -> R { - blk(&self.node().layout_data) - } + pub fn traverse_postorder(self, traversal: &mut T) -> bool { + if traversal.should_prune(self) { + return true + } + + let mut opt_kid = self.first_child(); + loop { + match opt_kid { + None => break, + Some(kid) => { + if !kid.traverse_postorder(traversal) { + return false + } + opt_kid = kid.next_sibling() + } + } + } - pub fn write_layout_data(self, blk: &fn(data: &mut LayoutData) -> R) -> R { - blk(&mut self.mut_node().layout_data) + traversal.process(self) } } diff --git a/servo/src/components/script/script.rc b/servo/src/components/script/script.rc index 8c24cc5a9959..a2dee9a69437 100644 --- a/servo/src/components/script/script.rc +++ b/servo/src/components/script/script.rc @@ -14,7 +14,6 @@ #[feature(globs, macro_rules, struct_variant, managed_boxes)]; extern mod geom; -extern mod gfx (name = "gfx"); extern mod hubbub; extern mod js; extern mod servo_net (name = "net");