diff options
Diffstat (limited to 'components/layout')
30 files changed, 335 insertions, 303 deletions
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index ca77107965b..d24261495e1 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -34,9 +34,6 @@ path = "../util" [dependencies.cssparser] git = "https://github.com/servo/rust-cssparser" -[dependencies.encoding] -git = "https://github.com/lifthrasiir/rust-encoding" - [dependencies.geom] git = "https://github.com/servo/rust-geom" @@ -48,3 +45,6 @@ git = "https://github.com/servo/string-cache" [dependencies.string_cache_macros] git = "https://github.com/servo/string-cache" + +[dependencies] +encoding = "0.2" diff --git a/components/layout/block.rs b/components/layout/block.rs index 3f7fd4be823..f91f079f6bf 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -61,7 +61,7 @@ use style::ComputedValues; use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::computed_values::{LengthOrPercentage, box_sizing, display, float}; use style::computed_values::{overflow, position}; -use sync::Arc; +use std::sync::Arc; /// Information specific to floated blocks. #[deriving(Clone, Encodable)] @@ -92,6 +92,7 @@ impl FloatedBlockInfo { } /// The solutions for the block-size-and-margins constraint equation. +#[deriving(Copy)] struct BSizeConstraintSolution { block_start: Au, _block_end: Au, @@ -347,8 +348,8 @@ impl CandidateBSizeIterator { // If the style includes `box-sizing: border-box`, subtract the border and padding. let adjustment_for_box_sizing = match fragment.style.get_box().box_sizing { - box_sizing::border_box => fragment.border_padding.block_start_end(), - box_sizing::content_box => Au(0), + box_sizing::T::border_box => fragment.border_padding.block_start_end(), + box_sizing::T::content_box => Au(0), }; return CandidateBSizeIterator { @@ -1323,12 +1324,12 @@ impl BlockFlow { } match flow::base(kid).flags.float_kind() { - float::none => {} - float::left => { + float::T::none => {} + float::T::left => { inline_size_of_preceding_left_floats = inline_size_of_preceding_left_floats + flow::base(kid).intrinsic_inline_sizes.preferred_inline_size; } - float::right => { + float::T::right => { inline_size_of_preceding_right_floats = inline_size_of_preceding_right_floats + flow::base(kid).intrinsic_inline_sizes.preferred_inline_size; } @@ -1408,14 +1409,16 @@ impl BlockFlow { /// `FormattingContextType`. fn formatting_context_type(&self) -> FormattingContextType { let style = self.fragment.style(); - if style.get_box().float != float::none { + if style.get_box().float != float::T::none { return FormattingContextType::Other } match style.get_box().display { - display::table_cell | display::table_caption | display::inline_block => { + display::T::table_cell | + display::T::table_caption | + display::T::inline_block => { FormattingContextType::Other } - _ if style.get_box().overflow != overflow::visible => FormattingContextType::Block, + _ if style.get_box().overflow != overflow::T::visible => FormattingContextType::Block, _ => FormattingContextType::None, } } @@ -1462,7 +1465,7 @@ impl BlockFlow { } fn is_inline_block(&self) -> bool { - self.fragment.style().get_box().display == display::inline_block + self.fragment.style().get_box().display == display::T::inline_block } /// Computes the content portion (only) of the intrinsic inline sizes of this flow. This is @@ -1527,16 +1530,16 @@ impl Flow for BlockFlow { child_base.intrinsic_inline_sizes.minimum_inline_size); match float_kind { - float::none => { + float::T::none => { computation.content_intrinsic_sizes.preferred_inline_size = max(computation.content_intrinsic_sizes.preferred_inline_size, child_base.intrinsic_inline_sizes.preferred_inline_size); } - float::left => { + float::T::left => { left_float_width = left_float_width + child_base.intrinsic_inline_sizes.preferred_inline_size; } - float::right => { + float::T::right => { right_float_width = right_float_width + child_base.intrinsic_inline_sizes.preferred_inline_size; } @@ -1556,9 +1559,9 @@ impl Flow for BlockFlow { self.base.intrinsic_inline_sizes = computation.finish(); match self.fragment.style().get_box().float { - float::none => {} - float::left => flags.insert(HAS_LEFT_FLOATED_DESCENDANTS), - float::right => flags.insert(HAS_RIGHT_FLOATED_DESCENDANTS), + float::T::none => {} + float::T::left => flags.insert(HAS_LEFT_FLOATED_DESCENDANTS), + float::T::right => flags.insert(HAS_RIGHT_FLOATED_DESCENDANTS), } self.base.flags = flags } @@ -1911,7 +1914,7 @@ impl fmt::Show for BlockFlow { } /// The inputs for the inline-sizes-and-margins constraint equation. -#[deriving(Show)] +#[deriving(Show, Copy)] pub struct ISizeConstraintInput { pub computed_inline_size: MaybeAuto, pub inline_start_margin: MaybeAuto, @@ -1944,7 +1947,7 @@ impl ISizeConstraintInput { } /// The solutions for the inline-size-and-margins constraint equation. -#[deriving(Show)] +#[deriving(Copy, Show)] pub struct ISizeConstraintSolution { pub inline_start: Au, pub inline_end: Au, @@ -2006,11 +2009,12 @@ pub trait ISizeAndMarginsComputer { let style = block.fragment.style(); match (computed_inline_size, style.get_box().box_sizing) { - (MaybeAuto::Specified(size), box_sizing::border_box) => { + (MaybeAuto::Specified(size), box_sizing::T::border_box) => { computed_inline_size = MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end()) } - (MaybeAuto::Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {} + (MaybeAuto::Auto, box_sizing::T::border_box) | + (_, box_sizing::T::content_box) => {} } // The text alignment of a block flow is the text alignment of its box's style. diff --git a/components/layout/construct.rs b/components/layout/construct.rs index c2911b13640..7db6466d48b 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -55,7 +55,7 @@ use std::sync::atomic::Relaxed; use style::computed_values::{caption_side, display, empty_cells, float, list_style_position}; use style::computed_values::{position}; use style::{mod, ComputedValues}; -use sync::Arc; +use std::sync::Arc; use url::Url; /// The results of flow construction for a DOM node. @@ -701,7 +701,7 @@ impl<'a> FlowConstructor<'a> { // `<div style="position:absolute">foo bar baz</div>`. The fragments for `foo`, `bar`, and // `baz` had better not be absolutely positioned! let mut style = (*node.style()).clone(); - if style.get_box().display != display::inline { + if style.get_box().display != display::T::inline { style = Arc::new(style::make_inline(&*style)) } @@ -859,7 +859,7 @@ impl<'a> FlowConstructor<'a> { float_value: float::T) -> ConstructionResult { let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableWrapper); let wrapper_flow = match float_value { - float::none => box TableWrapperFlow::from_node_and_fragment(node, fragment), + float::T::none => box TableWrapperFlow::from_node_and_fragment(node, fragment), _ => { let float_kind = FloatKind::from_property(float_value); box TableWrapperFlow::float_from_node_and_fragment(node, fragment, float_kind) @@ -882,7 +882,7 @@ impl<'a> FlowConstructor<'a> { // value of `caption-side`. self.place_table_caption_under_table_wrapper_on_side(&mut wrapper_flow, node, - caption_side::top); + caption_side::T::top); match construction_result { ConstructionResult::Flow(table_flow, table_abs_descendants) => { @@ -895,7 +895,7 @@ impl<'a> FlowConstructor<'a> { // If the value of `caption-side` is `bottom`, place it now. self.place_table_caption_under_table_wrapper_on_side(&mut wrapper_flow, node, - caption_side::bottom); + caption_side::T::bottom); // The flow is done. wrapper_flow.finish(); @@ -954,10 +954,12 @@ impl<'a> FlowConstructor<'a> { // Determine if the table cell should be hidden. Per CSS 2.1 § 17.6.1.1, this will be true // if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to // `hide`. - let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide && + let hide = node.style().get_inheritedtable().empty_cells == empty_cells::T::hide && node.children().all(|kid| { let position = kid.style().get_box().position; - !kid.is_content() || position == position::absolute || position == position::fixed + !kid.is_content() || + position == position::T::absolute || + position == position::T::fixed }); let flow = box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide) @@ -1003,11 +1005,11 @@ impl<'a> FlowConstructor<'a> { let flow; let initial_fragment; match node.style().get_list().list_style_position { - list_style_position::outside => { + list_style_position::T::outside => { flow = box ListItemFlow::from_node_and_marker(self, node, marker_fragment); initial_fragment = None; } - list_style_position::inside => { + list_style_position::T::inside => { flow = box ListItemFlow::from_node_and_marker(self, node, None); initial_fragment = marker_fragment; } @@ -1117,7 +1119,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // Pseudo-element. let style = node.style(); let display = match node.get_pseudo_element_type() { - PseudoElementType::Normal => display::inline, + PseudoElementType::Normal => display::T::inline, PseudoElementType::Before(display) => display, PseudoElementType::After(display) => display, }; @@ -1126,20 +1128,20 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { Some(NodeTypeId::Element(_)) => { let style = node.style(); let munged_display = if style.get_box()._servo_display_for_hypothetical_box == - display::inline { - display::inline + display::T::inline { + display::T::inline } else { style.get_box().display }; (munged_display, style.get_box().float, style.get_box().position) } - Some(NodeTypeId::Text) => (display::inline, float::none, position::static_), + Some(NodeTypeId::Text) => (display::T::inline, float::T::none, position::T::static_), Some(NodeTypeId::Comment) | Some(NodeTypeId::DocumentType) | Some(NodeTypeId::DocumentFragment) | Some(NodeTypeId::Document) | Some(NodeTypeId::ProcessingInstruction) => { - (display::none, float::none, position::static_) + (display::T::none, float::T::none, position::T::static_) } }; @@ -1149,14 +1151,14 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { match (display, float, positioning) { // `display: none` contributes no flow construction result. Nuke the flow construction // results of children. - (display::none, _, _) => { + (display::T::none, _, _) => { for child in node.children() { drop(child.swap_out_construction_result()) } } // Table items contribute table flow construction results. - (display::table, float_value, _) => { + (display::T::table, float_value, _) => { let construction_result = self.build_flow_for_table_wrapper(node, float_value); node.set_flow_construction_result(construction_result) } @@ -1167,18 +1169,19 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // positioned, but inline we shouldn't try to construct a block // flow here - instead, let it match the inline case // below. - (display::block, _, position::absolute) | (_, _, position::fixed) => { + (display::T::block, _, position::T::absolute) | + (_, _, position::T::fixed) => { node.set_flow_construction_result(self.build_flow_for_nonfloated_block(node)) } // List items contribute their own special flows. - (display::list_item, _, _) => { + (display::T::list_item, _, _) => { node.set_flow_construction_result(self.build_flow_for_list_item(node)) } // Inline items that are absolutely-positioned contribute inline fragment construction // results with a hypothetical fragment. - (display::inline, _, position::absolute) => { + (display::T::inline, _, position::T::absolute) => { let construction_result = self.build_fragment_for_absolutely_positioned_inline(node); node.set_flow_construction_result(construction_result) @@ -1187,50 +1190,51 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // Inline items contribute inline fragment construction results. // // FIXME(pcwalton, #3307): This is not sufficient to handle floated generated content. - (display::inline, float::none, _) => { + (display::T::inline, float::T::none, _) => { let construction_result = self.build_fragments_for_inline(node); node.set_flow_construction_result(construction_result) } // Inline-block items contribute inline fragment construction results. - (display::inline_block, float::none, _) => { + (display::T::inline_block, float::T::none, _) => { let construction_result = self.build_fragment_for_inline_block(node); node.set_flow_construction_result(construction_result) } // Table items contribute table flow construction results. - (display::table_caption, _, _) => { + (display::T::table_caption, _, _) => { let construction_result = self.build_flow_for_table_caption(node); node.set_flow_construction_result(construction_result) } // Table items contribute table flow construction results. - (display::table_column_group, _, _) => { + (display::T::table_column_group, _, _) => { let construction_result = self.build_flow_for_table_colgroup(node); node.set_flow_construction_result(construction_result) } // Table items contribute table flow construction results. - (display::table_column, _, _) => { + (display::T::table_column, _, _) => { let construction_result = self.build_fragments_for_table_column(node); node.set_flow_construction_result(construction_result) } // Table items contribute table flow construction results. - (display::table_row_group, _, _) | (display::table_header_group, _, _) | - (display::table_footer_group, _, _) => { + (display::T::table_row_group, _, _) | + (display::T::table_header_group, _, _) | + (display::T::table_footer_group, _, _) => { let construction_result = self.build_flow_for_table_rowgroup(node); node.set_flow_construction_result(construction_result) } // Table items contribute table flow construction results. - (display::table_row, _, _) => { + (display::T::table_row, _, _) => { let construction_result = self.build_flow_for_table_row(node); node.set_flow_construction_result(construction_result) } // Table items contribute table flow construction results. - (display::table_cell, _, _) => { + (display::T::table_cell, _, _) => { let construction_result = self.build_flow_for_table_cell(node); node.set_flow_construction_result(construction_result) } @@ -1240,7 +1244,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // TODO(pcwalton): Make this only trigger for blocks and handle the other `display` // properties separately. - (_, float::none, _) => { + (_, float::T::none, _) => { node.set_flow_construction_result(self.build_flow_for_nonfloated_block(node)) } diff --git a/components/layout/context.rs b/components/layout/context.rs index 6d04c131b85..7a5b0454ab8 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -15,8 +15,10 @@ use script_traits::UntrustedNodeAddress; use servo_msg::constellation_msg::ConstellationChan; use servo_net::local_image_cache::LocalImageCache; use servo_util::geometry::Au; -use sync::{Arc, Mutex}; +use std::cell::Cell; use std::mem; +use std::ptr; +use std::sync::{Arc, Mutex}; use style::Stylist; use url::Url; @@ -26,25 +28,21 @@ struct LocalLayoutContext { style_sharing_candidate_cache: StyleSharingCandidateCache, } -local_data_key!(local_context_key: *mut LocalLayoutContext) +thread_local!(static local_context_key: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut())) fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext { - let maybe_context = local_context_key.get(); - - let context = match maybe_context { - None => { + local_context_key.with(|ref r| { + if r.get().is_null() { let context = box LocalLayoutContext { font_context: FontContext::new(shared_layout_context.font_cache_task.clone()), applicable_declarations_cache: ApplicableDeclarationsCache::new(), style_sharing_candidate_cache: StyleSharingCandidateCache::new(), }; - local_context_key.replace(Some(unsafe { mem::transmute(context) })); - local_context_key.get().unwrap() - }, - Some(context) => context - }; + r.set(unsafe { mem::transmute(context) }); + } - *context + r.get() + }) } pub struct SharedLayoutContext { diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index e4d6b767c34..e453d36f7ae 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -20,7 +20,7 @@ use std::slice::Items; use string_cache::{Atom, Namespace}; use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode}; use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade}; -use sync::Arc; +use std::sync::Arc; pub struct ApplicableDeclarations { pub normal: SmallVec16<DeclarationBlock>, diff --git a/components/layout/css/node_style.rs b/components/layout/css/node_style.rs index 8b4e1aa08a4..d2cbf029b1a 100644 --- a/components/layout/css/node_style.rs +++ b/components/layout/css/node_style.rs @@ -8,7 +8,7 @@ use wrapper::{PseudoElementType, ThreadSafeLayoutNode}; use std::mem; use style::ComputedValues; -use sync::Arc; +use std::sync::Arc; /// Node mixin providing `style` method that returns a `NodeStyle` pub trait StyledNode { diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 80877ffaaf9..326a688e5df 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -28,15 +28,15 @@ use gfx::display_list::{BorderRadii, BoxShadowDisplayItem, ClippingRegion}; use gfx::display_list::{DisplayItem, DisplayList, DisplayItemMetadata}; use gfx::display_list::{GradientDisplayItem}; use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem}; -use gfx::display_list::{SidewaysLeft}; -use gfx::display_list::{SidewaysRight, SolidColorDisplayItem}; -use gfx::display_list::{StackingContext, TextDisplayItem, Upright}; +use gfx::display_list::TextOrientation; +use gfx::display_list::{SolidColorDisplayItem}; +use gfx::display_list::{StackingContext, TextDisplayItem}; use gfx::paint_task::PaintLayer; -use servo_msg::compositor_msg::{FixedPosition, Scrollable}; +use servo_msg::compositor_msg::ScrollPolicy; use servo_msg::constellation_msg::Msg as ConstellationMsg; use servo_msg::constellation_msg::ConstellationChan; use servo_net::image::holder::ImageHolder; -use servo_util::cursor::{DefaultCursor, TextCursor, VerticalTextCursor}; +use servo_util::cursor::Cursor; use servo_util::geometry::{mod, Au}; use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize}; use servo_util::opts; @@ -48,7 +48,7 @@ use style::computed_values::{background_attachment, background_repeat, border_st use style::computed_values::{position, visibility}; use style::style_structs::Border; use style::{ComputedValues, RGBA}; -use sync::Arc; +use std::sync::Arc; use url::Url; /// The results of display list building for a single flow. @@ -253,7 +253,7 @@ impl FragmentDisplayListBuilding for Fragment { base: BaseDisplayItem::new(*absolute_bounds, DisplayItemMetadata::new(self.node, style, - DefaultCursor), + Cursor::DefaultCursor), clip.clone()), color: background_color.to_gfx_color(), }), level); @@ -319,10 +319,10 @@ impl FragmentDisplayListBuilding for Fragment { // Use background-attachment to get the initial virtual origin let (virtual_origin_x, virtual_origin_y) = match background.background_attachment { - background_attachment::scroll => { + background_attachment::T::scroll => { (absolute_bounds.origin.x, absolute_bounds.origin.y) } - background_attachment::fixed => { + background_attachment::T::fixed => { (Au(0), Au(0)) } }; @@ -338,25 +338,25 @@ impl FragmentDisplayListBuilding for Fragment { // Adjust origin and size based on background-repeat match background.background_repeat { - background_repeat::no_repeat => { + background_repeat::T::no_repeat => { bounds.origin.x = abs_x; bounds.origin.y = abs_y; bounds.size.width = image_width; bounds.size.height = image_height; } - background_repeat::repeat_x => { + background_repeat::T::repeat_x => { bounds.origin.y = abs_y; bounds.size.height = image_height; ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width, abs_x, image.width); } - background_repeat::repeat_y => { + background_repeat::T::repeat_y => { bounds.origin.x = abs_x; bounds.size.width = image_width; ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height, abs_y, image.height); } - background_repeat::repeat => { + background_repeat::T::repeat => { ImageFragmentInfo::tile_image(&mut bounds.origin.x, &mut bounds.size.width, abs_x, image.width); ImageFragmentInfo::tile_image(&mut bounds.origin.y, &mut bounds.size.height, @@ -367,7 +367,7 @@ impl FragmentDisplayListBuilding for Fragment { // Create the image display item. display_list.push(DisplayItem::ImageClass(box ImageDisplayItem { base: BaseDisplayItem::new(bounds, - DisplayItemMetadata::new(self.node, style, DefaultCursor), + DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor), clip), image: image.clone(), stretch_size: Size2D(Au::from_px(image.width as int), @@ -477,7 +477,7 @@ impl FragmentDisplayListBuilding for Fragment { let gradient_display_item = DisplayItem::GradientClass(box GradientDisplayItem { base: BaseDisplayItem::new(*absolute_bounds, - DisplayItemMetadata::new(self.node, style, DefaultCursor), + DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor), clip), start_point: center - delta, end_point: center + delta, @@ -505,7 +505,7 @@ impl FragmentDisplayListBuilding for Fragment { base: BaseDisplayItem::new(bounds, DisplayItemMetadata::new(self.node, style, - DefaultCursor), + Cursor::DefaultCursor), (*clip).clone()), box_bounds: *absolute_bounds, color: style.resolve_color(box_shadow.color).to_gfx_color(), @@ -536,7 +536,7 @@ impl FragmentDisplayListBuilding for Fragment { // Append the border to the display list. display_list.push(DisplayItem::BorderClass(box BorderDisplayItem { base: BaseDisplayItem::new(*abs_bounds, - DisplayItemMetadata::new(self.node, style, DefaultCursor), + DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor), (*clip).clone()), border_widths: border.to_physical(style.writing_mode), color: SideOffsets2D::new(top_color.to_gfx_color(), @@ -562,7 +562,7 @@ impl FragmentDisplayListBuilding for Fragment { } let outline_style = style.get_outline().outline_style; - if outline_style == border_style::none { + if outline_style == border_style::T::none { return } @@ -578,7 +578,7 @@ impl FragmentDisplayListBuilding for Fragment { let color = style.resolve_color(style.get_outline().outline_color).to_gfx_color(); display_list.outlines.push_back(DisplayItem::BorderClass(box BorderDisplayItem { base: BaseDisplayItem::new(bounds, - DisplayItemMetadata::new(self.node, style, DefaultCursor), + DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor), (*clip).clone()), border_widths: SideOffsets2D::new_all_same(width), color: SideOffsets2D::new_all_same(color), @@ -600,11 +600,11 @@ impl FragmentDisplayListBuilding for Fragment { // Compute the text fragment bounds and draw a border surrounding them. display_list.content.push_back(DisplayItem::BorderClass(box BorderDisplayItem { base: BaseDisplayItem::new(*stacking_relative_border_box, - DisplayItemMetadata::new(self.node, style, DefaultCursor), + DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor), (*clip).clone()), border_widths: SideOffsets2D::new_all_same(Au::from_px(1)), color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)), - style: SideOffsets2D::new_all_same(border_style::solid), + style: SideOffsets2D::new_all_same(border_style::T::solid), radius: Default::default(), })); @@ -618,10 +618,10 @@ impl FragmentDisplayListBuilding for Fragment { let line_display_item = box LineDisplayItem { base: BaseDisplayItem::new(baseline, - DisplayItemMetadata::new(self.node, style, DefaultCursor), + DisplayItemMetadata::new(self.node, style, Cursor::DefaultCursor), (*clip).clone()), color: color::rgb(0, 200, 0), - style: border_style::dashed, + style: border_style::T::dashed, }; display_list.content.push_back(DisplayItem::LineClass(line_display_item)); } @@ -635,11 +635,11 @@ impl FragmentDisplayListBuilding for Fragment { base: BaseDisplayItem::new(*stacking_relative_border_box, DisplayItemMetadata::new(self.node, &*self.style, - DefaultCursor), + Cursor::DefaultCursor), (*clip).clone()), border_widths: SideOffsets2D::new_all_same(Au::from_px(1)), color: SideOffsets2D::new_all_same(color::rgb(0, 0, 200)), - style: SideOffsets2D::new_all_same(border_style::solid), + style: SideOffsets2D::new_all_same(border_style::T::solid), radius: Default::default(), })); } @@ -651,7 +651,7 @@ impl FragmentDisplayListBuilding for Fragment { // Account for `clip` per CSS 2.1 § 11.1.2. let style_clip_rect = match (self.style().get_box().position, self.style().get_effects().clip) { - (position::absolute, Some(style_clip_rect)) => style_clip_rect, + (position::T::absolute, Some(style_clip_rect)) => style_clip_rect, _ => return (*parent_clip).clone(), }; @@ -686,7 +686,7 @@ impl FragmentDisplayListBuilding for Fragment { stacking_relative_flow_origin, self); - if self.style().get_inheritedbox().visibility != visibility::visible { + if self.style().get_inheritedbox().visibility != visibility::T::visible { return } @@ -848,7 +848,7 @@ impl FragmentDisplayListBuilding for Fragment { base: BaseDisplayItem::new(stacking_relative_content_box, DisplayItemMetadata::new(self.node, &*self.style, - DefaultCursor), + Cursor::DefaultCursor), (*clip).clone()), image: image.clone(), stretch_size: stacking_relative_content_box.size, @@ -899,7 +899,7 @@ impl FragmentDisplayListBuilding for Fragment { // Only clip if `overflow` tells us to. match self.style.get_box().overflow { - overflow::hidden | overflow::auto | overflow::scroll => { + overflow::T::hidden | overflow::T::auto | overflow::T::scroll => { // Create a new clip rect. current_clip.intersect_rect(stacking_relative_border_box) } @@ -916,12 +916,12 @@ impl FragmentDisplayListBuilding for Fragment { // Determine the orientation and cursor to use. let (orientation, cursor) = if self.style.writing_mode.is_vertical() { if self.style.writing_mode.is_sideways_left() { - (SidewaysLeft, VerticalTextCursor) + (TextOrientation::SidewaysLeft, Cursor::VerticalTextCursor) } else { - (SidewaysRight, VerticalTextCursor) + (TextOrientation::SidewaysRight, Cursor::VerticalTextCursor) } } else { - (Upright, TextCursor) + (TextOrientation::Upright, Cursor::TextCursor) }; // Compute location of the baseline. @@ -995,7 +995,7 @@ impl FragmentDisplayListBuilding for Fragment { let stacking_relative_box = stacking_relative_box.to_physical(self.style.writing_mode, container_size); - let metadata = DisplayItemMetadata::new(self.node, &*self.style, DefaultCursor); + let metadata = DisplayItemMetadata::new(self.node, &*self.style, Cursor::DefaultCursor); display_list.content.push_back(DisplayItem::SolidColorClass(box SolidColorDisplayItem { base: BaseDisplayItem::new(stacking_relative_box, metadata, (*clip).clone()), color: color.to_gfx_color(), @@ -1083,9 +1083,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // If we got here, then we need a new layer. let scroll_policy = if self.is_fixed() { - FixedPosition + ScrollPolicy::FixedPosition } else { - Scrollable + ScrollPolicy::Scrollable }; let transparent = color::rgba(1.0, 1.0, 1.0, 0.0); @@ -1163,7 +1163,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow { fn build_display_list_for_inline(&mut self, layout_context: &LayoutContext) { // TODO(#228): Once we form lines 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!("Flow: building display list for {:u} inline fragments", self.fragments.len()); + debug!("Flow: building display list for {} inline fragments", self.fragments.len()); let mut display_list = box DisplayList::new(); for fragment in self.fragments.fragments.iter_mut() { @@ -1227,6 +1227,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { } // A helper data structure for gradients. +#[deriving(Copy)] struct StopRun { start_offset: f32, end_offset: f32, @@ -1250,7 +1251,7 @@ fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32 } /// "Steps" as defined by CSS 2.1 § E.2. -#[deriving(Clone, PartialEq, Show)] +#[deriving(Clone, PartialEq, Show, Copy)] pub enum StackingLevel { /// The border and backgrounds for the root of this stacking context: steps 1 and 2. BackgroundAndBorders, diff --git a/components/layout/floats.rs b/components/layout/floats.rs index ca840bc5374..5d82014f779 100644 --- a/components/layout/floats.rs +++ b/components/layout/floats.rs @@ -12,7 +12,7 @@ use std::fmt; use style::computed_values::float; /// The kind of float: left or right. -#[deriving(Clone, Encodable, Show)] +#[deriving(Clone, Encodable, Show, Copy)] pub enum FloatKind { Left, Right @@ -21,14 +21,15 @@ pub enum FloatKind { impl FloatKind { pub fn from_property(property: float::T) -> FloatKind { match property { - float::none => panic!("can't create a float type from an unfloated property"), - float::left => FloatKind::Left, - float::right => FloatKind::Right, + float::T::none => panic!("can't create a float type from an unfloated property"), + float::T::left => FloatKind::Left, + float::T::right => FloatKind::Right, } } } /// The kind of clearance: left, right, or both. +#[deriving(Copy)] pub enum ClearType { Left, Right, @@ -36,7 +37,7 @@ pub enum ClearType { } /// Information about a single float. -#[deriving(Clone)] +#[deriving(Clone, Copy)] struct Float { /// The boundaries of this float. bounds: LogicalRect<Au>, diff --git a/components/layout/flow.rs b/components/layout/flow.rs index d252a93269b..bffdb756505 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -60,7 +60,7 @@ use std::sync::atomic::{AtomicUint, SeqCst}; use std::slice::MutItems; use style::computed_values::{clear, empty_cells, float, position, text_align}; use style::ComputedValues; -use sync::Arc; +use std::sync::Arc; /// Virtual methods that make up a float context. /// @@ -255,12 +255,12 @@ pub trait Flow: fmt::Show + ToString + Sync { /// The 'position' property of this flow. fn positioning(&self) -> position::T { - position::static_ + position::T::static_ } /// Return true if this flow has position 'fixed'. fn is_fixed(&self) -> bool { - self.positioning() == position::fixed + self.positioning() == position::T::fixed } fn is_positioned(&self) -> bool { @@ -268,7 +268,7 @@ pub trait Flow: fmt::Show + ToString + Sync { } fn is_relatively_positioned(&self) -> bool { - self.positioning() == position::relative + self.positioning() == position::T::relative } /// Return true if this is the root of an absolute flow tree. @@ -471,6 +471,7 @@ pub trait PostorderFlowTraversal { bitflags! { #[doc = "Flags used in flows."] + #[deriving(Copy)] flags FlowFlags: u16 { // floated descendants flags #[doc = "Whether this flow has descendants that float left in the same block formatting"] @@ -575,11 +576,11 @@ impl FlowFlags { #[inline] pub fn float_kind(&self) -> float::T { if self.contains(FLOATS_LEFT) { - float::left + float::T::left } else if self.contains(FLOATS_RIGHT) { - float::right + float::T::right } else { - float::none + float::T::none } } @@ -658,8 +659,8 @@ pub struct DescendantIter<'a> { iter: MutItems<'a, FlowRef>, } -impl<'a> Iterator<&'a mut Flow + 'a> for DescendantIter<'a> { - fn next(&mut self) -> Option<&'a mut Flow + 'a> { +impl<'a> Iterator<&'a mut (Flow + 'a)> for DescendantIter<'a> { + fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { self.iter.next().map(|flow| &mut **flow) } } @@ -668,7 +669,7 @@ pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, MutItems<'a, Au>>; /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be /// confused with absolutely-positioned flows). -#[deriving(Encodable)] +#[deriving(Encodable, Copy)] pub struct AbsolutePositionInfo { /// The size of the containing block for relatively-positioned descendants. pub relative_containing_block_size: LogicalSize<Au>, @@ -863,7 +864,7 @@ impl BaseFlow { Some(node) => { let node_style = node.style(); match node_style.get_box().position { - position::absolute | position::fixed => { + position::T::absolute | position::T::fixed => { flags.insert(IS_ABSOLUTELY_POSITIONED) } _ => {} @@ -871,17 +872,17 @@ impl BaseFlow { if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary { match node_style.get_box().float { - float::none => {} - float::left => flags.insert(FLOATS_LEFT), - float::right => flags.insert(FLOATS_RIGHT), + float::T::none => {} + float::T::left => flags.insert(FLOATS_LEFT), + float::T::right => flags.insert(FLOATS_RIGHT), } } match node_style.get_box().clear { - clear::none => {} - clear::left => flags.insert(CLEARS_LEFT), - clear::right => flags.insert(CLEARS_RIGHT), - clear::both => { + clear::T::none => {} + clear::T::left => flags.insert(CLEARS_LEFT), + clear::T::right => flags.insert(CLEARS_RIGHT), + clear::T::both => { flags.insert(CLEARS_LEFT); flags.insert(CLEARS_RIGHT); } @@ -962,7 +963,7 @@ impl BaseFlow { } } -impl<'a> ImmutableFlowUtils for &'a Flow + 'a { +impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) { /// Returns true if this flow is a block flow. fn is_block_like(self) -> bool { match self.class() { @@ -1064,7 +1065,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a { let fragment = Fragment::new_anonymous_from_specific_info(node, SpecificFragmentInfo::TableCell); - let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide; + let hide = node.style().get_inheritedtable().empty_cells == empty_cells::T::hide; box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide) as Box<Flow> }, @@ -1138,7 +1139,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a { } } -impl<'a> MutableFlowUtils for &'a mut Flow + 'a { +impl<'a> MutableFlowUtils for &'a mut (Flow + 'a) { /// Traverses the tree in preorder. fn traverse_preorder<T:PreorderFlowTraversal>(self, traversal: &T) { if traversal.should_process(self) { diff --git a/components/layout/flow_list.rs b/components/layout/flow_list.rs index a4b2abe0eb3..c3300e6ab79 100644 --- a/components/layout/flow_list.rs +++ b/components/layout/flow_list.rs @@ -105,9 +105,9 @@ impl FlowList { } } -impl<'a> Iterator<&'a Flow + 'a> for FlowListIterator<'a> { +impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> { #[inline] - fn next(&mut self) -> Option<&'a Flow + 'a> { + fn next(&mut self) -> Option<&'a (Flow + 'a)> { self.it.next().map(|x| x.deref()) } @@ -117,9 +117,9 @@ impl<'a> Iterator<&'a Flow + 'a> for FlowListIterator<'a> { } } -impl<'a> Iterator<&'a mut Flow + 'a> for MutFlowListIterator<'a> { +impl<'a> Iterator<&'a mut (Flow + 'a)> for MutFlowListIterator<'a> { #[inline] - fn next(&mut self) -> Option<&'a mut Flow + 'a> { + fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { self.it.next().map(|x| x.deref_mut()) } diff --git a/components/layout/flow_ref.rs b/components/layout/flow_ref.rs index e46c42d4844..67f306d4508 100644 --- a/components/layout/flow_ref.rs +++ b/components/layout/flow_ref.rs @@ -34,17 +34,17 @@ impl FlowRef { } impl<'a> Deref<Flow + 'a> for FlowRef { - fn deref(&self) -> &Flow + 'a { + fn deref(&self) -> &(Flow + 'a) { unsafe { - mem::transmute_copy::<raw::TraitObject, &Flow + 'a>(&self.object) + mem::transmute_copy::<raw::TraitObject, &(Flow + 'a)>(&self.object) } } } impl<'a> DerefMut<Flow + 'a> for FlowRef { - fn deref_mut<'a>(&mut self) -> &mut Flow + 'a { + fn deref_mut<'a>(&mut self) -> &mut (Flow + 'a) { unsafe { - mem::transmute_copy::<raw::TraitObject, &mut Flow + 'a>(&self.object) + mem::transmute_copy::<raw::TraitObject, &mut (Flow + 'a)>(&self.object) } } } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index cfc2ab8b1a5..bf8ae12c10f 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -45,7 +45,7 @@ use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::computed_values::{LengthOrPercentageOrNone}; use style::computed_values::{clear, overflow_wrap, position, text_align}; use style::computed_values::{text_decoration, vertical_align, white_space}; -use sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex}; use url::Url; /// Fragments (`struct Fragment`) are the leaves of the layout tree. They cannot position @@ -398,7 +398,7 @@ impl ScannedTextFragmentInfo { /// Describes how to split a fragment. This is used during line breaking as part of the return /// value of `find_split_info_for_inline_size()`. -#[deriving(Show)] +#[deriving(Show, Clone)] pub struct SplitInfo { // TODO(bjz): this should only need to be a single character index, but both values are // currently needed for splitting in the `inline::try_append_*` functions. @@ -455,7 +455,7 @@ impl UnscannedTextFragmentInfo { } /// A fragment that represents a table column. -#[deriving(Clone)] +#[deriving(Copy, Clone)] pub struct TableColumnFragmentInfo { /// the number of columns a <col> element should span pub span: int, @@ -877,7 +877,7 @@ impl Fragment { } // Go over the ancestor fragments and add all relative offsets (if any). - let mut rel_pos = if self.style().get_box().position == position::relative { + let mut rel_pos = if self.style().get_box().position == position::T::relative { from_style(self.style(), containing_block_size) } else { LogicalSize::zero(self.style.writing_mode) @@ -887,7 +887,7 @@ impl Fragment { None => {} Some(ref inline_fragment_context) => { for style in inline_fragment_context.styles.iter() { - if style.get_box().position == position::relative { + if style.get_box().position == position::T::relative { rel_pos = rel_pos + from_style(&**style, containing_block_size); } } @@ -903,10 +903,10 @@ impl Fragment { pub fn clear(&self) -> Option<ClearType> { let style = self.style(); match style.get_box().clear { - clear::none => None, - clear::left => Some(ClearType::Left), - clear::right => Some(ClearType::Right), - clear::both => Some(ClearType::Both), + clear::T::none => None, + clear::T::left => Some(ClearType::Left), + clear::T::right => Some(ClearType::Right), + clear::T::both => Some(ClearType::Both), } } @@ -1152,7 +1152,7 @@ impl Fragment { let mut flags = SplitOptions::empty(); if starts_line { flags.insert(STARTS_LINE); - if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::break_word { + if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::T::break_word { flags.insert(RETRY_AT_CHARACTER_BOUNDARIES) } } @@ -1279,8 +1279,8 @@ impl Fragment { /// whitespace that should be stripped. pub fn is_ignorable_whitespace(&self) -> bool { match self.white_space() { - white_space::pre => return false, - white_space::normal | white_space::nowrap => {} + white_space::T::pre => return false, + white_space::T::normal | white_space::T::nowrap => {} } match self.specific { SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => { @@ -1616,12 +1616,12 @@ impl Fragment { return true } match self.style().get_box().position { - position::absolute | position::fixed => { + position::T::absolute | position::T::fixed => { // FIXME(pcwalton): This should only establish a new stacking context when // `z-index` is not `auto`. But this matches what we did before. true } - position::relative | position::static_ => { + position::T::relative | position::T::static_ => { // FIXME(pcwalton): `position: relative` establishes a new stacking context if // `z-index` is not `auto`. But this matches what we did before. false diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index bf2fcacf66d..6949063d41b 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -12,6 +12,7 @@ use style::ComputedValues; bitflags! { #[doc = "Individual layout actions that may be necessary after restyling."] + #[deriving(Copy)] flags RestyleDamage: u8 { #[doc = "Repaint the node itself."] #[doc = "Currently unused; need to decide how this propagates."] @@ -87,7 +88,7 @@ impl RestyleDamage { } impl fmt::Show for RestyleDamage { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::FormatError> { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { let mut first_elem = true; let to_iter = @@ -181,7 +182,7 @@ pub trait LayoutDamageComputation { fn reflow_entire_document(self); } -impl<'a> LayoutDamageComputation for &'a mut Flow+'a { +impl<'a> LayoutDamageComputation for &'a mut (Flow + 'a) { fn compute_layout_damage(self) -> SpecialRestyleDamage { let mut special_damage = SpecialRestyleDamage::empty(); let is_absolutely_positioned = flow::base(self).flags.contains(IS_ABSOLUTELY_POSITIONED); @@ -203,7 +204,7 @@ impl<'a> LayoutDamageComputation for &'a mut Flow+'a { } let self_base = flow::base(self); - if self_base.flags.float_kind() != float::none && + if self_base.flags.float_kind() != float::T::none && self_base.restyle_damage.intersects(REFLOW) { special_damage.insert(REFLOW_ENTIRE_DOCUMENT); } diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 0a2234bfa8b..67fc65b21e7 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -34,7 +34,7 @@ use std::mem; use std::u16; use style::computed_values::{text_align, vertical_align, white_space}; use style::ComputedValues; -use sync::Arc; +use std::sync::Arc; // From gfxFontConstants.h in Firefox static FONT_SUBSCRIPT_OFFSET_RATIO: f64 = 0.20; @@ -65,7 +65,7 @@ static FONT_SUPERSCRIPT_OFFSET_RATIO: f64 = 0.34; /// with a float or a horizontal wall of the containing block. The block-start /// inline-start corner of the green zone is the same as that of the line, but /// the green zone can be taller and wider than the line itself. -#[deriving(Encodable, Show)] +#[deriving(Encodable, Show, Copy)] pub struct Line { /// A range of line indices that describe line breaks. /// @@ -267,14 +267,14 @@ impl LineBreaker { // Set up our reflow flags. let flags = match fragment.style().get_inheritedtext().white_space { - white_space::normal => InlineReflowFlags::empty(), - white_space::pre | white_space::nowrap => NO_WRAP_INLINE_REFLOW_FLAG, + white_space::T::normal => InlineReflowFlags::empty(), + white_space::T::pre | white_space::T::nowrap => NO_WRAP_INLINE_REFLOW_FLAG, }; // Try to append the fragment, and commit the line (so we can try again with the next // line) if we couldn't. match fragment.style().get_inheritedtext().white_space { - white_space::normal | white_space::nowrap => { + white_space::T::normal | white_space::T::nowrap => { if !self.append_fragment_to_line_if_possible(fragment, flow, layout_context, @@ -282,7 +282,7 @@ impl LineBreaker { self.flush_current_line() } } - white_space::pre => { + white_space::T::pre => { // FIXME(pcwalton): Surely we can unify // `append_fragment_to_line_if_possible` and // `try_append_to_line_by_new_line` by adding another bit in the reflow @@ -602,8 +602,8 @@ impl LineBreaker { fragment.border_box.size.block); fragment.transform(size, info) }; - (split_result.inline_start.map(|x| split_fragment(x)), - split_result.inline_end.map(|x| split_fragment(x))) + (split_result.inline_start.as_ref().map(|x| split_fragment(x.clone())), + split_result.inline_end.as_ref().map(|x| split_fragment(x.clone()))) } }; @@ -769,53 +769,53 @@ impl InlineFlow { layout_context: &LayoutContext) -> (Au, bool) { match fragment.vertical_align() { - vertical_align::baseline => (-ascent, false), - vertical_align::middle => { + vertical_align::T::baseline => (-ascent, false), + vertical_align::T::middle => { // TODO: x-height value should be used from font info. // TODO: The code below passes our current reftests but doesn't work in all // situations. Add vertical align reftests and fix this. (-ascent, false) }, - vertical_align::sub => { + vertical_align::T::sub => { let sub_offset = (parent_text_block_start + parent_text_block_end) .scale_by(FONT_SUBSCRIPT_OFFSET_RATIO); (sub_offset - ascent, false) }, - vertical_align::super_ => { + vertical_align::T::super_ => { let super_offset = (parent_text_block_start + parent_text_block_end) .scale_by(FONT_SUPERSCRIPT_OFFSET_RATIO); (-super_offset - ascent, false) }, - vertical_align::text_top => { + vertical_align::T::text_top => { let fragment_block_size = *block_size_above_baseline + *depth_below_baseline; let prev_depth_below_baseline = *depth_below_baseline; *block_size_above_baseline = parent_text_block_start; *depth_below_baseline = fragment_block_size - *block_size_above_baseline; (*depth_below_baseline - prev_depth_below_baseline - ascent, false) }, - vertical_align::text_bottom => { + vertical_align::T::text_bottom => { let fragment_block_size = *block_size_above_baseline + *depth_below_baseline; let prev_depth_below_baseline = *depth_below_baseline; *depth_below_baseline = parent_text_block_end; *block_size_above_baseline = fragment_block_size - *depth_below_baseline; (*depth_below_baseline - prev_depth_below_baseline - ascent, false) }, - vertical_align::top => { + vertical_align::T::top => { *largest_block_size_for_top_fragments = max(*largest_block_size_for_top_fragments, *block_size_above_baseline + *depth_below_baseline); let offset_top = *block_size_above_baseline - ascent; (offset_top, true) }, - vertical_align::bottom => { + vertical_align::T::bottom => { *largest_block_size_for_bottom_fragments = max(*largest_block_size_for_bottom_fragments, *block_size_above_baseline + *depth_below_baseline); let offset_bottom = -(*depth_below_baseline + ascent); (offset_bottom, true) }, - vertical_align::Length(length) => (-(length + ascent), false), - vertical_align::Percentage(p) => { + vertical_align::T::Length(length) => (-(length + ascent), false), + vertical_align::T::Percentage(p) => { let line_height = fragment.calculate_line_height(layout_context); let percent_offset = line_height.scale_by(p); (-(percent_offset + ascent), false) @@ -838,9 +838,9 @@ impl InlineFlow { // coordinates. // // TODO(burg, issue #213): Implement `text-align: justify`. - text_align::left | text_align::justify => Au(0), - text_align::center => slack_inline_size.scale_by(0.5), - text_align::right => slack_inline_size, + text_align::T::left | text_align::T::justify => Au(0), + text_align::T::center => slack_inline_size.scale_by(0.5), + text_align::T::right => slack_inline_size, }; for fragment_index in range(line.range.begin(), line.range.end()) { @@ -866,11 +866,11 @@ impl InlineFlow { for fragment_index in range(line.range.begin(), line.range.end()) { let fragment = fragments.get_mut(fragment_index.to_uint()); match fragment.vertical_align() { - vertical_align::top => { + vertical_align::T::top => { fragment.border_box.start.b = fragment.border_box.start.b + line_distance_from_flow_block_start } - vertical_align::bottom => { + vertical_align::T::bottom => { fragment.border_box.start.b = fragment.border_box.start.b + line_distance_from_flow_block_start + baseline_distance_from_block_start + largest_depth_below_baseline diff --git a/components/layout/layout_debug.rs b/components/layout/layout_debug.rs index a70dca58840..f16a18e1dfb 100644 --- a/components/layout/layout_debug.rs +++ b/components/layout/layout_debug.rs @@ -14,7 +14,7 @@ use std::cell::RefCell; use std::io::File; use std::sync::atomic::{AtomicUint, SeqCst, INIT_ATOMIC_UINT}; -local_data_key!(state_key: RefCell<State>) +thread_local!(static state_key: RefCell<Option<State>> = RefCell::new(None)) static mut DEBUG_ID_COUNTER: AtomicUint = INIT_ATOMIC_UINT; @@ -59,16 +59,16 @@ struct State { /// will be output at the beginning and end of this scope. impl Scope { pub fn new(name: String) -> Scope { - let maybe_refcell = state_key.get(); - match maybe_refcell { - Some(refcell) => { - let mut state = refcell.borrow_mut(); - let flow_trace = json::encode(&flow::base(state.flow_root.deref())); - let data = box ScopeData::new(name, flow_trace); - state.scope_stack.push(data); + state_key.with(|ref r| { + match &mut *r.borrow_mut() { + &Some(ref mut state) => { + let flow_trace = json::encode(&flow::base(state.flow_root.deref())); + let data = box ScopeData::new(name.clone(), flow_trace); + state.scope_stack.push(data); + } + &None => {} } - None => {} - } + }); Scope } } @@ -76,17 +76,17 @@ impl Scope { #[cfg(not(ndebug))] impl Drop for Scope { fn drop(&mut self) { - let maybe_refcell = state_key.get(); - match maybe_refcell { - Some(refcell) => { - let mut state = refcell.borrow_mut(); - let mut current_scope = state.scope_stack.pop().unwrap(); - current_scope.post = json::encode(&flow::base(state.flow_root.deref())); - let previous_scope = state.scope_stack.last_mut().unwrap(); - previous_scope.children.push(current_scope); + state_key.with(|ref r| { + match &mut *r.borrow_mut() { + &Some(ref mut state) => { + let mut current_scope = state.scope_stack.pop().unwrap(); + current_scope.post = json::encode(&flow::base(state.flow_root.deref())); + let previous_scope = state.scope_stack.last_mut().unwrap(); + previous_scope.children.push(current_scope); + } + &None => {} } - None => {} - } + }); } } @@ -100,22 +100,23 @@ pub fn generate_unique_debug_id() -> u16 { /// Begin a layout debug trace. If this has not been called, /// creating debug scopes has no effect. pub fn begin_trace(flow_root: FlowRef) { - assert!(state_key.get().is_none()); - - let flow_trace = json::encode(&flow::base(flow_root.deref())); - let state = State { - scope_stack: vec![box ScopeData::new("root".into_string(), flow_trace)], - flow_root: flow_root, - }; - state_key.replace(Some(RefCell::new(state))); + assert!(state_key.with(|ref r| r.borrow().is_none())); + + state_key.with(|ref r| { + let flow_trace = json::encode(&flow::base(flow_root.deref())); + let state = State { + scope_stack: vec![box ScopeData::new("root".into_string(), flow_trace)], + flow_root: flow_root.clone(), + }; + *r.borrow_mut() = Some(state); + }); } /// End the debug layout trace. This will write the layout /// trace to disk in the current directory. The output /// file can then be viewed with an external tool. pub fn end_trace() { - let task_state_cell = state_key.replace(None).unwrap(); - let mut task_state = task_state_cell.borrow_mut(); + let mut task_state = state_key.with(|ref r| r.borrow_mut().take().unwrap()); assert!(task_state.scope_stack.len() == 1); let mut root_scope = task_state.scope_stack.pop().unwrap(); root_scope.post = json::encode(&flow::base(task_state.flow_root.deref())); diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index e64ea0f1d22..48c1bb10496 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -30,27 +30,27 @@ use gfx::display_list::{StackingContext}; use gfx::font_cache_task::FontCacheTask; use gfx::paint_task::{PaintChan, PaintLayer}; use gfx::paint_task::Msg as PaintMsg; -use layout_traits::{mod, LayoutControlMsg, LayoutTaskFactory}; +use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; use script::dom::bindings::js::JS; use script::dom::node::{LayoutDataRef, Node, NodeTypeId}; use script::dom::element::ElementTypeId; use script::dom::htmlelement::HTMLElementTypeId; use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse}; -use script::layout_interface::{ContentBoxesQuery, ContentBoxQuery}; +use script::layout_interface::ReflowQueryType; use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC}; -use script::layout_interface::{MouseOverResponse, Msg, NoQuery}; +use script::layout_interface::{MouseOverResponse, Msg}; use script::layout_interface::{Reflow, ReflowGoal, ScriptLayoutChan, TrustedNodeAddress}; -use script_traits::{ConstellationControlMsg, ReflowEvent, OpaqueScriptLayoutChannel}; +use script_traits::{ConstellationControlMsg, CompositorEvent, OpaqueScriptLayoutChannel}; use script_traits::{ScriptControlChan, UntrustedNodeAddress}; -use servo_msg::compositor_msg::Scrollable; +use servo_msg::compositor_msg::ScrollPolicy; use servo_msg::constellation_msg::Msg as ConstellationMsg; use servo_msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType}; use servo_msg::constellation_msg::PipelineId; use servo_net::image_cache_task::{ImageCacheTask, ImageResponseMsg}; use servo_net::local_image_cache::{ImageResponder, LocalImageCache}; use servo_net::resource_task::{ResourceTask, load_bytes_iter}; -use servo_util::cursor::DefaultCursor; +use servo_util::cursor::Cursor; use servo_util::geometry::Au; use servo_util::logical_geometry::LogicalPoint; use servo_util::opts; @@ -66,7 +66,7 @@ use std::mem; use std::ptr; use style::{StylesheetOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules}; use style::{MediaType, Device}; -use sync::{Arc, Mutex, MutexGuard}; +use std::sync::{Arc, Mutex, MutexGuard}; use url::Url; /// Mutable data belonging to the LayoutTask. @@ -161,7 +161,8 @@ impl ImageResponder<UntrustedNodeAddress> for LayoutImageResponder { debug!("Dirtying {:x}", node_address as uint); let mut nodes = SmallVec1::new(); nodes.vec_push(node_address); - drop(chan.send_opt(ConstellationControlMsg::SendEvent(id.clone(), ReflowEvent(nodes)))) + drop(chan.send_opt(ConstellationControlMsg::SendEvent( + id.clone(), CompositorEvent::ReflowEvent(nodes)))) }; f } @@ -346,7 +347,7 @@ impl LayoutTask { match port_to_read { PortToRead::Pipeline => { match self.pipeline_port.recv() { - layout_traits::ExitNowMsg(exit_type) => { + LayoutControlMsg::ExitNowMsg(exit_type) => { self.handle_script_request(Msg::ExitNow(exit_type), possibly_locked_rw_data) } } @@ -690,7 +691,7 @@ impl LayoutTask { .add_to(&mut *display_list); let paint_layer = Arc::new(PaintLayer::new(layout_root.layer_id(0), color, - Scrollable)); + ScrollPolicy::Scrollable)); let origin = Rect(Point2D(Au(0), Au(0)), root_size); let stacking_context = Arc::new(StackingContext::new(display_list, &origin, @@ -846,13 +847,13 @@ impl LayoutTask { } match data.query_type { - ContentBoxQuery(node) => { + ReflowQueryType::ContentBoxQuery(node) => { self.process_content_box_request(node, &mut layout_root, &mut rw_data) } - ContentBoxesQuery(node) => { + ReflowQueryType::ContentBoxesQuery(node) => { self.process_content_boxes_request(node, &mut layout_root, &mut rw_data) } - NoQuery => {} + ReflowQueryType::NoQuery => {} } self.first_reflow.set(false); @@ -999,7 +1000,7 @@ impl LayoutRPC for LayoutRPCImpl { let cursor = if !mouse_over_list.is_empty() { mouse_over_list[0].cursor } else { - DefaultCursor + Cursor::DefaultCursor }; let ConstellationChan(ref constellation_chan) = rw_data.constellation_chan; constellation_chan.send(ConstellationMsg::SetCursor(cursor)); diff --git a/components/layout/lib.rs b/components/layout/lib.rs index 7691a051afc..1da38b4eee8 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -33,7 +33,6 @@ extern crate string_cache; extern crate collections; extern crate encoding; extern crate libc; -extern crate sync; extern crate url; // Listed first because of macro definitions diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index b13630496c5..296a73454ca 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -21,7 +21,7 @@ use servo_util::geometry::Au; use servo_util::opts; use style::ComputedValues; use style::computed_values::list_style_type; -use sync::Arc; +use std::sync::Arc; /// A block with the CSS `display` property equal to `list-item`. #[deriving(Show)] @@ -131,12 +131,12 @@ pub fn static_text_for_list_style_type(list_style_type: list_style_type::T) // Just to keep things simple, use a nonbreaking space (Unicode 0xa0) to provide the marker // separation. match list_style_type { - list_style_type::none => None, - list_style_type::disc => Some("•\u00a0"), - list_style_type::circle => Some("◦\u00a0"), - list_style_type::square => Some("▪\u00a0"), - list_style_type::disclosure_open => Some("▾\u00a0"), - list_style_type::disclosure_closed => Some("‣\u00a0"), + list_style_type::T::none => None, + list_style_type::T::disc => Some("•\u{a0}"), + list_style_type::T::circle => Some("◦\u{a0}"), + list_style_type::T::square => Some("▪\u{a0}"), + list_style_type::T::disclosure_open => Some("▾\u{a0}"), + list_style_type::T::disclosure_closed => Some("‣\u{a0}"), } } diff --git a/components/layout/model.rs b/components/layout/model.rs index 4e4e5cad399..a031a5b0537 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -18,6 +18,7 @@ use std::cmp::{max, min}; use std::fmt; /// A collapsible margin. See CSS 2.1 § 8.3.1. +#[deriving(Copy)] pub struct AdjoiningMargins { /// The value of the greatest positive margin. pub most_positive: Au, @@ -60,6 +61,7 @@ impl AdjoiningMargins { } /// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1. +#[deriving(Copy)] pub enum CollapsibleMargins { /// Margins may not collapse with this flow. None(Au, Au), @@ -237,6 +239,7 @@ impl MarginCollapseInfo { } } +#[deriving(Copy)] pub enum MarginCollapseState { AccumulatingCollapsibleTopMargin, AccumulatingMarginIn, @@ -322,7 +325,7 @@ impl IntrinsicISizesContribution { } /// Useful helper data type when computing values for blocks and positioned elements. -#[deriving(PartialEq, Show)] +#[deriving(Copy, PartialEq, Show)] pub enum MaybeAuto { Auto, Specified(Au), diff --git a/components/layout/table.rs b/components/layout/table.rs index e05abd4d67e..0dd9f9caa08 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -27,7 +27,7 @@ use std::cmp::max; use std::fmt; use style::{ComputedValues, CSSFloat}; use style::computed_values::{LengthOrPercentageOrAuto, table_layout}; -use sync::Arc; +use std::sync::Arc; /// A table flow corresponded to the table's internal table fragment under a table wrapper flow. /// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment, @@ -54,7 +54,7 @@ impl TableFlow { -> TableFlow { let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment); let table_layout = if block_flow.fragment().style().get_table().table_layout == - table_layout::fixed { + table_layout::T::fixed { TableLayout::Fixed } else { TableLayout::Auto @@ -72,7 +72,7 @@ impl TableFlow { -> TableFlow { let mut block_flow = BlockFlow::from_node(constructor, node); let table_layout = if block_flow.fragment().style().get_table().table_layout == - table_layout::fixed { + table_layout::T::fixed { TableLayout::Fixed } else { TableLayout::Auto @@ -91,7 +91,7 @@ impl TableFlow { -> TableFlow { let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind); let table_layout = if block_flow.fragment().style().get_table().table_layout == - table_layout::fixed { + table_layout::T::fixed { TableLayout::Fixed } else { TableLayout::Auto @@ -441,7 +441,7 @@ impl ISizeAndMarginsComputer for InternalTable { /// maximum of 100 pixels and 20% of the table), the preceding constraint means that we must /// potentially store both a specified width *and* a specified percentage, so that the inline-size /// assignment phase of layout will know which one to pick. -#[deriving(Clone, Encodable, Show)] +#[deriving(Clone, Encodable, Show, Copy)] pub struct ColumnIntrinsicInlineSize { /// The preferred intrinsic inline size. pub preferred: Au, @@ -485,7 +485,7 @@ impl ColumnIntrinsicInlineSize { /// /// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too /// eventually. -#[deriving(Encodable)] +#[deriving(Encodable, Copy)] pub struct ColumnComputedInlineSize { /// The computed size of this inline column. pub size: Au, diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 1a77cde7092..938bfa0e0d2 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -17,7 +17,7 @@ use geom::{Point2D, Rect}; use servo_util::geometry::Au; use std::fmt; use style::ComputedValues; -use sync::Arc; +use std::sync::Arc; /// A table formatting context. pub struct TableCaptionFlow { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index b97a12e143d..89eea551c73 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -19,7 +19,7 @@ use geom::{Point2D, Rect}; use servo_util::geometry::Au; use std::fmt; use style::{UnsignedIntegerAttribute, ComputedValues}; -use sync::Arc; +use std::sync::Arc; /// A table formatting context. #[deriving(Encodable)] diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 5e7b066d206..648c1ae125c 100644 --- a/components/layout/table_colgroup.rs +++ b/components/layout/table_colgroup.rs @@ -19,7 +19,7 @@ use std::cmp::max; use std::fmt; use style::computed_values::LengthOrPercentageOrAuto; use style::ComputedValues; -use sync::Arc; +use std::sync::Arc; /// A table formatting context. pub struct TableColGroupFlow { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index b3e9e1ae7f6..55bc3634efa 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -24,7 +24,7 @@ use std::cmp::max; use std::fmt; use style::ComputedValues; use style::computed_values::LengthOrPercentageOrAuto; -use sync::Arc; +use std::sync::Arc; /// A single row of a table. #[deriving(Encodable)] @@ -39,7 +39,7 @@ pub struct TableRowFlow { } /// Information about the column inline size and span for each cell. -#[deriving(Encodable)] +#[deriving(Encodable, Copy)] pub struct CellIntrinsicInlineSize { /// Inline sizes that this cell contributes to the column. pub column_size: ColumnIntrinsicInlineSize, diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 2c2847565c7..80647a01a77 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -19,7 +19,7 @@ use geom::{Point2D, Rect}; use servo_util::geometry::Au; use std::fmt; use style::ComputedValues; -use sync::Arc; +use std::sync::Arc; /// A table formatting context. #[deriving(Encodable)] diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 1c68b7fa924..5a856db7334 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -29,9 +29,9 @@ use std::cmp::{max, min}; use std::fmt; use style::{ComputedValues, CSSFloat}; use style::computed_values::table_layout; -use sync::Arc; +use std::sync::Arc; -#[deriving(Encodable, Show)] +#[deriving(Copy, Encodable, Show)] pub enum TableLayout { Fixed, Auto @@ -55,7 +55,7 @@ impl TableWrapperFlow { -> TableWrapperFlow { let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment); let table_layout = if block_flow.fragment().style().get_table().table_layout == - table_layout::fixed { + table_layout::T::fixed { TableLayout::Fixed } else { TableLayout::Auto @@ -72,7 +72,7 @@ impl TableWrapperFlow { -> TableWrapperFlow { let mut block_flow = BlockFlow::from_node(constructor, node); let table_layout = if block_flow.fragment().style().get_table().table_layout == - table_layout::fixed { + table_layout::T::fixed { TableLayout::Fixed } else { TableLayout::Auto @@ -90,7 +90,7 @@ impl TableWrapperFlow { -> TableWrapperFlow { let mut block_flow = BlockFlow::float_from_node_and_fragment(node, fragment, float_kind); let table_layout = if block_flow.fragment().style().get_table().table_layout == - table_layout::fixed { + table_layout::T::fixed { TableLayout::Fixed } else { TableLayout::Auto @@ -487,7 +487,7 @@ impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandid /// The `CSSFloat` member specifies the weight of the smaller of the two guesses, on a scale from /// 0.0 to 1.0. -#[deriving(PartialEq, Show)] +#[deriving(Copy, PartialEq, Show)] enum SelectedAutoLayoutCandidateGuess { UseMinimumGuess, InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(CSSFloat), diff --git a/components/layout/text.rs b/components/layout/text.rs index ea79541bde0..e92197b7257 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -14,7 +14,7 @@ use gfx::font::{ShapingOptions}; use gfx::font_context::FontContext; use gfx::text::glyph::CharIndex; use gfx::text::text_run::TextRun; -use gfx::text::util::{mod, CompressWhitespaceNewline, CompressNone}; +use gfx::text::util::{mod, CompressionMode}; use servo_util::dlist; use servo_util::geometry::Au; use servo_util::logical_geometry::{LogicalSize, WritingMode}; @@ -25,7 +25,7 @@ use std::mem; use style::ComputedValues; use style::computed_values::{line_height, text_orientation, text_transform, white_space}; use style::style_structs::Font as FontStyle; -use sync::Arc; +use std::sync::Arc; /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s. pub struct TextRunScanner { @@ -114,8 +114,8 @@ impl TextRunScanner { let inherited_text_style = in_fragment.style().get_inheritedtext(); fontgroup = font_context.get_layout_font_group_for_style(font_style); compression = match in_fragment.white_space() { - white_space::normal | white_space::nowrap => CompressWhitespaceNewline, - white_space::pre => CompressNone, + white_space::T::normal | white_space::T::nowrap => CompressionMode::CompressWhitespaceNewline, + white_space::T::pre => CompressionMode::CompressNone, }; text_transform = inherited_text_style.text_transform; letter_spacing = inherited_text_style.letter_spacing; @@ -213,22 +213,22 @@ impl TextRunScanner { string: &mut String, text_transform: text_transform::T) { match text_transform { - text_transform::none => {} - text_transform::uppercase => { + text_transform::T::none => {} + text_transform::T::uppercase => { let length = string.len(); let original = mem::replace(string, String::with_capacity(length)); for character in original.chars() { string.push(character.to_uppercase()) } } - text_transform::lowercase => { + text_transform::T::lowercase => { let length = string.len(); let original = mem::replace(string, String::with_capacity(length)); for character in original.chars() { string.push(character.to_lowercase()) } } - text_transform::capitalize => { + text_transform::T::capitalize => { let length = string.len(); let original = mem::replace(string, String::with_capacity(length)); let mut capitalize_next_letter = true; @@ -266,9 +266,9 @@ fn bounding_box_for_run_metrics(metrics: &RunMetrics, writing_mode: WritingMode) // This will be a reminder to update the code below. let dummy: Option<text_orientation::T> = None; match dummy { - Some(text_orientation::sideways_right) | - Some(text_orientation::sideways_left) | - Some(text_orientation::sideways) | + Some(text_orientation::T::sideways_right) | + Some(text_orientation::T::sideways_left) | + Some(text_orientation::T::sideways) | None => {} } @@ -296,8 +296,8 @@ pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: Arc<Fo pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> Au { let font_size = style.get_font().font_size; match style.get_inheritedbox().line_height { - line_height::Normal => metrics.line_gap, - line_height::Number(l) => font_size.scale_by(l), - line_height::Length(l) => l + line_height::T::Normal => metrics.line_gap, + line_height::T::Number(l) => font_size.scale_by(l), + line_height::T::Length(l) => l } } diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index df56254c066..bafd242fc31 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -21,6 +21,9 @@ use servo_util::opts; use servo_util::tid::tid; use style::TNode; +use std::cell::RefCell; +use std::mem; + /// Every time we do another layout, the old bloom filters are invalid. This is /// detected by ticking a generation number every layout. type Generation = uint; @@ -45,7 +48,7 @@ type Generation = uint; /// Since a work-stealing queue is used for styling, sometimes, the bloom filter /// will no longer be the for the parent of the node we're currently on. When /// this happens, the task local bloom filter will be thrown away and rebuilt. -local_data_key!(style_bloom: (Box<BloomFilter>, UnsafeLayoutNode, Generation)) +thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None)) /// Returns the task local bloom filter. /// @@ -53,43 +56,48 @@ local_data_key!(style_bloom: (Box<BloomFilter>, UnsafeLayoutNode, Generation)) /// it will be thrown out and a new one will be made for you. fn take_task_local_bloom_filter(parent_node: Option<LayoutNode>, layout_context: &LayoutContext) -> Box<BloomFilter> { - match (parent_node, style_bloom.replace(None)) { - // Root node. Needs new bloom filter. - (None, _ ) => { - debug!("[{}] No parent, but new bloom filter!", tid()); - box BloomFilter::new() - } - // No bloom filter for this thread yet. - (Some(parent), None) => { - let mut bloom_filter = box BloomFilter::new(); - insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context); - bloom_filter - } - // Found cached bloom filter. - (Some(parent), Some((mut bloom_filter, old_node, old_generation))) => { - // Hey, the cached parent is our parent! We can reuse the bloom filter. - if old_node == layout_node_to_unsafe_layout_node(&parent) && - old_generation == layout_context.shared.generation { - debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0()); - bloom_filter - } else { - // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing - // allocation to avoid malloc churn. - *bloom_filter = BloomFilter::new(); + STYLE_BLOOM.with(|style_bloom| { + match (parent_node, style_bloom.borrow_mut().take()) { + // Root node. Needs new bloom filter. + (None, _ ) => { + debug!("[{}] No parent, but new bloom filter!", tid()); + box BloomFilter::new() + } + // No bloom filter for this thread yet. + (Some(parent), None) => { + let mut bloom_filter = box BloomFilter::new(); insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context); bloom_filter } - }, - } + // Found cached bloom filter. + (Some(parent), Some((mut bloom_filter, old_node, old_generation))) => { + // Hey, the cached parent is our parent! We can reuse the bloom filter. + if old_node == layout_node_to_unsafe_layout_node(&parent) && + old_generation == layout_context.shared.generation { + debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.val0()); + bloom_filter.clone() + } else { + // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing + // allocation to avoid malloc churn. + *bloom_filter = BloomFilter::new(); + insert_ancestors_into_bloom_filter(&mut bloom_filter, parent, layout_context); + bloom_filter + } + }, + } + }) } fn put_task_local_bloom_filter(bf: Box<BloomFilter>, unsafe_node: &UnsafeLayoutNode, layout_context: &LayoutContext) { - match style_bloom.replace(Some((bf, *unsafe_node, layout_context.shared.generation))) { - None => {}, - Some(_) => panic!("Putting into a never-taken task-local bloom filter"), - } + let bf: *mut BloomFilter = unsafe { mem::transmute(bf) }; + STYLE_BLOOM.with(|style_bloom| { + assert!(style_bloom.borrow().is_none(), + "Putting into a never-taken task-local bloom filter"); + let bf: Box<BloomFilter> = unsafe { mem::transmute(bf) }; + *style_bloom.borrow_mut() = Some((bf, *unsafe_node, layout_context.shared.generation)); + }) } /// "Ancestors" in this context is inclusive of ourselves. @@ -112,6 +120,7 @@ fn insert_ancestors_into_bloom_filter(bf: &mut Box<BloomFilter>, /// The recalc-style-for-node traversal, which styles each node and must run before /// layout computation. This computes the styles applied to each node. +#[deriving(Copy)] pub struct RecalcStyleForNode<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -200,6 +209,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { } /// The flow construction traversal, which builds flows for styled nodes. +#[deriving(Copy)] pub struct ConstructFlows<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -238,9 +248,10 @@ impl<'a> PostorderDomTraversal for ConstructFlows<'a> { let unsafe_layout_node = layout_node_to_unsafe_layout_node(&node); let (mut bf, old_node, old_generation) = - style_bloom - .replace(None) - .expect("The bloom filter should have been set by style recalc."); + STYLE_BLOOM.with(|style_bloom| { + mem::replace(&mut *style_bloom.borrow_mut(), None) + .expect("The bloom filter should have been set by style recalc.") + }); assert_eq!(old_node, unsafe_layout_node); assert_eq!(old_generation, self.layout_context.shared.generation); @@ -297,6 +308,7 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> { } /// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`. +#[deriving(Copy)] pub struct AssignISizes<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -317,6 +329,7 @@ impl<'a> PreorderFlowTraversal for AssignISizes<'a> { /// layout computation. Determines the final block-sizes for all layout objects, computes /// positions, and computes overflow regions. In Gecko this corresponds to `Reflow` and /// `FinishAndStoreOverflow`. +#[deriving(Copy)] pub struct AssignBSizesAndStoreOverflow<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -341,6 +354,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> { } } +#[deriving(Copy)] pub struct ComputeAbsolutePositions<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -352,6 +366,7 @@ impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> { } } +#[deriving(Copy)] pub struct BuildDisplayList<'a> { pub layout_context: &'a LayoutContext<'a>, } diff --git a/components/layout/util.rs b/components/layout/util.rs index 368182e6c9e..0ba105f20fa 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -19,7 +19,7 @@ use std::mem; use std::cell::{Ref, RefMut}; use style::ComputedValues; use style; -use sync::Arc; +use std::sync::Arc; /// Data that layout associates with a node. pub struct PrivateLayoutData { @@ -64,6 +64,7 @@ impl PrivateLayoutData { } bitflags! { + #[deriving(Copy)] flags LayoutDataFlags: u8 { #[doc="Whether a flow has been newly constructed."] const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01 diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index aca02bdbb4e..c22bb367b60 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -137,6 +137,7 @@ pub trait TLayoutNode { /// A wrapper so that layout can access only the methods that it should have access to. Layout must /// only ever see these and must never see instances of `JS`. +#[deriving(Copy)] pub struct LayoutNode<'a> { /// The wrapped node. node: JS<Node>, @@ -476,6 +477,7 @@ impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { } /// A wrapper around elements that ensures layout can only ever access safe properties. +#[deriving(Copy)] pub struct LayoutElement<'le> { element: &'le Element, } @@ -631,10 +633,10 @@ impl<'le> TElementAttributes for LayoutElement<'le> { fn get_content(content_list: &content::T) -> String { match *content_list { - content::Content(ref value) => { + content::T::Content(ref value) => { let iter = &mut value.clone().into_iter().peekable(); match iter.next() { - Some(content::StringContent(content)) => content, + Some(content::ContentItem::StringContent(content)) => content, _ => "".into_string(), } } @@ -642,7 +644,7 @@ fn get_content(content_list: &content::T) -> String { } } -#[deriving(PartialEq, Clone)] +#[deriving(Copy, PartialEq, Clone)] pub enum PseudoElementType { Normal, Before(display::T), @@ -667,7 +669,7 @@ impl PseudoElementType { /// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout /// node does not allow any parents or siblings of nodes to be accessed, to avoid races. -#[deriving(Clone)] +#[deriving(Copy, Clone)] pub struct ThreadSafeLayoutNode<'ln> { /// The wrapped node. node: LayoutNode<'ln>, @@ -716,9 +718,9 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(self.get_before_display())); return Some(pseudo_before_node) } - PseudoElementType::Before(display::inline) => {} + PseudoElementType::Before(display::T::inline) => {} PseudoElementType::Before(_) => { - let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(display::inline)); + let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(display::T::inline)); return Some(pseudo_before_node) } _ => {} @@ -922,7 +924,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { // If you implement other values for this property, you will almost certainly // want to update this check. match self.style().get_inheritedtext().white_space { - white_space::normal => true, + white_space::T::normal => true, _ => false, } } |