diff options
Diffstat (limited to 'components/layout')
31 files changed, 504 insertions, 409 deletions
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index d24261495e1..fb3796577e6 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -7,6 +7,9 @@ authors = ["The Servo Project Developers"] name = "layout" path = "lib.rs" +[dependencies.canvas] +path = "../canvas" + [dependencies.gfx] path = "../gfx" @@ -37,9 +40,6 @@ git = "https://github.com/servo/rust-cssparser" [dependencies.geom] git = "https://github.com/servo/rust-geom" -[dependencies.url] -git = "https://github.com/servo/rust-url" - [dependencies.string_cache] git = "https://github.com/servo/string-cache" @@ -48,3 +48,4 @@ git = "https://github.com/servo/string-cache" [dependencies] encoding = "0.2" +url = "*"
\ No newline at end of file diff --git a/components/layout/block.rs b/components/layout/block.rs index f91f079f6bf..d1ffc16a111 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -32,7 +32,7 @@ use context::LayoutContext; use css::node_style::StyledNode; use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding}; use floats::{ClearType, FloatKind, Floats, PlacementInfo}; -use flow::{mod, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow}; +use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow}; use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal}; use flow::{PostorderFlowTraversal, mut_base}; use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS}; @@ -64,7 +64,7 @@ use style::computed_values::{overflow, position}; use std::sync::Arc; /// Information specific to floated blocks. -#[deriving(Clone, Encodable)] +#[derive(Clone, Encodable)] pub struct FloatedBlockInfo { /// The amount of inline size that is available for the float. pub containing_inline_size: Au, @@ -92,7 +92,7 @@ impl FloatedBlockInfo { } /// The solutions for the block-size-and-margins constraint equation. -#[deriving(Copy)] +#[derive(Copy)] struct BSizeConstraintSolution { block_start: Au, _block_end: Au, @@ -366,7 +366,8 @@ impl CandidateBSizeIterator { } } -impl Iterator<MaybeAuto> for CandidateBSizeIterator { +impl Iterator for CandidateBSizeIterator { + type Item = MaybeAuto; fn next(&mut self) -> Option<MaybeAuto> { self.status = match self.status { CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying, @@ -487,13 +488,13 @@ pub enum BlockType { FloatNonReplaced, } -#[deriving(Clone, PartialEq)] +#[derive(Clone, PartialEq)] pub enum MarginsMayCollapseFlag { MarginsMayCollapse, MarginsMayNotCollapse, } -#[deriving(PartialEq)] +#[derive(PartialEq)] enum FormattingContextType { None, Block, @@ -525,7 +526,7 @@ fn propagate_layer_flag_from_child(layers_needed_for_descendants: &mut bool, kid } // A block formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct BlockFlow { /// Data common to all flows. pub base: BaseFlow, @@ -561,8 +562,8 @@ bitflags! { } } -impl<'a,E,S> Encodable<S,E> for BlockFlowFlags where S: Encoder<E> { - fn encode(&self, e: &mut S) -> Result<(),E> { +impl Encodable for BlockFlowFlags { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { self.bits().encode(e) } } @@ -1905,7 +1906,7 @@ impl Flow for BlockFlow { impl fmt::Show for BlockFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, - "{} - {:x}: frag={} ({})", + "{:?} - {:x}: frag={:?} ({:?})", self.class(), self.base.debug_id(), self.fragment, @@ -1914,7 +1915,7 @@ impl fmt::Show for BlockFlow { } /// The inputs for the inline-sizes-and-margins constraint equation. -#[deriving(Show, Copy)] +#[derive(Show, Copy)] pub struct ISizeConstraintInput { pub computed_inline_size: MaybeAuto, pub inline_start_margin: MaybeAuto, @@ -1947,7 +1948,7 @@ impl ISizeConstraintInput { } /// The solutions for the inline-size-and-margins constraint equation. -#[deriving(Copy, Show)] +#[derive(Copy, Show)] pub struct ISizeConstraintSolution { pub inline_start: Au, pub inline_end: Au, @@ -2560,7 +2561,7 @@ impl ISizeAndMarginsComputer for FloatNonReplaced { let available_inline_size_float = available_inline_size - margin_inline_start - margin_inline_end; let shrink_to_fit = block.get_shrink_to_fit_inline_size(available_inline_size_float); let inline_size = computed_inline_size.specified_or_default(shrink_to_fit); - debug!("assign_inline_sizes_float -- inline_size: {}", inline_size); + debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } } @@ -2580,7 +2581,7 @@ impl ISizeAndMarginsComputer for FloatReplaced { MaybeAuto::Specified(w) => w, MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now") }; - debug!("assign_inline_sizes_float -- inline_size: {}", inline_size); + debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } diff --git a/components/layout/construct.rs b/components/layout/construct.rs index eb90fbf734e..9e14e2244ab 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -31,7 +31,7 @@ use fragment::TableColumnFragmentInfo; use fragment::UnscannedTextFragmentInfo; use incremental::{RECONSTRUCT_FLOW, RestyleDamage}; use inline::InlineFlow; -use list_item::{mod, ListItemFlow}; +use list_item::{self, ListItemFlow}; use parallel; use table_wrapper::TableWrapperFlow; use table::TableFlow; @@ -50,17 +50,18 @@ use script::dom::htmlelement::HTMLElementTypeId; use script::dom::htmlobjectelement::is_image_data; use script::dom::node::NodeTypeId; use servo_util::opts; +use std::borrow::ToOwned; use std::collections::DList; use std::mem; -use std::sync::atomic::Relaxed; +use std::sync::atomic::Ordering; use style::computed_values::{caption_side, display, empty_cells, float, list_style_position}; use style::computed_values::{position}; -use style::{mod, ComputedValues}; +use style::{self, ComputedValues}; use std::sync::Arc; use url::Url; /// The results of flow construction for a DOM node. -#[deriving(Clone)] +#[derive(Clone)] pub enum ConstructionResult { /// This node contributes nothing at all (`display: none`). Alternately, this is what newly /// created nodes have their `ConstructionResult` set to. @@ -89,7 +90,7 @@ impl ConstructionResult { match self { &ConstructionResult::None => 0u, &ConstructionResult::ConstructionItem(_) => 0u, - &ConstructionResult::Flow(ref flow_ref, _) => flow::base(flow_ref.deref()).debug_id(), + &ConstructionResult::Flow(ref flow_ref, _) => flow::base(&**flow_ref).debug_id(), } } } @@ -97,7 +98,7 @@ impl ConstructionResult { /// Represents the output of flow construction for a DOM node that has not yet resulted in a /// complete flow. Construction items bubble up the tree until they find a `Flow` to be attached /// to. -#[deriving(Clone)] +#[derive(Clone)] pub enum ConstructionItem { /// Inline fragments and associated {ib} splits that have not yet found flows. InlineFragments(InlineFragmentsConstructionResult), @@ -108,7 +109,7 @@ pub enum ConstructionItem { } /// Represents inline fragments and {ib} splits that are bubbling up from an inline. -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineFragmentsConstructionResult { /// Any {ib} splits that we're bubbling up. pub splits: DList<InlineBlockSplit>, @@ -146,7 +147,7 @@ pub struct InlineFragmentsConstructionResult { /// C /// ]) /// ``` -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineBlockSplit { /// The inline fragments that precede the flow. pub predecessors: DList<Fragment>, @@ -221,8 +222,8 @@ pub struct FlowConstructor<'a> { impl<'a> FlowConstructor<'a> { /// Creates a new flow constructor. - pub fn new<'a>(layout_context: &'a LayoutContext<'a>) - -> FlowConstructor<'a> { + pub fn new<'b>(layout_context: &'b LayoutContext<'b>) + -> FlowConstructor<'b> { FlowConstructor { layout_context: layout_context, } @@ -375,7 +376,7 @@ impl<'a> FlowConstructor<'a> { ConstructionResult::Flow(kid_flow, kid_abs_descendants) => { // If kid_flow is TableCaptionFlow, kid_flow should be added under // TableWrapperFlow. - if flow.is_table() && kid_flow.deref().is_table_caption() { + if flow.is_table() && kid_flow.is_table_caption() { kid.set_flow_construction_result(ConstructionResult::Flow(kid_flow, Descendants::new())) } else if flow.need_anonymous_flow(&*kid_flow) { @@ -455,7 +456,7 @@ impl<'a> FlowConstructor<'a> { // Add whitespace results. They will be stripped out later on when // between block elements, and retained when between inline elements. let fragment_info = - SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".into_string())); + SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".to_owned())); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_style, whitespace_damage, @@ -652,7 +653,7 @@ impl<'a> FlowConstructor<'a> { whitespace_damage)) => { // Instantiate the whitespace fragment. let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text( - " ".into_string())); + " ".to_owned())); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, whitespace_style, whitespace_damage, @@ -814,7 +815,7 @@ impl<'a> FlowConstructor<'a> { for kid in node.children() { match kid.swap_out_construction_result() { ConstructionResult::Flow(mut kid_flow, _) => { - if kid_flow.deref().is_table_caption() && + if kid_flow.is_table_caption() && kid_flow.as_block() .fragment .style() @@ -986,7 +987,7 @@ impl<'a> FlowConstructor<'a> { .list_style_type) { None => None, Some(text) => { - let text = text.into_string(); + let text = text.to_owned(); let mut unscanned_marker_fragments = DList::new(); unscanned_marker_fragments.push_back(Fragment::new_from_specific_info( node, @@ -1149,7 +1150,7 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { } }; - debug!("building flow for node: {} {} {}", display, float, node.type_id()); + debug!("building flow for node: {:?} {:?} {:?}", display, float, node.type_id()); // Switch on display and floatedness. match (display, float, positioning) { @@ -1376,15 +1377,15 @@ impl FlowConstructionUtils for FlowRef { /// /// This must not be public because only the layout constructor can do this. fn add_new_child(&mut self, mut new_child: FlowRef) { - let base = flow::mut_base(self.deref_mut()); + let base = flow::mut_base(&mut **self); { - let kid_base = flow::mut_base(new_child.deref_mut()); + let kid_base = flow::mut_base(&mut *new_child); kid_base.parallel.parent = parallel::mut_owned_flow_to_unsafe_flow(self); } base.children.push_back(new_child); - let _ = base.parallel.children_count.fetch_add(1, Relaxed); + let _ = base.parallel.children_count.fetch_add(1, Ordering::Relaxed); } /// Finishes a flow. Once a flow is finished, no more child flows or fragments may be added to diff --git a/components/layout/context.rs b/components/layout/context.rs index b329a20221d..e3df7a1a8b5 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -28,7 +28,7 @@ struct LocalLayoutContext { style_sharing_candidate_cache: StyleSharingCandidateCache, } -thread_local!(static LOCAL_CONTEXT_KEY: Cell<*mut LocalLayoutContext> = Cell::new(ptr::null_mut())) +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 { LOCAL_CONTEXT_KEY.with(|ref r| { @@ -80,6 +80,9 @@ pub struct SharedLayoutContext { pub generation: uint, } +pub struct SharedLayoutContextWrapper(pub *const SharedLayoutContext); +unsafe impl Send for SharedLayoutContextWrapper {} + pub struct LayoutContext<'a> { pub shared: &'a SharedLayoutContext, cached_local_layout_context: *mut LocalLayoutContext, @@ -97,7 +100,7 @@ impl<'a> LayoutContext<'a> { } #[inline(always)] - pub fn font_context<'a>(&'a self) -> &'a mut FontContext { + pub fn font_context<'b>(&'b self) -> &'b mut FontContext { unsafe { let cached_context = &mut *self.cached_local_layout_context; &mut cached_context.font_context @@ -105,7 +108,7 @@ impl<'a> LayoutContext<'a> { } #[inline(always)] - pub fn applicable_declarations_cache<'a>(&'a self) -> &'a mut ApplicableDeclarationsCache { + pub fn applicable_declarations_cache<'b>(&'b self) -> &'b mut ApplicableDeclarationsCache { unsafe { let cached_context = &mut *self.cached_local_layout_context; &mut cached_context.applicable_declarations_cache @@ -113,7 +116,7 @@ impl<'a> LayoutContext<'a> { } #[inline(always)] - pub fn style_sharing_candidate_cache<'a>(&'a self) -> &'a mut StyleSharingCandidateCache { + pub fn style_sharing_candidate_cache<'b>(&'b self) -> &'b mut StyleSharingCandidateCache { unsafe { let cached_context = &mut *self.cached_local_layout_context; &mut cached_context.style_sharing_candidate_cache diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index 8606c575146..0f1931c3efb 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -5,20 +5,21 @@ //! High-level interface to CSS selector matching. use css::node_style::StyledNode; -use incremental::{mod, RestyleDamage}; +use incremental::{self, RestyleDamage}; use util::{LayoutDataAccess, LayoutDataWrapper}; use wrapper::{LayoutElement, LayoutNode, TLayoutNode}; use script::dom::node::NodeTypeId; use servo_util::bloom::BloomFilter; -use servo_util::cache::{Cache, LRUCache, SimpleHashCache}; +use servo_util::cache::{LRUCache, SimpleHashCache}; use servo_util::smallvec::{SmallVec, SmallVec16}; use servo_util::arc_ptr_eq; +use std::borrow::ToOwned; use std::mem; -use std::hash::{Hash, sip}; -use std::slice::Items; +use std::hash::{Hash, Hasher, Writer}; +use std::slice::Iter; use string_cache::{Atom, Namespace}; -use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode}; +use style::{self, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode}; use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade}; use std::sync::Arc; @@ -49,7 +50,7 @@ impl ApplicableDeclarations { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct ApplicableDeclarationsCacheEntry { pub declarations: Vec<DeclarationBlock>, } @@ -65,12 +66,13 @@ impl ApplicableDeclarationsCacheEntry { impl PartialEq for ApplicableDeclarationsCacheEntry { fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool { let this_as_query = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()); - this_as_query.equiv(other) + this_as_query.eq(other) } } +impl Eq for ApplicableDeclarationsCacheEntry {} -impl Hash for ApplicableDeclarationsCacheEntry { - fn hash(&self, state: &mut sip::SipState) { +impl<H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheEntry { + fn hash(&self, state: &mut H) { let tmp = ApplicableDeclarationsCacheQuery::new(self.declarations.as_slice()); tmp.hash(state); } @@ -88,8 +90,8 @@ impl<'a> ApplicableDeclarationsCacheQuery<'a> { } } -impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> { - fn equiv(&self, other: &ApplicableDeclarationsCacheEntry) -> bool { +impl<'a> PartialEq for ApplicableDeclarationsCacheQuery<'a> { + fn eq(&self, other: &ApplicableDeclarationsCacheQuery<'a>) -> bool { if self.declarations.len() != other.declarations.len() { return false } @@ -101,10 +103,17 @@ impl<'a> Equiv<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCache return true } } +impl<'a> Eq for ApplicableDeclarationsCacheQuery<'a> {} +impl<'a> PartialEq<ApplicableDeclarationsCacheEntry> for ApplicableDeclarationsCacheQuery<'a> { + fn eq(&self, other: &ApplicableDeclarationsCacheEntry) -> bool { + let other_as_query = ApplicableDeclarationsCacheQuery::new(other.declarations.as_slice()); + self.eq(&other_as_query) + } +} -impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> { - fn hash(&self, state: &mut sip::SipState) { +impl<'a, H: Hasher+Writer> Hash<H> for ApplicableDeclarationsCacheQuery<'a> { + fn hash(&self, state: &mut H) { for declaration in self.declarations.iter() { let ptr: uint = unsafe { mem::transmute_copy(declaration) @@ -128,7 +137,7 @@ impl ApplicableDeclarationsCache { } fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> { - match self.cache.find_equiv(&ApplicableDeclarationsCacheQuery::new(declarations)) { + match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) { None => None, Some(ref values) => Some((*values).clone()), } @@ -167,7 +176,7 @@ fn create_common_style_affecting_attributes_from_element(element: &LayoutElement flags } -#[deriving(Clone)] +#[derive(Clone)] pub struct StyleSharingCandidate { pub style: Arc<ComputedValues>, pub parent_style: Arc<ComputedValues>, @@ -237,7 +246,7 @@ impl StyleSharingCandidate { parent_style: parent_style, local_name: element.get_local_name().clone(), class: element.get_attr(&ns!(""), &atom!("class")) - .map(|string| string.into_string()), + .map(|string| string.to_owned()), link: element.get_link().is_some(), namespace: (*element.get_namespace()).clone(), common_style_affecting_attributes: @@ -320,7 +329,7 @@ impl StyleSharingCandidateCache { } } - pub fn iter<'a>(&'a self) -> Items<'a,(StyleSharingCandidate,())> { + pub fn iter<'a>(&'a self) -> Iter<'a,(StyleSharingCandidate,())> { self.cache.iter() } @@ -607,8 +616,8 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &None => panic!("no layout data"), - &Some(ref mut layout_data) => { + &mut None => panic!("no layout data"), + &mut Some(ref mut layout_data) => { match self.type_id() { Some(NodeTypeId::Text) => { // Text nodes get a copy of the parent style. This ensures diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 2e4ae665ea9..1c81e65459b 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -13,7 +13,7 @@ use block::BlockFlow; use canvas::canvas_paint_task::CanvasMsg::SendPixelContents; use context::LayoutContext; -use flow::{mod, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER}; +use flow::{self, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER}; use fragment::{CoordinateSystem, Fragment, IframeFragmentInfo, ImageFragmentInfo}; use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo}; use inline::InlineFlow; @@ -40,20 +40,22 @@ use servo_msg::constellation_msg::Msg as ConstellationMsg; use servo_msg::constellation_msg::ConstellationChan; use servo_net::image::holder::ImageHolder; use servo_util::cursor::Cursor; -use servo_util::geometry::{mod, Au, to_px}; +use servo_util::geometry::{self, Au, to_px, to_frac_px}; use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize}; use servo_util::opts; use std::default::Default; use std::iter::repeat; -use std::num::FloatMath; -use style::computed::{AngleOrCorner, LengthOrPercentage, HorizontalDirection, VerticalDirection}; -use style::computed::{Image, LinearGradient}; +use std::num::Float; +use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection}; +use style::computed::{Image, LinearGradient, LengthOrPercentage}; use style::computed_values::filter::Filter; use style::computed_values::{background_attachment, background_repeat, border_style, overflow}; use style::computed_values::{position, visibility}; use style::style_structs::Border; use style::{ComputedValues, RGBA}; +use std::num::ToPrimitive; use std::sync::Arc; +use std::sync::mpsc::channel; use url::Url; /// The results of display list building for a single flow. @@ -216,21 +218,51 @@ pub trait FragmentDisplayListBuilding { clip: &ClippingRegion); } +fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> { + // No two corners' border radii may add up to more than the length of the edge + // between them. To prevent that, all radii are scaled down uniformly. + fn scale_factor(radius_a: Au, radius_b: Au, edge_length: Au) -> f64 { + let required = radius_a + radius_b; + + if required <= edge_length { + 1.0 + } else { + to_frac_px(edge_length) / to_frac_px(required) + } + } + + let top_factor = scale_factor(radii.top_left, radii.top_right, size.width); + let bottom_factor = scale_factor(radii.bottom_left, radii.bottom_right, size.width); + let left_factor = scale_factor(radii.top_left, radii.bottom_left, size.height); + let right_factor = scale_factor(radii.top_right, radii.bottom_right, size.height); + let min_factor = top_factor.min(bottom_factor).min(left_factor).min(right_factor); + if min_factor < 1.0 { + BorderRadii { + top_left: radii.top_left .scale_by(min_factor), + top_right: radii.top_right .scale_by(min_factor), + bottom_left: radii.bottom_left .scale_by(min_factor), + bottom_right: radii.bottom_right.scale_by(min_factor), + } + } else { + *radii + } +} + fn build_border_radius(abs_bounds: &Rect<Au>, border_style: &Border) -> BorderRadii<Au> { // TODO(cgaebel): Support border radii even in the case of multiple border widths. // This is an extension of supporting elliptical radii. For now, all percentage // radii will be relative to the width. - BorderRadii { - top_left: model::specified(border_style.border_top_left_radius.radius, + handle_overlapping_radii(&abs_bounds.size, &BorderRadii { + top_left: model::specified(border_style.border_top_left_radius, abs_bounds.size.width), - top_right: model::specified(border_style.border_top_right_radius.radius, + top_right: model::specified(border_style.border_top_right_radius, abs_bounds.size.width), - bottom_right: model::specified(border_style.border_bottom_right_radius.radius, + bottom_right: model::specified(border_style.border_bottom_right_radius, abs_bounds.size.width), - bottom_left: model::specified(border_style.border_bottom_left_radius.radius, + bottom_left: model::specified(border_style.border_bottom_left_radius, abs_bounds.size.width), - } + }) } impl FragmentDisplayListBuilding for Fragment { @@ -689,7 +721,7 @@ impl FragmentDisplayListBuilding for Fragment { relative_containing_block_size, CoordinateSystem::Self); - debug!("Fragment::build_display_list at rel={}, abs={}, dirty={}, flow origin={}: {}", + debug!("Fragment::build_display_list at rel={:?}, abs={:?}, dirty={:?}, flow origin={:?}: {:?}", self.border_box, stacking_relative_border_box, layout_context.shared.dirty, @@ -879,8 +911,8 @@ impl FragmentDisplayListBuilding for Fragment { let (sender, receiver) = channel::<Vec<u8>>(); let canvas_data = match canvas_fragment_info.renderer { Some(ref renderer) => { - renderer.deref().lock().send(SendPixelContents(sender)); - receiver.recv() + renderer.lock().unwrap().send(SendPixelContents(sender)); + receiver.recv().unwrap() }, None => repeat(0xFFu8).take(width * height * 4).collect(), }; @@ -916,7 +948,7 @@ impl FragmentDisplayListBuilding for Fragment { Size2D(geometry::to_frac_px(content_size.width) as f32, geometry::to_frac_px(content_size.height) as f32)); - debug!("finalizing position and size of iframe for {},{}", + debug!("finalizing position and size of iframe for {:?},{:?}", iframe_fragment.pipeline_id, iframe_fragment.subpage_id); let ConstellationChan(ref chan) = layout_context.shared.constellation_chan; @@ -1226,12 +1258,12 @@ impl InlineFlowDisplayListBuilding for InlineFlow { &self.base.clip); match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut block_flow) => { - let block_flow = block_flow.flow_ref.deref_mut(); + let block_flow = &mut *block_flow.flow_ref; flow::mut_base(block_flow).display_list_building_result .add_to(&mut *display_list) } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => { - let block_flow = block_flow.flow_ref.deref_mut(); + let block_flow = &mut *block_flow.flow_ref; flow::mut_base(block_flow).display_list_building_result .add_to(&mut *display_list) } @@ -1276,7 +1308,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { } // A helper data structure for gradients. -#[deriving(Copy)] +#[derive(Copy)] struct StopRun { start_offset: f32, end_offset: f32, @@ -1300,7 +1332,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, Copy)] +#[derive(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 5d82014f779..10a057f172e 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, Copy)] +#[derive(Clone, RustcEncodable, Show, Copy)] pub enum FloatKind { Left, Right @@ -29,7 +29,7 @@ impl FloatKind { } /// The kind of clearance: left, right, or both. -#[deriving(Copy)] +#[derive(Copy)] pub enum ClearType { Left, Right, @@ -37,7 +37,7 @@ pub enum ClearType { } /// Information about a single float. -#[deriving(Clone, Copy)] +#[derive(Clone, Copy)] struct Float { /// The boundaries of this float. bounds: LogicalRect<Au>, @@ -47,12 +47,12 @@ struct Float { impl fmt::Show for Float { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "bounds={} kind={}", self.bounds, self.kind) + write!(f, "bounds={:?} kind={:?}", self.bounds, self.kind) } } /// Information about the floats next to a flow. -#[deriving(Clone)] +#[derive(Clone)] struct FloatList { /// Information about each of the floats here. floats: PersistentList<Float>, @@ -77,7 +77,7 @@ impl FloatList { impl fmt::Show for FloatList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "max_block_start={} floats={}", self.max_block_start, self.floats.len()) + write!(f, "max_block_start={:?} floats={}", self.max_block_start, self.floats.len()) } } @@ -96,7 +96,7 @@ pub struct PlacementInfo { impl fmt::Show for PlacementInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, - "size={} ceiling={} max_inline_size={} kind={}", + "size={:?} ceiling={:?} max_inline_size={:?} kind={:?}", self.size, self.ceiling, self.max_inline_size, @@ -110,7 +110,7 @@ fn range_intersect(block_start_1: Au, block_end_1: Au, block_start_2: Au, block_ /// Encapsulates information about floats. This is optimized to avoid allocation if there are /// no floats, and to avoid copying when translating the list of floats downward. -#[deriving(Clone)] +#[derive(Clone)] pub struct Floats { /// The list of floats. list: FloatList, @@ -125,7 +125,7 @@ impl fmt::Show for Floats { if !self.list.is_present() { write!(f, "[empty]") } else { - write!(f, "offset={} floats={}", self.offset, self.list) + write!(f, "offset={:?} floats={:?}", self.offset, self.list) } } } @@ -166,7 +166,7 @@ impl Floats { let list = &self.list; let block_start = block_start - self.offset.block; - debug!("available_rect: trying to find space at {}", block_start); + debug!("available_rect: trying to find space at {:?}", block_start); // Relevant dimensions for the inline-end-most inline-start float let mut max_inline_start = Au(0) - self.offset.inline; @@ -183,7 +183,7 @@ impl Floats { let float_pos = float.bounds.start; let float_size = float.bounds.size; - debug!("float_pos: {}, float_size: {}", float_pos, float_size); + debug!("float_pos: {:?}, float_size: {:?}", float_pos, float_size); match float.kind { FloatKind::Left if float_pos.i + float_size.inline > max_inline_start && float_pos.b + float_size.block > block_start && @@ -194,7 +194,7 @@ impl Floats { l_block_end = Some(float_pos.b + float_size.block); debug!("available_rect: collision with inline_start float: new \ - max_inline_start is {}", + max_inline_start is {:?}", max_inline_start); } FloatKind::Right if float_pos.i < min_inline_end && @@ -205,7 +205,7 @@ impl Floats { r_block_start = Some(float_pos.b); r_block_end = Some(float_pos.b + float_size.block); debug!("available_rect: collision with inline_end float: new min_inline_end \ - is {}", + is {:?}", min_inline_end); } FloatKind::Left | FloatKind::Right => {} @@ -262,7 +262,7 @@ impl Floats { } } - debug!("add_float: added float with info {}", new_info); + debug!("add_float: added float with info {:?}", new_info); let new_float = Float { bounds: LogicalRect::from_point_size( @@ -303,7 +303,7 @@ impl Floats { /// Given placement information, finds the closest place a fragment can be positioned without /// colliding with any floats. pub fn place_between_floats(&self, info: &PlacementInfo) -> LogicalRect<Au> { - debug!("place_between_floats: Placing object with {}", info.size); + debug!("place_between_floats: Placing object with {:?}", info.size); // If no floats, use this fast path. if !self.list.is_present() { @@ -333,7 +333,7 @@ impl Floats { let maybe_location = self.available_rect(float_b, info.size.block, info.max_inline_size); - debug!("place_float: Got available rect: {} for y-pos: {}", maybe_location, float_b); + debug!("place_float: Got available rect: {:?} for y-pos: {:?}", maybe_location, float_b); match maybe_location { // If there are no floats blocking us, return the current location // TODO(eatkinson): integrate with overflow diff --git a/components/layout/flow.rs b/components/layout/flow.rs index bbfb698a2f3..c87088bf829 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -55,9 +55,10 @@ use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use std::mem; use std::fmt; use std::iter::Zip; +use std::num::FromPrimitive; use std::raw; -use std::sync::atomic::{AtomicUint, SeqCst}; -use std::slice::MutItems; +use std::sync::atomic::{AtomicUint, Ordering}; +use std::slice::IterMut; use style::computed_values::{clear, empty_cells, float, position, text_align}; use style::ComputedValues; use std::sync::Arc; @@ -66,7 +67,7 @@ use std::sync::Arc; /// /// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding /// methods to `ImmutableFlowUtils` or `MutableFlowUtils` before adding more methods here. -pub trait Flow: fmt::Show + ToString + Sync { +pub trait Flow: fmt::Show + Sync { // RTTI // // TODO(pcwalton): Use Rust's RTTI, once that works. @@ -82,7 +83,7 @@ pub trait Flow: fmt::Show + ToString + Sync { /// If this is a block flow, returns the underlying object. Fails otherwise. fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow { - debug!("called as_block() on a flow of type {}", self.class()); + debug!("called as_block() on a flow of type {:?}", self.class()); panic!("called as_block() on a non-block flow") } @@ -204,10 +205,10 @@ pub trait Flow: fmt::Show + ToString + Sync { fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self, layout_context: &'a LayoutContext<'a>) -> bool { - let impacted = base(&*self).flags.impacted_by_floats(); + let impacted = base(self).flags.impacted_by_floats(); if impacted { self.assign_block_size(layout_context); - mut_base(&mut *self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); + mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } impacted } @@ -295,7 +296,8 @@ pub trait Flow: fmt::Show + ToString + Sync { /// Returns a layer ID for the given fragment. fn layer_id(&self, fragment_id: uint) -> LayerId { unsafe { - let pointer: uint = mem::transmute(self); + let obj = mem::transmute::<&&Self, &raw::TraitObject>(&self); + let pointer: uint = mem::transmute(obj.data); LayerId(pointer, fragment_id) } } @@ -308,9 +310,9 @@ pub trait Flow: fmt::Show + ToString + Sync { // Base access #[inline(always)] -pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow { +pub fn base<'a, T: ?Sized + Flow>(this: &'a T) -> &'a BaseFlow { unsafe { - let obj = mem::transmute::<&'a Flow, raw::TraitObject>(this); + let obj = mem::transmute::<&&'a T, &'a raw::TraitObject>(&this); mem::transmute::<*mut (), &'a BaseFlow>(obj.data) } } @@ -321,9 +323,9 @@ pub fn imm_child_iter<'a>(flow: &'a Flow) -> FlowListIterator<'a> { } #[inline(always)] -pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow { +pub fn mut_base<'a, T: ?Sized + Flow>(this: &'a mut T) -> &'a mut BaseFlow { unsafe { - let obj = mem::transmute::<&'a mut Flow, raw::TraitObject>(this); + let obj = mem::transmute::<&&'a mut T, &'a raw::TraitObject>(&this); mem::transmute::<*mut (), &'a mut BaseFlow>(obj.data) } } @@ -423,7 +425,7 @@ pub trait MutableOwnedFlowUtils { fn set_absolute_descendants(&mut self, abs_descendants: AbsDescendants); } -#[deriving(Encodable, PartialEq, Show)] +#[derive(RustcEncodable, PartialEq, Show)] pub enum FlowClass { Block, Inline, @@ -465,7 +467,6 @@ 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"] @@ -540,7 +541,7 @@ impl FlowFlags { #[inline] pub fn set_text_align(&mut self, value: text_align::T) { *self = (*self & !TEXT_ALIGN) | - FlowFlags::from_bits(value as u16 << TEXT_ALIGN_SHIFT).unwrap(); + FlowFlags::from_bits((value as u16) << TEXT_ALIGN_SHIFT).unwrap(); } #[inline] @@ -592,7 +593,7 @@ impl FlowFlags { /// The Descendants of a flow. /// /// Also, details about their position wrt this flow. -#[deriving(Clone)] +#[derive(Clone)] pub struct Descendants { /// Links to every descendant. This must be private because it is unsafe to leak `FlowRef`s to /// layout. @@ -650,20 +651,21 @@ impl Descendants { pub type AbsDescendants = Descendants; pub struct DescendantIter<'a> { - iter: MutItems<'a, FlowRef>, + iter: IterMut<'a, FlowRef>, } -impl<'a> Iterator<&'a mut (Flow + 'a)> for DescendantIter<'a> { +impl<'a> Iterator for DescendantIter<'a> { + type Item = &'a mut (Flow + 'a); fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { self.iter.next().map(|flow| &mut **flow) } } -pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, MutItems<'a, Au>>; +pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, IterMut<'a, Au>>; /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be /// confused with absolutely-positioned flows). -#[deriving(Encodable, Copy)] +#[derive(RustcEncodable, Copy)] pub struct AbsolutePositionInfo { /// The size of the containing block for relatively-positioned descendants. pub relative_containing_block_size: LogicalSize<Au>, @@ -776,33 +778,36 @@ pub struct BaseFlow { pub flags: FlowFlags, } +unsafe impl Send for BaseFlow {} +unsafe impl Sync for BaseFlow {} + impl fmt::Show for BaseFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, - "@ {}, CC {}, ADC {}", + "@ {:?}, CC {}, ADC {}", self.position, - self.parallel.children_count.load(SeqCst), + self.parallel.children_count.load(Ordering::SeqCst), self.abs_descendants.len()) } } -impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for BaseFlow { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { e.emit_struct("base", 0, |e| { - try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))) + try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))); try!(e.emit_struct_field("stacking_relative_position", 1, - |e| self.stacking_relative_position.encode(e))) + |e| self.stacking_relative_position.encode(e))); try!(e.emit_struct_field("intrinsic_inline_sizes", 2, - |e| self.intrinsic_inline_sizes.encode(e))) - try!(e.emit_struct_field("position", 3, |e| self.position.encode(e))) + |e| self.intrinsic_inline_sizes.encode(e))); + try!(e.emit_struct_field("position", 3, |e| self.position.encode(e))); e.emit_struct_field("children", 4, |e| { e.emit_seq(self.children.len(), |e| { for (i, c) in self.children.iter().enumerate() { try!(e.emit_seq_elt(i, |e| { try!(e.emit_struct("flow", 0, |e| { - try!(e.emit_struct_field("class", 0, |e| c.class().encode(e))) + try!(e.emit_struct_field("class", 0, |e| c.class().encode(e))); e.emit_struct_field("data", 1, |e| { match c.class() { FlowClass::Block => c.as_immutable_block().encode(e), @@ -815,9 +820,9 @@ impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow { _ => { Ok(()) } // TODO: Support captions } }) - })) + })); Ok(()) - })) + })); } Ok(()) }) @@ -830,7 +835,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow { #[unsafe_destructor] impl Drop for BaseFlow { fn drop(&mut self) { - if self.ref_count.load(SeqCst) != 0 { + if self.ref_count.load(Ordering::SeqCst) != 0 { panic!("Flow destroyed before its ref count hit zero—this is unsafe!") } } @@ -838,7 +843,7 @@ impl Drop for BaseFlow { /// Whether a base flow should be forced to be nonfloated. This can affect e.g. `TableFlow`, which /// is never floated because the table wrapper flow is the floated one. -#[deriving(Clone, PartialEq)] +#[derive(Clone, PartialEq)] pub enum ForceNonfloatedFlag { /// The flow should be floated if the node has a `float` property. FloatIfNecessary, @@ -951,7 +956,7 @@ impl BaseFlow { } if bounds.union(&paint_bounds.bounding_rect()) != bounds { - error!("DisplayList item {} outside of Flow overflow ({})", item, paint_bounds); + error!("DisplayList item {:?} outside of Flow overflow ({:?})", item, paint_bounds); } } } @@ -1125,7 +1130,8 @@ impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) { indent.push_str("| ") } - println!("{}+ {}", indent, self.to_string()); + // TODO: ICE, already fixed in rustc. + //println!("{}+ {:?}", indent, self); for kid in imm_child_iter(self) { kid.dump_with_level(level + 1) diff --git a/components/layout/flow_list.rs b/components/layout/flow_list.rs index c3300e6ab79..4011cd4c400 100644 --- a/components/layout/flow_list.rs +++ b/components/layout/flow_list.rs @@ -15,36 +15,36 @@ pub struct FlowList { } pub struct FlowListIterator<'a> { - it: dlist::Items<'a, FlowRef>, + it: dlist::Iter<'a, FlowRef>, } pub struct MutFlowListIterator<'a> { - it: dlist::MutItems<'a, FlowRef>, + it: dlist::IterMut<'a, FlowRef>, } impl FlowList { /// Provide a reference to the front element, or None if the list is empty #[inline] pub fn front<'a>(&'a self) -> Option<&'a Flow> { - self.flows.front().map(|head| head.deref()) + self.flows.front().map(|head| &**head) } /// Provide a mutable reference to the front element, or None if the list is empty #[inline] pub unsafe fn front_mut<'a>(&'a mut self) -> Option<&'a mut Flow> { - self.flows.front_mut().map(|head| head.deref_mut()) + self.flows.front_mut().map(|head| &mut **head) } /// Provide a reference to the back element, or None if the list is empty #[inline] pub fn back<'a>(&'a self) -> Option<&'a Flow> { - self.flows.back().map(|tail| tail.deref()) + self.flows.back().map(|tail| &**tail) } /// Provide a mutable reference to the back element, or None if the list is empty #[inline] pub unsafe fn back_mut<'a>(&'a mut self) -> Option<&'a mut Flow> { - self.flows.back_mut().map(|tail| tail.deref_mut()) + self.flows.back_mut().map(|tail| &mut **tail) } /// Add an element first in the list @@ -105,10 +105,11 @@ impl FlowList { } } -impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> { +impl<'a> Iterator for FlowListIterator<'a> { + type Item = &'a (Flow + 'a); #[inline] fn next(&mut self) -> Option<&'a (Flow + 'a)> { - self.it.next().map(|x| x.deref()) + self.it.next().map(|x| &**x) } #[inline] @@ -117,10 +118,11 @@ impl<'a> Iterator<&'a (Flow + 'a)> for FlowListIterator<'a> { } } -impl<'a> Iterator<&'a mut (Flow + 'a)> for MutFlowListIterator<'a> { +impl<'a> Iterator for MutFlowListIterator<'a> { + type Item = &'a mut (Flow + 'a); #[inline] fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { - self.it.next().map(|x| x.deref_mut()) + self.it.next().map(|x| &mut **x) } #[inline] diff --git a/components/layout/flow_ref.rs b/components/layout/flow_ref.rs index 67f306d4508..605a7e4ede5 100644 --- a/components/layout/flow_ref.rs +++ b/components/layout/flow_ref.rs @@ -10,15 +10,19 @@ use flow::Flow; use flow; use std::mem; +use std::ops::{Deref, DerefMut}; use std::ptr; use std::raw; -use std::sync::atomic::SeqCst; +use std::sync::atomic::Ordering; #[unsafe_no_drop_flag] pub struct FlowRef { object: raw::TraitObject, } +unsafe impl Send for FlowRef {} +unsafe impl Sync for FlowRef {} + impl FlowRef { pub fn new(mut flow: Box<Flow>) -> FlowRef { unsafe { @@ -33,7 +37,8 @@ impl FlowRef { } } -impl<'a> Deref<Flow + 'a> for FlowRef { +impl<'a> Deref for FlowRef { + type Target = Flow + 'a; fn deref(&self) -> &(Flow + 'a) { unsafe { mem::transmute_copy::<raw::TraitObject, &(Flow + 'a)>(&self.object) @@ -41,7 +46,7 @@ impl<'a> Deref<Flow + 'a> for FlowRef { } } -impl<'a> DerefMut<Flow + 'a> for FlowRef { +impl DerefMut for FlowRef { fn deref_mut<'a>(&mut self) -> &mut (Flow + 'a) { unsafe { mem::transmute_copy::<raw::TraitObject, &mut (Flow + 'a)>(&self.object) @@ -55,7 +60,7 @@ impl Drop for FlowRef { if self.object.vtable.is_null() { return } - if flow::base(&**self).ref_count().fetch_sub(1, SeqCst) > 1 { + if flow::base(&**self).ref_count().fetch_sub(1, Ordering::SeqCst) > 1 { return } let flow_ref: FlowRef = mem::replace(self, FlowRef { @@ -75,7 +80,7 @@ impl Drop for FlowRef { impl Clone for FlowRef { fn clone(&self) -> FlowRef { unsafe { - drop(flow::base(self.deref()).ref_count().fetch_add(1, SeqCst)); + drop(flow::base(&**self).ref_count().fetch_add(1, Ordering::SeqCst)); FlowRef { object: raw::TraitObject { vtable: self.object.vtable, diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 8bad0a288b6..21396838f0c 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -32,15 +32,17 @@ use serialize::{Encodable, Encoder}; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_net::image::holder::ImageHolder; use servo_net::local_image_cache::LocalImageCache; -use servo_util::geometry::{mod, Au, ZERO_POINT}; +use servo_util::geometry::{self, Au, ZERO_POINT}; use servo_util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin}; use servo_util::range::*; use servo_util::smallvec::SmallVec; use servo_util::str::is_whitespace; use std::cmp::{max, min}; use std::fmt; +use std::num::ToPrimitive; use std::str::FromStr; use std::sync::{Arc, Mutex}; +use std::sync::mpsc::Sender; use string_cache::Atom; use style::{ComputedValues, TElement, TNode, cascade_anonymous}; use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto}; @@ -75,7 +77,7 @@ use url::Url; /// /// FIXME(#2260, pcwalton): This can be slimmed down some by (at least) moving `inline_context` /// to be on `InlineFlow` only. -#[deriving(Clone)] +#[derive(Clone)] pub struct Fragment { /// An opaque reference to the DOM node that this `Fragment` originates from. pub node: OpaqueNode, @@ -111,11 +113,14 @@ pub struct Fragment { pub restyle_damage: RestyleDamage, } -impl<E, S: Encoder<E>> Encodable<S, E> for Fragment { - fn encode(&self, e: &mut S) -> Result<(), E> { +unsafe impl Send for Fragment {} +unsafe impl Sync for Fragment {} + +impl Encodable for Fragment { + fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { e.emit_struct("fragment", 0, |e| { - try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))) - try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e))) + try!(e.emit_struct_field("id", 0, |e| self.debug_id().encode(e))); + try!(e.emit_struct_field("border_box", 1, |e| self.border_box.encode(e))); e.emit_struct_field("margin", 2, |e| self.margin.encode(e)) }) } @@ -124,7 +129,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Fragment { /// Info specific to the kind of fragment. /// /// Keep this enum small. As in, no more than one word. Or pcwalton will yell at you. -#[deriving(Clone)] +#[derive(Clone)] pub enum SpecificFragmentInfo { Generic, Iframe(Box<IframeFragmentInfo>), @@ -164,7 +169,7 @@ impl SpecificFragmentInfo { SpecificFragmentInfo::InlineBlock(ref info) => &info.flow_ref, }; - flow::base(flow.deref()).restyle_damage + flow::base(&**flow).restyle_damage } pub fn get_type(&self) -> &'static str { @@ -191,7 +196,7 @@ impl SpecificFragmentInfo { /// /// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout /// can clone it. -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineAbsoluteHypotheticalFragmentInfo { pub flow_ref: FlowRef, } @@ -208,7 +213,7 @@ impl InlineAbsoluteHypotheticalFragmentInfo { /// /// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout /// can clone it. -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineBlockFragmentInfo { pub flow_ref: FlowRef, } @@ -221,7 +226,7 @@ impl InlineBlockFragmentInfo { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct CanvasFragmentInfo { pub replaced_image_fragment_info: ReplacedImageFragmentInfo, pub renderer: Option<Arc<Mutex<Sender<CanvasMsg>>>>, @@ -250,7 +255,7 @@ impl CanvasFragmentInfo { /// A fragment that represents a replaced content image and its accompanying borders, shadows, etc. -#[deriving(Clone)] +#[derive(Clone)] pub struct ImageFragmentInfo { /// The image held within this fragment. pub replaced_image_fragment_info: ReplacedImageFragmentInfo, @@ -309,7 +314,7 @@ impl ImageFragmentInfo { } } -#[deriving(Clone)] +#[derive(Clone)] pub struct ReplacedImageFragmentInfo { pub for_node: UntrustedNodeAddress, pub computed_inline_size: Option<Au>, @@ -479,7 +484,7 @@ impl ReplacedImageFragmentInfo { /// A fragment that represents an inline frame (iframe). This stores the pipeline ID so that the size /// of this iframe can be communicated via the constellation to the iframe's own layout task. -#[deriving(Clone)] +#[derive(Clone)] pub struct IframeFragmentInfo { /// The pipeline ID of this iframe. pub pipeline_id: PipelineId, @@ -502,7 +507,7 @@ impl IframeFragmentInfo { /// may be split into two or more fragments across line breaks. Several `TextFragment`s may /// correspond to a single DOM text node. Split text fragments are implemented by referring to /// subsets of a single `TextRun` object. -#[deriving(Clone)] +#[derive(Clone)] pub struct ScannedTextFragmentInfo { /// The text run that this represents. pub run: Arc<Box<TextRun>>, @@ -543,7 +548,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, Clone)] +#[derive(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. @@ -572,7 +577,7 @@ pub struct SplitResult { /// Data for an unscanned text fragment. Unscanned text fragments are the results of flow /// construction that have not yet had their inline-size determined. -#[deriving(Clone)] +#[derive(Clone)] pub struct UnscannedTextFragmentInfo { /// The text inside the fragment. /// @@ -600,7 +605,7 @@ impl UnscannedTextFragmentInfo { } /// A fragment that represents a table column. -#[deriving(Copy, Clone)] +#[derive(Copy, Clone)] pub struct TableColumnFragmentInfo { /// the number of columns a <col> element should span pub span: int, @@ -743,7 +748,7 @@ impl Fragment { /// if called on any other type of fragment. pub fn save_new_line_pos(&mut self) { match &mut self.specific { - &SpecificFragmentInfo::ScannedText(ref mut info) => { + &mut SpecificFragmentInfo::ScannedText(ref mut info) => { if !info.new_line_pos.is_empty() { info.original_new_line_pos = Some(info.new_line_pos.clone()); } @@ -754,7 +759,7 @@ impl Fragment { pub fn restore_new_line_pos(&mut self) { match &mut self.specific { - &SpecificFragmentInfo::ScannedText(ref mut info) => { + &mut SpecificFragmentInfo::ScannedText(ref mut info) => { match info.original_new_line_pos.take() { None => {} Some(new_line_pos) => info.new_line_pos = new_line_pos, @@ -1278,7 +1283,7 @@ impl Fragment { } SpecificFragmentInfo::ScannedText(ref text_fragment_info) => { let mut new_line_pos = text_fragment_info.new_line_pos.clone(); - let cur_new_line_pos = new_line_pos.remove(0).unwrap(); + let cur_new_line_pos = new_line_pos.remove(0); let inline_start_range = Range::new(text_fragment_info.range.begin(), cur_new_line_pos); @@ -1355,7 +1360,7 @@ impl Fragment { max_inline_size: Au, flags: SplitOptions) -> Option<SplitResult> - where I: Iterator<TextRunSlice<'a>> { + where I: Iterator<Item=TextRunSlice<'a>> { let text_fragment_info = if let SpecificFragmentInfo::ScannedText(ref text_fragment_info) = self.specific { text_fragment_info @@ -1368,15 +1373,15 @@ impl Fragment { let mut inline_start_range = Range::new(text_fragment_info.range.begin(), CharIndex(0)); let mut inline_end_range = None; - debug!("calculate_split_position: splitting text fragment (strlen={}, range={}, \ - max_inline_size={})", + debug!("calculate_split_position: splitting text fragment (strlen={}, range={:?}, \ + max_inline_size={:?})", text_fragment_info.run.text.len(), text_fragment_info.range, max_inline_size); for slice in slice_iterator { - debug!("calculate_split_position: considering slice (offset={}, slice range={}, \ - remaining_inline_size={})", + debug!("calculate_split_position: considering slice (offset={:?}, slice range={:?}, \ + remaining_inline_size={:?})", slice.offset, slice.range, remaining_inline_size); @@ -1408,7 +1413,7 @@ impl Fragment { let mut inline_end = slice.text_run_range(); inline_end.extend_to(text_fragment_info.range.end()); inline_end_range = Some(inline_end); - debug!("calculate_split_position: splitting remainder with inline-end range={}", + debug!("calculate_split_position: splitting remainder with inline-end range={:?}", inline_end); } @@ -1610,7 +1615,7 @@ impl Fragment { } SpecificFragmentInfo::InlineBlock(ref info) => { // See CSS 2.1 § 10.8.1. - let block_flow = info.flow_ref.deref().as_immutable_block(); + let block_flow = info.flow_ref.as_immutable_block(); let font_style = self.style.get_font_arc(); let font_metrics = text::font_metrics_for_style(layout_context.font_context(), font_style); @@ -1816,9 +1821,9 @@ impl Fragment { impl fmt::Show for Fragment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "({} {} ", self.debug_id(), self.specific.get_type())); - try!(write!(f, "bp {}", self.border_padding)); + try!(write!(f, "bp {:?}", self.border_padding)); try!(write!(f, " ")); - try!(write!(f, "m {}", self.margin)); + try!(write!(f, "m {:?}", self.margin)); write!(f, ")") } } @@ -1856,7 +1861,7 @@ pub trait FragmentBorderBoxIterator { /// The coordinate system used in `stacking_relative_border_box()`. See the documentation of that /// method for details. -#[deriving(Clone, PartialEq, Show)] +#[derive(Clone, PartialEq, Show)] pub enum CoordinateSystem { /// The border box returned is relative to the fragment's parent stacking context. Parent, diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index 6949063d41b..1b89015e6aa 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use flow::{mod, Flow}; +use flow::{self, Flow}; use flow::{IS_ABSOLUTELY_POSITIONED}; use std::fmt; @@ -12,7 +12,6 @@ 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."] @@ -125,7 +124,7 @@ macro_rules! add_if_not_equal( $damage.insert($($effect)|*); } }) -) +); pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage { let old: &ComputedValues = diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 67fc65b21e7..aadcd1b310e 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -31,6 +31,8 @@ use servo_util::range::{Range, RangeIndex}; use std::cmp::max; use std::fmt; use std::mem; +use std::num::ToPrimitive; +use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXor}; use std::u16; use style::computed_values::{text_align, vertical_align, white_space}; use style::ComputedValues; @@ -65,7 +67,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, Copy)] +#[derive(RustcEncodable, Show, Copy)] pub struct Line { /// A range of line indices that describe line breaks. /// @@ -150,7 +152,7 @@ pub struct Line { } int_range_index! { - #[deriving(Encodable)] + #[derive(RustcEncodable)] #[doc = "The index of a fragment in a flattened vector of DOM elements."] struct FragmentIndex(int) } @@ -256,7 +258,7 @@ impl LineBreaker { mut old_fragment_iter: I, flow: &'a InlineFlow, layout_context: &LayoutContext) - where I: Iterator<Fragment> { + where I: Iterator<Item=Fragment> { loop { // Acquire the next fragment to lay out from the work list or fragment list, as // appropriate. @@ -305,18 +307,18 @@ impl LineBreaker { /// Note that you probably don't want to call this method directly in order to be /// incremental-reflow-safe; try `next_unbroken_fragment` instead. fn next_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment> - where I: Iterator<Fragment> { + where I: Iterator<Item=Fragment> { if self.work_list.is_empty() { return match old_fragment_iter.next() { None => None, Some(fragment) => { - debug!("LineBreaker: working with fragment from flow: {}", fragment); + debug!("LineBreaker: working with fragment from flow: {:?}", fragment); Some(fragment) } } } - debug!("LineBreaker: working with fragment from work list: {}", self.work_list.front()); + debug!("LineBreaker: working with fragment from work list: {:?}", self.work_list.front()); self.work_list.pop_front() } @@ -325,7 +327,7 @@ impl LineBreaker { /// fragment to lay out, undoing line break operations that any previous reflows may have /// performed. You probably want to be using this method instead of `next_fragment`. fn next_unbroken_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment> - where I: Iterator<Fragment> { + where I: Iterator<Item=Fragment> { let mut result = match self.next_fragment(old_fragment_iter) { None => return None, Some(fragment) => fragment, @@ -342,7 +344,7 @@ impl LineBreaker { }; let need_to_merge = match (&mut result.specific, &candidate.specific) { - (&SpecificFragmentInfo::ScannedText(ref mut result_info), + (&mut SpecificFragmentInfo::ScannedText(ref mut result_info), &SpecificFragmentInfo::ScannedText(ref candidate_info)) if arc_ptr_eq(&result_info.run, &candidate_info.run) && result_info.range.end() + CharIndex(1) == candidate_info.range.begin() => { @@ -362,7 +364,7 @@ impl LineBreaker { /// Commits a line to the list. fn flush_current_line(&mut self) { - debug!("LineBreaker: flushing line {}: {}", self.lines.len(), self.pending_line); + debug!("LineBreaker: flushing line {}: {:?}", self.lines.len(), self.pending_line); self.lines.push(self.pending_line); self.cur_b = self.pending_line.bounds.start.b + self.pending_line.bounds.size.block; self.reset_line(); @@ -388,7 +390,7 @@ impl LineBreaker { first_fragment: &Fragment, ceiling: Au) -> (LogicalRect<Au>, Au) { - debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {}, \ + debug!("LineBreaker: trying to place first fragment of line {}; fragment size: {:?}, \ splittable: {}", self.lines.len(), first_fragment.border_box.size, @@ -496,7 +498,7 @@ impl LineBreaker { .expect("LineBreaker: this split case makes no sense!"); let writing_mode = self.floats.writing_mode; - let split_fragment = |split: SplitInfo| { + let split_fragment = |&:split: SplitInfo| { let info = box ScannedTextFragmentInfo::new(run.clone(), split.range, (*in_fragment.newline_positions() @@ -541,7 +543,7 @@ impl LineBreaker { self.pending_line.green_zone = line_bounds.size; } - debug!("LineBreaker: trying to append to line {} (fragment size: {}, green zone: {}): {}", + debug!("LineBreaker: trying to append to line {} (fragment size: {:?}, green zone: {:?}): {:?}", self.lines.len(), fragment.border_box.size, self.pending_line.green_zone, @@ -586,13 +588,13 @@ impl LineBreaker { match fragment.calculate_split_position(available_inline_size, self.pending_line_is_empty()) { None => { - debug!("LineBreaker: fragment was unsplittable; deferring to next line: {}", + debug!("LineBreaker: fragment was unsplittable; deferring to next line: {:?}", fragment); self.work_list.push_front(fragment); return false } Some(split_result) => { - let split_fragment = |split: SplitInfo| { + let split_fragment = |&:split: SplitInfo| { let info = box ScannedTextFragmentInfo::new(split_result.text_run.clone(), split.range, Vec::new(), @@ -657,7 +659,7 @@ impl LineBreaker { } /// Represents a list of inline fragments, including element ranges. -#[deriving(Encodable, Clone)] +#[derive(RustcEncodable, Clone)] pub struct InlineFragments { /// The fragments themselves. pub fragments: Vec<Fragment>, @@ -665,7 +667,7 @@ pub struct InlineFragments { impl fmt::Show for InlineFragments { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.fragments) + write!(f, "{:?}", self.fragments) } } @@ -711,7 +713,7 @@ impl InlineFragments { } /// Flows for inline layout. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct InlineFlow { /// Data common to all flows. pub base: BaseFlow, @@ -966,7 +968,7 @@ impl Flow for InlineFlow { let mut computation = IntrinsicISizesContribution::new(); for fragment in self.fragments.fragments.iter_mut() { - debug!("Flow: measuring {}", *fragment); + debug!("Flow: measuring {:?}", *fragment); computation.union_inline(&fragment.compute_intrinsic_inline_sizes().finish()) } self.base.intrinsic_inline_sizes = computation.finish() @@ -982,7 +984,7 @@ impl Flow for InlineFlow { // TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into // `Fragment`. - debug!("InlineFlow::assign_inline_sizes: floats in: {}", self.base.floats); + debug!("InlineFlow::assign_inline_sizes: floats in: {:?}", self.base.floats); self.base.position.size.inline = self.base.block_container_inline_size; @@ -1022,7 +1024,7 @@ impl Flow for InlineFlow { // element to determine its block-size for computing the line's own block-size. // // TODO(pcwalton): Cache the line scanner? - debug!("assign_block_size_inline: floats in: {}", self.base.floats); + debug!("assign_block_size_inline: floats in: {:?}", self.base.floats); // Assign the block-size for the inline fragments. let containing_block_block_size = @@ -1194,14 +1196,14 @@ impl Flow for InlineFlow { &stacking_relative_border_box); match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut info) => { - flow::mut_base(info.flow_ref.deref_mut()).clip = clip; + flow::mut_base(&mut *info.flow_ref).clip = clip; let block_flow = info.flow_ref.as_block(); block_flow.base.absolute_position_info = self.base.absolute_position_info; block_flow.base.stacking_relative_position = stacking_relative_border_box.origin; } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => { - flow::mut_base(info.flow_ref.deref_mut()).clip = clip; + flow::mut_base(&mut *info.flow_ref).clip = clip; let block_flow = info.flow_ref.as_block(); block_flow.base.absolute_position_info = self.base.absolute_position_info; block_flow.base.stacking_relative_position = @@ -1254,11 +1256,11 @@ impl Flow for InlineFlow { impl fmt::Show for InlineFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} - {:x} - {}", self.class(), self.base.debug_id(), self.fragments) + write!(f, "{:?} - {:x} - {:?}", self.class(), self.base.debug_id(), self.fragments) } } -#[deriving(Clone)] +#[derive(Clone)] pub struct InlineFragmentContext { pub styles: Vec<Arc<ComputedValues>>, } diff --git a/components/layout/layout_debug.rs b/components/layout/layout_debug.rs index 94ddad456f6..5f0851b1f36 100644 --- a/components/layout/layout_debug.rs +++ b/components/layout/layout_debug.rs @@ -10,13 +10,15 @@ use flow_ref::FlowRef; use flow; use serialize::json; + +use std::borrow::ToOwned; use std::cell::RefCell; use std::io::File; -use std::sync::atomic::{AtomicUint, SeqCst, INIT_ATOMIC_UINT}; +use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT}; -thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None)) +thread_local!(static STATE_KEY: RefCell<Option<State>> = RefCell::new(None)); -static mut DEBUG_ID_COUNTER: AtomicUint = INIT_ATOMIC_UINT; +static mut DEBUG_ID_COUNTER: AtomicUint = ATOMIC_UINT_INIT; pub struct Scope; @@ -29,9 +31,9 @@ macro_rules! layout_debug_scope( layout_debug::Scope } ) -) +); -#[deriving(Encodable)] +#[derive(RustcEncodable)] struct ScopeData { name: String, pre: String, @@ -61,12 +63,12 @@ impl Scope { pub fn new(name: String) -> Scope { 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())); + &mut Some(ref mut state) => { + let flow_trace = json::encode(&flow::base(&*state.flow_root)); let data = box ScopeData::new(name.clone(), flow_trace); state.scope_stack.push(data); } - &None => {} + &mut None => {} } }); Scope @@ -78,13 +80,13 @@ impl Drop for Scope { fn drop(&mut self) { STATE_KEY.with(|ref r| { match &mut *r.borrow_mut() { - &Some(ref mut state) => { + &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())); + current_scope.post = json::encode(&flow::base(&*state.flow_root)); let previous_scope = state.scope_stack.last_mut().unwrap(); previous_scope.children.push(current_scope); } - &None => {} + &mut None => {} } }); } @@ -94,7 +96,7 @@ impl Drop for Scope { /// which are often reallocated but represent essentially the /// same data. pub fn generate_unique_debug_id() -> u16 { - unsafe { DEBUG_ID_COUNTER.fetch_add(1, SeqCst) as u16 } + unsafe { DEBUG_ID_COUNTER.fetch_add(1, Ordering::SeqCst) as u16 } } /// Begin a layout debug trace. If this has not been called, @@ -103,9 +105,9 @@ pub fn begin_trace(flow_root: FlowRef) { 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 flow_trace = json::encode(&flow::base(&*flow_root)); let state = State { - scope_stack: vec![box ScopeData::new("root".into_string(), flow_trace)], + scope_stack: vec![box ScopeData::new("root".to_owned(), flow_trace)], flow_root: flow_root.clone(), }; *r.borrow_mut() = Some(state); @@ -119,7 +121,7 @@ pub fn end_trace() { 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())); + root_scope.post = json::encode(&flow::base(&*task_state.flow_root)); let result = json::encode(&root_scope); let path = Path::new("layout_trace.json"); diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index b8c2385a557..53491dfdc5e 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -7,13 +7,13 @@ use css::node_style::StyledNode; use construct::ConstructionResult; -use context::SharedLayoutContext; -use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; +use context::{SharedLayoutContext, SharedLayoutContextWrapper}; +use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow_ref::FlowRef; use fragment::{Fragment, FragmentBorderBoxIterator}; use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT}; use layout_debug; -use parallel::{mod, UnsafeFlow}; +use parallel::{self, UnsafeFlow}; use sequential; use util::{LayoutDataAccess, LayoutDataWrapper, OpaqueNodeMethods, ToGfxColor}; use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; @@ -59,8 +59,10 @@ use servo_util::task_state; use servo_util::time::{TimeProfilerCategory, ProfilerMetadata, TimeProfilerChan}; use servo_util::time::{TimerMetadataFrameType, TimerMetadataReflowType, profile}; use servo_util::workqueue::WorkQueue; +use std::borrow::ToOwned; use std::cell::Cell; -use std::comm::{channel, Sender, Receiver, Select}; +use std::ops::{Deref, DerefMut}; +use std::sync::mpsc::{channel, Sender, Receiver, Select}; use std::mem; use std::ptr; use style::computed_values::{filter, mix_blend_mode}; @@ -88,7 +90,7 @@ pub struct LayoutTaskData { pub stylist: Box<Stylist>, /// The workers that we use for parallel operation. - pub parallel_traversal: Option<WorkQueue<*const SharedLayoutContext, UnsafeFlow>>, + pub parallel_traversal: Option<WorkQueue<SharedLayoutContextWrapper, UnsafeFlow>>, /// The dirty rect. Used during display list construction. pub dirty: Rect<Au>, @@ -152,19 +154,17 @@ struct LayoutImageResponder { } impl ImageResponder<UntrustedNodeAddress> for LayoutImageResponder { - fn respond(&self) -> proc(ImageResponseMsg, UntrustedNodeAddress):Send { + fn respond(&self) -> Box<Fn(ImageResponseMsg, UntrustedNodeAddress)+Send> { let id = self.id.clone(); let script_chan = self.script_chan.clone(); - let f: proc(ImageResponseMsg, UntrustedNodeAddress):Send = - proc(_, node_address) { - let ScriptControlChan(chan) = script_chan; - 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(), CompositorEvent::ReflowEvent(nodes)))) - }; - f + box move |&:_, node_address| { + let ScriptControlChan(ref chan) = script_chan; + debug!("Dirtying {:x}", node_address.0 as uint); + let mut nodes = SmallVec1::new(); + nodes.vec_push(node_address); + drop(chan.send(ConstellationControlMsg::SendEvent( + id, CompositorEvent::ReflowEvent(nodes)))) + } } } @@ -184,7 +184,7 @@ impl LayoutTaskFactory for LayoutTask { time_profiler_chan: TimeProfilerChan, shutdown_chan: Sender<()>) { let ConstellationChan(con_chan) = constellation_chan.clone(); - spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, proc() { + spawn_named_with_send_on_failure("LayoutTask", task_state::LAYOUT, move || { { // Ensures layout task is destroyed before we send shutdown message let sender = chan.sender(); let layout = @@ -218,20 +218,21 @@ enum RWGuard<'a> { Used(MutexGuard<'a, LayoutTaskData>), } -impl<'a> Deref<LayoutTaskData> for RWGuard<'a> { +impl<'a> Deref for RWGuard<'a> { + type Target = LayoutTaskData; fn deref(&self) -> &LayoutTaskData { match *self { - RWGuard::Held(ref x) => x.deref(), - RWGuard::Used(ref x) => x.deref(), + RWGuard::Held(ref x) => &**x, + RWGuard::Used(ref x) => &**x, } } } -impl<'a> DerefMut<LayoutTaskData> for RWGuard<'a> { +impl<'a> DerefMut for RWGuard<'a> { fn deref_mut(&mut self) -> &mut LayoutTaskData { match *self { - RWGuard::Held(ref mut x) => x.deref_mut(), - RWGuard::Used(ref mut x) => x.deref_mut(), + RWGuard::Held(ref mut x) => &mut **x, + RWGuard::Used(ref mut x) => &mut **x, } } } @@ -256,7 +257,7 @@ impl LayoutTask { let device = Device::new(MediaType::Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.0)); let parallel_traversal = if opts::get().layout_threads != 1 { Some(WorkQueue::new("LayoutWorker", task_state::LAYOUT, - opts::get().layout_threads, ptr::null())) + opts::get().layout_threads, SharedLayoutContextWrapper(ptr::null()))) } else { None }; @@ -291,7 +292,7 @@ impl LayoutTask { /// Starts listening on the port. fn start(self) { - let mut possibly_locked_rw_data = Some(self.rw_data.lock()); + let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap()); while self.handle_request(&mut possibly_locked_rw_data) { // Loop indefinitely. } @@ -346,14 +347,14 @@ impl LayoutTask { match port_to_read { PortToRead::Pipeline => { - match self.pipeline_port.recv() { + match self.pipeline_port.recv().unwrap() { LayoutControlMsg::ExitNowMsg(exit_type) => { self.handle_script_request(Msg::ExitNow(exit_type), possibly_locked_rw_data) } } }, PortToRead::Script => { - let msg = self.port.recv(); + let msg = self.port.recv().unwrap(); self.handle_script_request(msg, possibly_locked_rw_data) } } @@ -369,7 +370,7 @@ impl LayoutTask { possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) -> RWGuard<'a> { match possibly_locked_rw_data.take() { - None => RWGuard::Used(self.rw_data.lock()), + None => RWGuard::Used((*self.rw_data).lock().unwrap()), Some(x) => RWGuard::Held(x), } } @@ -433,7 +434,7 @@ impl LayoutTask { possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { response_chan.send(()); loop { - match self.port.recv() { + match self.port.recv().unwrap() { Msg::ReapLayoutData(dead_layout_data) => { unsafe { LayoutTask::handle_reap_layout_data(dead_layout_data) @@ -461,7 +462,7 @@ impl LayoutTask { { let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); - match rw_data.deref_mut().parallel_traversal { + match (&mut *rw_data).parallel_traversal { None => {} Some(ref mut traversal) => traversal.shutdown(), } @@ -469,7 +470,7 @@ impl LayoutTask { } self.paint_chan.send(PaintMsg::Exit(Some(response_chan), exit_type)); - response_port.recv() + response_port.recv().unwrap() } fn handle_load_stylesheet<'a>(&'a self, @@ -498,8 +499,8 @@ impl LayoutTask { // Find all font-face rules and notify the font cache of them. // GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!) let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); - iter_font_face_rules(&sheet, &rw_data.stylist.device, |family, src| { - self.font_cache_task.add_web_font(family.into_string(), (*src).clone()); + iter_font_face_rules(&sheet, &rw_data.stylist.device, &|&:family, src| { + self.font_cache_task.add_web_font(family.to_owned(), (*src).clone()); }); rw_data.stylist.add_stylesheet(sheet); LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); @@ -643,7 +644,7 @@ impl LayoutTask { flow::mut_base(&mut **layout_root).clip = ClippingRegion::from_rect(&data.page_clip_rect); - let rw_data = rw_data.deref_mut(); + let rw_data = &mut **rw_data; match rw_data.parallel_traversal { None => { sequential::build_display_list_for_subtree(layout_root, shared_layout_context); @@ -687,8 +688,8 @@ impl LayoutTask { root_flow.position.size.to_physical(root_flow.writing_mode) }; let mut display_list = box DisplayList::new(); - flow::mut_base(layout_root.deref_mut()).display_list_building_result - .add_to(&mut *display_list); + flow::mut_base(&mut **layout_root).display_list_building_result + .add_to(&mut *display_list); let paint_layer = Arc::new(PaintLayer::new(layout_root.layer_id(0), color, ScrollPolicy::Scrollable)); @@ -733,7 +734,7 @@ impl LayoutTask { { // Reset the image cache. - let mut local_image_cache = rw_data.local_image_cache.lock(); + let mut local_image_cache = rw_data.local_image_cache.lock().unwrap(); local_image_cache.next_round(self.make_on_image_available_cb()); } @@ -747,7 +748,7 @@ impl LayoutTask { rw_data.screen_size = current_screen_size; // Create a layout context for use throughout the following passes. - let mut shared_layout_context = self.build_shared_layout_context(rw_data.deref(), + let mut shared_layout_context = self.build_shared_layout_context(&*rw_data, node, &data.url); @@ -772,7 +773,7 @@ impl LayoutTask { if needs_reflow { self.try_get_layout_root(*node).map( - |mut flow| LayoutTask::reflow_all_nodes(flow.deref_mut())); + |mut flow| LayoutTask::reflow_all_nodes(&mut *flow)); } let mut layout_root = profile(TimeProfilerCategory::LayoutStyleRecalc, @@ -780,7 +781,7 @@ impl LayoutTask { self.time_profiler_chan.clone(), || { // Perform CSS selector matching and flow construction. - let rw_data = rw_data.deref_mut(); + let rw_data = &mut *rw_data; match rw_data.parallel_traversal { None => { sequential::traverse_dom_preorder(*node, &shared_layout_context); @@ -797,10 +798,9 @@ impl LayoutTask { self.profiler_metadata(data), self.time_profiler_chan.clone(), || { - if opts::get().nonincremental_layout || layout_root.deref_mut() - .compute_layout_damage() + if opts::get().nonincremental_layout || layout_root.compute_layout_damage() .contains(REFLOW_ENTIRE_DOCUMENT) { - layout_root.deref_mut().reflow_entire_document() + layout_root.reflow_entire_document() } }); @@ -819,7 +819,7 @@ impl LayoutTask { self.profiler_metadata(data), self.time_profiler_chan.clone(), || { - let rw_data = rw_data.deref_mut(); + let rw_data = &mut *rw_data; match rw_data.parallel_traversal { None => { // Sequential mode. @@ -946,14 +946,14 @@ impl LayoutRPC for LayoutRPCImpl { // need to compare nodes for equality. Thus we can safely work only with `OpaqueNode`. fn content_box(&self) -> ContentBoxResponse { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); ContentBoxResponse(rw_data.content_box_response) } /// Requests the dimensions of all the content boxes, as in the `getClientRects()` call. fn content_boxes(&self) -> ContentBoxesResponse { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); ContentBoxesResponse(rw_data.content_boxes_response.clone()) } @@ -962,7 +962,7 @@ impl LayoutRPC for LayoutRPCImpl { let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64)); let resp = { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); match rw_data.stacking_context { None => panic!("no root stacking context!"), Some(ref stacking_context) => { @@ -989,7 +989,7 @@ impl LayoutRPC for LayoutRPCImpl { let point = Point2D(Au::from_frac_px(point.x as f64), Au::from_frac_px(point.y as f64)); { let &LayoutRPCImpl(ref rw_data) = self; - let rw_data = rw_data.lock(); + let rw_data = rw_data.lock().unwrap(); match rw_data.stacking_context { None => panic!("no root stacking context!"), Some(ref stacking_context) => { diff --git a/components/layout/lib.rs b/components/layout/lib.rs index 5fc89dbd82d..17812c262c2 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -2,14 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#![feature(globs, macro_rules, phase, thread_local, unsafe_destructor)] +#![feature(thread_local, unsafe_destructor, box_syntax, plugin, int_uint)] #![deny(unused_imports)] #![deny(unused_variables)] #![allow(unrooted_must_root)] #![allow(missing_copy_implementations)] +#![allow(unstable)] -#[phase(plugin, link)] +#[macro_use] extern crate log; extern crate cssparser; @@ -19,17 +20,19 @@ extern crate gfx; extern crate layout_traits; extern crate script; extern crate script_traits; +extern crate "serialize" as rustc_serialize; extern crate serialize; extern crate png; extern crate style; -#[phase(plugin)] +#[macro_use] +#[no_link] #[plugin] extern crate "plugins" as servo_plugins; extern crate "net" as servo_net; extern crate "msg" as servo_msg; -#[phase(plugin, link)] +#[macro_use] extern crate "util" as servo_util; -#[phase(plugin)] +#[no_link] #[macro_use] #[plugin] extern crate string_cache_macros; extern crate string_cache; diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index 296a73454ca..3c4dc8a7fc8 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -24,7 +24,7 @@ use style::computed_values::list_style_type; use std::sync::Arc; /// A block with the CSS `display` property equal to `list-item`. -#[deriving(Show)] +#[derive(Show)] pub struct ListItemFlow { /// Data common to all block flows. pub block_flow: BlockFlow, diff --git a/components/layout/model.rs b/components/layout/model.rs index a031a5b0537..b83585906ad 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -18,7 +18,7 @@ use std::cmp::{max, min}; use std::fmt; /// A collapsible margin. See CSS 2.1 § 8.3.1. -#[deriving(Copy)] +#[derive(Copy)] pub struct AdjoiningMargins { /// The value of the greatest positive margin. pub most_positive: Au, @@ -61,7 +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)] +#[derive(Copy)] pub enum CollapsibleMargins { /// Margins may not collapse with this flow. None(Au, Au), @@ -239,14 +239,14 @@ impl MarginCollapseInfo { } } -#[deriving(Copy)] +#[derive(Copy)] pub enum MarginCollapseState { AccumulatingCollapsibleTopMargin, AccumulatingMarginIn, } /// Intrinsic inline-sizes, which consist of minimum and preferred. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct IntrinsicISizes { /// The *minimum inline-size* of the content. pub minimum_inline_size: Au, @@ -256,7 +256,7 @@ pub struct IntrinsicISizes { impl fmt::Show for IntrinsicISizes { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "min={}, pref={}", self.minimum_inline_size, self.preferred_inline_size) + write!(f, "min={:?}, pref={:?}", self.minimum_inline_size, self.preferred_inline_size) } } @@ -325,7 +325,7 @@ impl IntrinsicISizesContribution { } /// Useful helper data type when computing values for blocks and positioned elements. -#[deriving(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] pub enum MaybeAuto { Auto, Specified(Au), @@ -358,7 +358,7 @@ impl MaybeAuto { } #[inline] - pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto { + pub fn map<F>(&self, mapper: F) -> MaybeAuto where F: FnOnce(Au) -> Au { match *self { MaybeAuto::Auto => MaybeAuto::Auto, MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)), diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index a6a20ad33ba..05eb9168a04 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -6,7 +6,7 @@ //! //! This code is highly unsafe. Keep this file small and easy to audit. -use context::{LayoutContext, SharedLayoutContext}; +use context::{LayoutContext, SharedLayoutContextWrapper, SharedLayoutContext}; use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal}; use flow; use flow_ref::FlowRef; @@ -23,7 +23,7 @@ use servo_util::time::{TimeProfilerCategory, ProfilerMetadata, TimeProfilerChan, use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy}; use std::mem; use std::ptr; -use std::sync::atomic::{AtomicInt, Relaxed, SeqCst}; +use std::sync::atomic::{AtomicInt, Ordering}; #[allow(dead_code)] fn static_assertion(node: UnsafeLayoutNode) { @@ -81,17 +81,17 @@ impl DomParallelInfo { pub trait ParallelPreorderDomTraversal : PreorderDomTraversal { fn run_parallel(&self, node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>); + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>); #[inline(always)] fn run_parallel_helper(&self, unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>, + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>, top_down_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>), bottom_up_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>)) { // Get a real layout node. let node: LayoutNode = unsafe { @@ -108,7 +108,7 @@ pub trait ParallelPreorderDomTraversal : PreorderDomTraversal { { let mut layout_data_ref = node.mutate_layout_data(); let layout_data = layout_data_ref.as_mut().expect("no layout data"); - layout_data.data.parallel.children_count.store(child_count as int, Relaxed); + layout_data.data.parallel.children_count.store(child_count as int, Ordering::Relaxed); } // Possibly enqueue the children. @@ -141,7 +141,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { /// fetch-and-subtract the parent's children count. fn run_parallel(&self, mut unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>) { loop { // Get a real layout node. let node: LayoutNode = unsafe { @@ -151,7 +151,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { // Perform the appropriate traversal. self.process(node); - let shared_layout_context = unsafe { &**proxy.user_data() }; + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let parent = @@ -173,7 +173,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal { .data .parallel .children_count - .fetch_sub(1, SeqCst) == 1 { + .fetch_sub(1, Ordering::SeqCst) == 1 { // We were the last child of our parent. Construct flows for our parent. } else { // Get out of here and find another node to work on. @@ -216,22 +216,22 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { /// fetch-and-subtract the parent's children count. fn run_parallel(&self, mut unsafe_flow: UnsafeFlow, - _: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + _: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { loop { unsafe { // Get a real flow. let flow: &mut FlowRef = mem::transmute(&unsafe_flow); // Perform the appropriate traversal. - if self.should_process(flow.deref_mut()) { - self.process(flow.deref_mut()); + if self.should_process(&mut **flow) { + self.process(&mut **flow); } - let base = flow::mut_base(flow.deref_mut()); + let base = flow::mut_base(&mut **flow); // Reset the count of children for the next layout traversal. - base.parallel.children_count.store(base.children.len() as int, Relaxed); + base.parallel.children_count.store(base.children.len() as int, Ordering::Relaxed); // Possibly enqueue the parent. let unsafe_parent = base.parallel.parent; @@ -244,8 +244,8 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { // of our parent to finish processing? If so, we can continue // on with our parent; otherwise, we've gotta wait. let parent: &mut FlowRef = mem::transmute(&unsafe_parent); - let parent_base = flow::mut_base(parent.deref_mut()); - if parent_base.parallel.children_count.fetch_sub(1, SeqCst) == 1 { + let parent_base = flow::mut_base(&mut **parent); + if parent_base.parallel.children_count.fetch_sub(1, Ordering::SeqCst) == 1 { // We were the last child of our parent. Reflow our parent. unsafe_flow = unsafe_parent } else { @@ -261,30 +261,30 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { fn run_parallel(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>); + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>); #[inline(always)] fn run_parallel_helper(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>, + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>, top_down_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>), bottom_up_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*const SharedLayoutContext, + &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>)) { let mut had_children = false; unsafe { // Get a real flow. let flow: &mut FlowRef = mem::transmute(&unsafe_flow); - if self.should_process(flow.deref_mut()) { + if self.should_process(&mut **flow) { // Perform the appropriate traversal. - self.process(flow.deref_mut()); + self.process(&mut **flow); } // Possibly enqueue the children. - for kid in flow::child_iter(flow.deref_mut()) { + for kid in flow::child_iter(&mut **flow) { had_children = true; proxy.push(WorkUnit { fun: top_down_func, @@ -306,7 +306,7 @@ impl<'a> ParallelPostorderFlowTraversal for BubbleISizes<'a> {} impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> { fn run_parallel(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { self.run_parallel_helper(unsafe_flow, proxy, assign_inline_sizes, @@ -319,7 +319,7 @@ impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {} impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> { fn run_parallel(&self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) { self.run_parallel_helper(unsafe_flow, proxy, compute_absolute_positions, @@ -334,7 +334,7 @@ impl<'a> ParallelPostorderDomTraversal for ConstructFlows<'a> {} impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> { fn run_parallel(&self, unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) { + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) { self.run_parallel_helper(unsafe_node, proxy, recalc_style, @@ -343,8 +343,8 @@ impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> { } fn recalc_style(unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let recalc_style_for_node_traversal = RecalcStyleForNode { layout_context: &layout_context, @@ -353,8 +353,8 @@ fn recalc_style(unsafe_node: UnsafeLayoutNode, } fn construct_flows(unsafe_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNode>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let construct_flows_traversal = ConstructFlows { layout_context: &layout_context, @@ -363,8 +363,8 @@ fn construct_flows(unsafe_node: UnsafeLayoutNode, } fn assign_inline_sizes(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let assign_inline_sizes_traversal = AssignISizes { layout_context: &layout_context, @@ -373,8 +373,8 @@ fn assign_inline_sizes(unsafe_flow: UnsafeFlow, } fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow { layout_context: &layout_context, @@ -383,8 +383,8 @@ fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow, } fn compute_absolute_positions(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let compute_absolute_positions_traversal = ComputeAbsolutePositions { layout_context: &layout_context, @@ -393,8 +393,8 @@ fn compute_absolute_positions(unsafe_flow: UnsafeFlow, } fn build_display_list(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) { - let shared_layout_context = unsafe { &**proxy.user_data() }; + proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlow>) { + let shared_layout_context = unsafe { &*(proxy.user_data().0) }; let layout_context = LayoutContext::new(shared_layout_context); let build_display_list_traversal = BuildDisplayList { @@ -406,8 +406,8 @@ fn build_display_list(unsafe_flow: UnsafeFlow, pub fn traverse_dom_preorder(root: LayoutNode, shared_layout_context: &SharedLayoutContext, - queue: &mut WorkQueue<*const SharedLayoutContext, UnsafeLayoutNode>) { - queue.data = shared_layout_context as *const _; + queue: &mut WorkQueue<SharedLayoutContextWrapper, UnsafeLayoutNode>) { + queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _); queue.push(WorkUnit { fun: recalc_style, @@ -416,21 +416,21 @@ pub fn traverse_dom_preorder(root: LayoutNode, queue.run(); - queue.data = ptr::null(); + queue.data = SharedLayoutContextWrapper(ptr::null()); } pub fn traverse_flow_tree_preorder(root: &mut FlowRef, profiler_metadata: ProfilerMetadata, time_profiler_chan: TimeProfilerChan, shared_layout_context: &SharedLayoutContext, - queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) { + queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) { if opts::get().bubble_inline_sizes_separately { let layout_context = LayoutContext::new(shared_layout_context); let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; - root.deref_mut().traverse_postorder(&bubble_inline_sizes); + root.traverse_postorder(&bubble_inline_sizes); } - queue.data = shared_layout_context as *const _; + queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _); profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata, time_profiler_chan, || { @@ -442,15 +442,15 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef, queue.run(); - queue.data = ptr::null() + queue.data = SharedLayoutContextWrapper(ptr::null()) } pub fn build_display_list_for_subtree(root: &mut FlowRef, profiler_metadata: ProfilerMetadata, time_profiler_chan: TimeProfilerChan, shared_layout_context: &SharedLayoutContext, - queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) { - queue.data = shared_layout_context as *const _; + queue: &mut WorkQueue<SharedLayoutContextWrapper,UnsafeFlow>) { + queue.data = SharedLayoutContextWrapper(shared_layout_context as *const _); profile(TimeProfilerCategory::LayoutParallelWarmup, profiler_metadata, time_profiler_chan, || { @@ -462,5 +462,5 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef, queue.run(); - queue.data = ptr::null() + queue.data = SharedLayoutContextWrapper(ptr::null()) } diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 1be77041113..ff2bd948c51 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -5,7 +5,7 @@ //! Implements sequential traversals over the DOM and flow trees. use context::{LayoutContext, SharedLayoutContext}; -use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, PostorderFlowTraversal}; +use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, PostorderFlowTraversal}; use flow::{PreorderFlowTraversal}; use flow_ref::FlowRef; use fragment::FragmentBorderBoxIterator; @@ -59,7 +59,7 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef, let layout_context = LayoutContext::new(shared_layout_context); - let root = root.deref_mut(); + let root = &mut **root; if opts::get().bubble_inline_sizes_separately { let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context }; @@ -94,7 +94,7 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef, let compute_absolute_positions = ComputeAbsolutePositions { layout_context: &layout_context }; let build_display_list = BuildDisplayList { layout_context: &layout_context }; - doit(root.deref_mut(), compute_absolute_positions, build_display_list); + doit(&mut **root, compute_absolute_positions, build_display_list); } pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef, @@ -117,5 +117,5 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef, } } - doit(root.deref_mut(), iterator, &ZERO_POINT); + doit(&mut **root, iterator, &ZERO_POINT); } diff --git a/components/layout/table.rs b/components/layout/table.rs index 0dd9f9caa08..533d5166dbd 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -11,7 +11,7 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution}; use construct::FlowConstructor; use context::LayoutContext; use floats::FloatKind; -use flow::{mod, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; +use flow::{self, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; use flow::ImmutableFlowUtils; use fragment::{Fragment, FragmentBorderBoxIterator}; use layout_debug; @@ -32,7 +32,7 @@ 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, /// not table fragment per CSS 2.1 § 10.5. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableFlow { pub block_flow: BlockFlow, @@ -399,7 +399,7 @@ impl Flow for TableFlow { impl fmt::Show for TableFlow { /// Outputs a debugging string describing this table flow. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableFlow: {}", self.block_flow) + write!(f, "TableFlow: {:?}", self.block_flow) } } @@ -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, Copy)] +#[derive(Clone, RustcEncodable, 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, Copy)] +#[derive(RustcEncodable, 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 938bfa0e0d2..d45bd50e91b 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -95,6 +95,6 @@ impl Flow for TableCaptionFlow { impl fmt::Show for TableCaptionFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableCaptionFlow: {}", self.block_flow) + write!(f, "TableCaptionFlow: {:?}", self.block_flow) } } diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 89eea551c73..c80a4135f9f 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -22,7 +22,7 @@ use style::{UnsignedIntegerAttribute, ComputedValues}; use std::sync::Arc; /// A table formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableCellFlow { /// Data common to all block flows. pub block_flow: BlockFlow, @@ -176,6 +176,6 @@ impl Flow for TableCellFlow { impl fmt::Show for TableCellFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableCellFlow: {}", self.block_flow) + write!(f, "TableCellFlow: {:?}", self.block_flow) } } diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 648c1ae125c..f828bcc658a 100644 --- a/components/layout/table_colgroup.rs +++ b/components/layout/table_colgroup.rs @@ -109,7 +109,7 @@ impl Flow for TableColGroupFlow { impl fmt::Show for TableColGroupFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.fragment { - Some(ref rb) => write!(f, "TableColGroupFlow: {}", rb), + Some(ref rb) => write!(f, "TableColGroupFlow: {:?}", rb), None => write!(f, "TableColGroupFlow"), } } diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 55bc3634efa..eb06b31cfec 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -27,7 +27,7 @@ use style::computed_values::LengthOrPercentageOrAuto; use std::sync::Arc; /// A single row of a table. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableRowFlow { pub block_flow: BlockFlow, @@ -39,7 +39,7 @@ pub struct TableRowFlow { } /// Information about the column inline size and span for each cell. -#[deriving(Encodable, Copy)] +#[derive(RustcEncodable, Copy)] pub struct CellIntrinsicInlineSize { /// Inline sizes that this cell contributes to the column. pub column_size: ColumnIntrinsicInlineSize, @@ -329,6 +329,6 @@ impl Flow for TableRowFlow { impl fmt::Show for TableRowFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableRowFlow: {}", self.block_flow.fragment) + write!(f, "TableRowFlow: {:?}", self.block_flow.fragment) } } diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 80647a01a77..00a0f23c1b5 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -22,7 +22,7 @@ use style::ComputedValues; use std::sync::Arc; /// A table formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableRowGroupFlow { /// Fields common to all block flows. pub block_flow: BlockFlow, @@ -164,6 +164,6 @@ impl Flow for TableRowGroupFlow { impl fmt::Show for TableRowGroupFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TableRowGroupFlow: {}", self.block_flow.fragment) + write!(f, "TableRowGroupFlow: {:?}", self.block_flow.fragment) } } diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index d696de85ddc..6cb69a8b216 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -27,18 +27,19 @@ use geom::{Point2D, Rect}; use servo_util::geometry::Au; use std::cmp::{max, min}; use std::fmt; +use std::ops::Add; use style::{ComputedValues, CSSFloat}; use style::computed_values::{table_layout, LengthOrPercentageOrAuto}; use std::sync::Arc; -#[deriving(Copy, Encodable, Show)] +#[derive(Copy, RustcEncodable, Show)] pub enum TableLayout { Fixed, Auto } /// A table wrapper flow based on a block formatting context. -#[deriving(Encodable)] +#[derive(RustcEncodable)] pub struct TableWrapperFlow { pub block_flow: BlockFlow, @@ -144,11 +145,11 @@ impl TableWrapperFlow { // Compute all the guesses for the column sizes, and sum them. let mut total_guess = AutoLayoutCandidateGuess::new(); let guesses: Vec<AutoLayoutCandidateGuess> = - self.column_intrinsic_inline_sizes.iter().map(|column_intrinsic_inline_size| { + self.column_intrinsic_inline_sizes.iter().map(|&mut:column_intrinsic_inline_size| { let guess = AutoLayoutCandidateGuess::from_column_intrinsic_inline_size( column_intrinsic_inline_size, available_inline_size); - total_guess = total_guess + guess; + total_guess = &total_guess + &guess; guess }).collect(); @@ -383,9 +384,9 @@ impl Flow for TableWrapperFlow { impl fmt::Show for TableWrapperFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.block_flow.base.flags.is_float() { - write!(f, "TableWrapperFlow(Float): {}", self.block_flow.fragment) + write!(f, "TableWrapperFlow(Float): {:?}", self.block_flow.fragment) } else { - write!(f, "TableWrapperFlow: {}", self.block_flow.fragment) + write!(f, "TableWrapperFlow: {:?}", self.block_flow.fragment) } } } @@ -482,9 +483,10 @@ impl AutoLayoutCandidateGuess { } } -impl Add<AutoLayoutCandidateGuess,AutoLayoutCandidateGuess> for AutoLayoutCandidateGuess { +impl<'a> Add for &'a AutoLayoutCandidateGuess { + type Output = AutoLayoutCandidateGuess; #[inline] - fn add(&self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess { + fn add(self, other: &AutoLayoutCandidateGuess) -> AutoLayoutCandidateGuess { AutoLayoutCandidateGuess { minimum_guess: self.minimum_guess + other.minimum_guess, minimum_percentage_guess: @@ -497,7 +499,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(Copy, PartialEq, Show)] +#[derive(Copy, PartialEq, Show)] enum SelectedAutoLayoutCandidateGuess { UseMinimumGuess, InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(CSSFloat), diff --git a/components/layout/text.rs b/components/layout/text.rs index f57aee50f7b..ca23fdc12de 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -14,7 +14,7 @@ use gfx::font::{RunMetrics, ShapingFlags, ShapingOptions}; use gfx::font_context::FontContext; use gfx::text::glyph::CharIndex; use gfx::text::text_run::TextRun; -use gfx::text::util::{mod, CompressionMode}; +use gfx::text::util::{self, CompressionMode}; use servo_util::dlist; use servo_util::geometry::Au; use servo_util::logical_geometry::{LogicalSize, WritingMode}; @@ -138,7 +138,7 @@ impl TextRunScanner { }; let mut new_line_pos = Vec::new(); - let old_length = CharIndex(run_text.as_slice().char_len() as int); + let old_length = CharIndex(run_text.chars().count() as int); last_whitespace = util::transform_text(in_fragment.as_slice(), compression, last_whitespace, @@ -146,7 +146,7 @@ impl TextRunScanner { &mut new_line_pos); new_line_positions.push(NewLinePositions(new_line_pos)); - let added_chars = CharIndex(run_text.as_slice().char_len() as int) - old_length; + let added_chars = CharIndex(run_text.chars().count() as int) - old_length; new_ranges.push(Range::new(char_total, added_chars)); char_total = char_total + added_chars; } @@ -195,13 +195,13 @@ impl TextRunScanner { let range = *new_ranges.get(logical_offset); if range.is_empty() { debug!("Elided an `SpecificFragmentInfo::UnscannedText` because it was zero-length after \ - compression; {}", + compression; {:?}", old_fragment); continue } let text_size = old_fragment.border_box.size; - let &NewLinePositions(ref mut new_line_positions) = + let &mut NewLinePositions(ref mut new_line_positions) = new_line_positions.get_mut(logical_offset); let new_text_fragment_info = box ScannedTextFragmentInfo::new(run.clone(), diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index bafd242fc31..c76c654dcf5 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -48,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. -thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None)) +thread_local!(static STYLE_BLOOM: RefCell<Option<(Box<BloomFilter>, UnsafeLayoutNode, Generation)>> = RefCell::new(None)); /// Returns the task local bloom filter. /// @@ -74,7 +74,7 @@ fn take_task_local_bloom_filter(parent_node: Option<LayoutNode>, layout_context: // 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()); + debug!("[{}] Parent matches (={}). Reusing bloom filter.", tid(), old_node.0); bloom_filter.clone() } else { // Oh no. the cached parent is stale. I guess we need a new one. Reuse the existing @@ -120,7 +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)] +#[derive(Copy)] pub struct RecalcStyleForNode<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -200,7 +200,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { // Before running the children, we need to insert our nodes into the bloom // filter. - debug!("[{}] + {:X}", tid(), unsafe_layout_node.val0()); + debug!("[{}] + {:X}", tid(), unsafe_layout_node.0); node.insert_into_bloom_filter(&mut *bf); // NB: flow construction updates the bloom filter on the way up. @@ -209,7 +209,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> { } /// The flow construction traversal, which builds flows for styled nodes. -#[deriving(Copy)] +#[derive(Copy)] pub struct ConstructFlows<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -258,7 +258,7 @@ impl<'a> PostorderDomTraversal for ConstructFlows<'a> { match node.layout_parent_node(self.layout_context.shared) { None => { - debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.val0()); + debug!("[{}] - {:X}, and deleting BF.", tid(), unsafe_layout_node.0); // If this is the reflow root, eat the task-local bloom filter. } Some(parent) => { @@ -308,7 +308,7 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> { } /// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`. -#[deriving(Copy)] +#[derive(Copy)] pub struct AssignISizes<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -329,7 +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)] +#[derive(Copy)] pub struct AssignBSizesAndStoreOverflow<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -354,7 +354,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> { } } -#[deriving(Copy)] +#[derive(Copy)] pub struct ComputeAbsolutePositions<'a> { pub layout_context: &'a LayoutContext<'a>, } @@ -366,7 +366,7 @@ impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> { } } -#[deriving(Copy)] +#[derive(Copy)] pub struct BuildDisplayList<'a> { pub layout_context: &'a LayoutContext<'a>, } diff --git a/components/layout/util.rs b/components/layout/util.rs index 0ba105f20fa..206590d7c23 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -64,7 +64,6 @@ impl PrivateLayoutData { } bitflags! { - #[deriving(Copy)] flags LayoutDataFlags: u8 { #[doc="Whether a flow has been newly constructed."] const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01 @@ -77,6 +76,14 @@ pub struct LayoutDataWrapper { pub data: Box<PrivateLayoutData>, } +#[allow(dead_code)] +fn static_assertion(x: Option<LayoutDataWrapper>) { + unsafe { + let _: Option<::script::dom::node::LayoutData> = + ::std::intrinsics::transmute(x); + } +} + /// A trait that allows access to the layout data of a DOM node. pub trait LayoutDataAccess { /// Borrows the layout data without checks. diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 1dd4be42288..d54af90014a 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -49,8 +49,8 @@ use script::dom::htmlelement::HTMLElementTypeId; use script::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers}; use script::dom::htmliframeelement::HTMLIFrameElement; use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers; -use script::dom::htmlinputelement::LayoutHTMLInputElementHelpers; -use script::dom::htmltextareaelement::LayoutHTMLTextAreaElementHelpers; +use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers}; +use script::dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers}; use script::dom::node::{Node, NodeTypeId}; use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers, SharedLayoutData}; use script::dom::node::{HAS_CHANGED, IS_DIRTY, HAS_DIRTY_SIBLINGS, HAS_DIRTY_DESCENDANTS}; @@ -58,8 +58,9 @@ use script::dom::text::Text; use script::layout_interface::LayoutChan; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace}; -use std::kinds::marker::ContravariantLifetime; +use std::marker::ContravariantLifetime; use std::mem; +use std::sync::mpsc::Sender; use string_cache::{Atom, Namespace}; use style::computed_values::{content, display, white_space}; use style::{NamespaceConstraint, AttrSelector, IntegerAttribute}; @@ -67,6 +68,7 @@ use style::{LengthAttribute, PropertyDeclarationBlock, SimpleColorAttribute}; use style::{TElement, TElementAttributes, TNode, UnsignedIntegerAttribute}; use url::Url; +use std::borrow::ToOwned; use std::cell::{Ref, RefMut}; /// Allows some convenience methods on generic layout nodes. @@ -160,7 +162,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)] +#[derive(Copy)] pub struct LayoutNode<'a> { /// The wrapped node. node: JS<Node>, @@ -211,15 +213,20 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { fn text(&self) -> String { unsafe { - if let Some(text) = TextCast::to_js(self.get_jsmanaged()) { - (*text.unsafe_get()).characterdata().data_for_layout().into_string() - } else if let Some(input) = HTMLInputElementCast::to_js(self.get_jsmanaged()) { - input.get_value_for_layout() - } else if let Some(area) = HTMLTextAreaElementCast::to_js(self.get_jsmanaged()) { - area.get_value_for_layout() - } else { - panic!("not text!") + let text: Option<JS<Text>> = TextCast::to_js(self.get_jsmanaged()); + if let Some(text) = text { + return (*text.unsafe_get()).characterdata().data_for_layout().to_owned(); + } + let input: Option<JS<HTMLInputElement>> = HTMLInputElementCast::to_js(self.get_jsmanaged()); + if let Some(input) = input { + return input.get_value_for_layout(); } + let area: Option<JS<HTMLTextAreaElement>> = HTMLTextAreaElementCast::to_js(self.get_jsmanaged()); + if let Some(area) = area { + return area.get_value_for_layout(); + } + + panic!("not text!") } } } @@ -244,7 +251,7 @@ impl<'ln> LayoutNode<'ln> { } fn debug_str(self) -> String { - format!("{}: changed={} dirty={} dirty_descendants={}", + format!("{:?}: changed={} dirty={} dirty_descendants={}", self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) } @@ -324,7 +331,7 @@ impl<'ln> LayoutNode<'ln> { pub fn debug_id(self) -> uint { let opaque: OpaqueNode = OpaqueNodeMethods::from_layout_node(&self); - opaque.to_untrusted_node_address() as uint + opaque.to_untrusted_node_address().0 as uint } } @@ -368,10 +375,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { None => panic!("not an element") }; - let element = &*elem.unsafe_get(); - LayoutElement { - element: mem::transmute(element), + element: &*elem.unsafe_get(), } } } @@ -384,8 +389,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { self.node_is_document() } - fn match_attr(self, attr: &AttrSelector, test: |&str| -> bool) -> bool { - assert!(self.is_element()) + fn match_attr<F>(self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool { + assert!(self.is_element()); let name = if self.is_html_element_in_html_document() { &attr.lower_name } else { @@ -449,7 +454,8 @@ pub struct LayoutNodeChildrenIterator<'a> { current: Option<LayoutNode<'a>>, } -impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> { +impl<'a> Iterator for LayoutNodeChildrenIterator<'a> { + type Item = LayoutNode<'a>; fn next(&mut self) -> Option<LayoutNode<'a>> { let node = self.current; self.current = node.and_then(|node| node.next_sibling()); @@ -461,7 +467,8 @@ pub struct LayoutNodeReverseChildrenIterator<'a> { current: Option<LayoutNode<'a>>, } -impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeReverseChildrenIterator<'a> { +impl<'a> Iterator for LayoutNodeReverseChildrenIterator<'a> { + type Item = LayoutNode<'a>; fn next(&mut self) -> Option<LayoutNode<'a>> { let node = self.current; self.current = node.and_then(|node| node.prev_sibling()); @@ -483,7 +490,8 @@ impl<'a> LayoutTreeIterator<'a> { } } -impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { +impl<'a> Iterator for LayoutTreeIterator<'a> { + type Item = LayoutNode<'a>; fn next(&mut self) -> Option<LayoutNode<'a>> { let ret = self.stack.pop(); ret.map(|node| self.stack.extend(node.rev_children())); @@ -492,7 +500,7 @@ impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { } /// A wrapper around elements that ensures layout can only ever access safe properties. -#[deriving(Copy)] +#[derive(Copy)] pub struct LayoutElement<'le> { element: &'le Element, } @@ -531,7 +539,8 @@ impl<'le> TElement<'le> for LayoutElement<'le> { fn get_link(self) -> Option<&'le str> { // FIXME: This is HTML only. - match NodeCast::from_actual(self.element).type_id_for_layout() { + let node: &Node = NodeCast::from_actual(self.element); + match node.type_id_for_layout() { // http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html# // selector-link NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | @@ -548,7 +557,8 @@ impl<'le> TElement<'le> for LayoutElement<'le> { #[inline] fn get_hover_state(self) -> bool { unsafe { - NodeCast::from_actual(self.element).get_hover_state_for_layout() + let node: &Node = NodeCast::from_actual(self.element); + node.get_hover_state_for_layout() } } @@ -562,14 +572,16 @@ impl<'le> TElement<'le> for LayoutElement<'le> { #[inline] fn get_disabled_state(self) -> bool { unsafe { - NodeCast::from_actual(self.element).get_disabled_state_for_layout() + let node: &Node = NodeCast::from_actual(self.element); + node.get_disabled_state_for_layout() } } #[inline] fn get_enabled_state(self) -> bool { unsafe { - NodeCast::from_actual(self.element).get_enabled_state_for_layout() + let node: &Node = NodeCast::from_actual(self.element); + node.get_enabled_state_for_layout() } } @@ -595,7 +607,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> { } #[inline(always)] - fn each_class(self, callback: |&Atom|) { + fn each_class<F>(self, mut callback: F) where F: FnMut(&Atom) { unsafe { match self.element.get_classes_for_layout() { None => {} @@ -652,14 +664,14 @@ fn get_content(content_list: &content::T) -> String { let iter = &mut value.clone().into_iter().peekable(); match iter.next() { Some(content::ContentItem::StringContent(content)) => content, - _ => "".into_string(), + _ => "".to_owned(), } } - _ => "".into_string(), + _ => "".to_owned(), } } -#[deriving(Copy, PartialEq, Clone)] +#[derive(Copy, PartialEq, Clone)] pub enum PseudoElementType { Normal, Before(display::T), @@ -684,7 +696,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(Copy, Clone)] +#[derive(Copy, Clone)] pub struct ThreadSafeLayoutNode<'ln> { /// The wrapped node. node: LayoutNode<'ln>, @@ -718,7 +730,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { } unsafe fn get<'a>(&'a self) -> &'a Node { // this change. - mem::transmute::<*mut Node,&'a Node>(self.get_jsmanaged().unsafe_get()) + &*self.get_jsmanaged().unsafe_get() } fn first_child(&self) -> Option<ThreadSafeLayoutNode<'ln>> { @@ -818,7 +830,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on // implementations. ThreadSafeLayoutElement { - element: &mut *element, + element: &*element, } } } @@ -947,7 +959,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_input_value(&self) -> String { unsafe { - match HTMLInputElementCast::to_js(self.get_jsmanaged()) { + let input: Option<JS<HTMLInputElement>> = HTMLInputElementCast::to_js(self.get_jsmanaged()); + match input { Some(input) => input.get_value_for_layout(), None => panic!("not an input element!") } @@ -966,7 +979,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option<u32> { unsafe { - match ElementCast::to_js(self.get_jsmanaged()) { + let elem: Option<JS<Element>> = ElementCast::to_js(self.get_jsmanaged()); + match elem { Some(element) => { (*element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute) } @@ -986,7 +1000,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn set_restyle_damage(self, damage: RestyleDamage) { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.restyle_damage = damage, + &mut Some(ref mut layout_data) => layout_data.data.restyle_damage = damage, _ => panic!("no layout data for this node"), } } @@ -1005,7 +1019,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn insert_flags(self, new_flags: LayoutDataFlags) { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.flags.insert(new_flags), + &mut Some(ref mut layout_data) => layout_data.data.flags.insert(new_flags), _ => panic!("no layout data for this node"), } } @@ -1014,7 +1028,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn remove_flags(self, flags: LayoutDataFlags) { let mut layout_data_ref = self.mutate_layout_data(); match &mut *layout_data_ref { - &Some(ref mut layout_data) => layout_data.data.flags.remove(flags), + &mut Some(ref mut layout_data) => layout_data.data.flags.remove(flags), _ => panic!("no layout data for this node"), } } @@ -1034,7 +1048,8 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'a> { parent_node: Option<ThreadSafeLayoutNode<'a>>, } -impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIterator<'a> { +impl<'a> Iterator for ThreadSafeLayoutNodeChildrenIterator<'a> { + type Item = ThreadSafeLayoutNode<'a>; fn next(&mut self) -> Option<ThreadSafeLayoutNode<'a>> { let node = self.current_node.clone(); |