diff --git a/components/layout/block.rs b/components/layout/block.rs index dbfde997841e..336dac78f5cd 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -34,6 +34,11 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BlockLevel, FragmentDis use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo}; use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal, mut_base}; +use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS}; +use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; +use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER}; +use flow::{IS_ABSOLUTELY_POSITIONED}; +use flow::{CLEARS_LEFT, CLEARS_RIGHT}; use flow; use fragment::{Fragment, ImageFragment, InlineBlockFragment, FragmentBoundsIterator}; use fragment::ScannedTextFragment; @@ -439,7 +444,7 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> { return; } - assert!(block_flow.base.flags.is_absolutely_positioned()); + assert!(block_flow.base.flags.contains(IS_ABSOLUTELY_POSITIONED)); if !block_flow.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) { return } @@ -506,12 +511,12 @@ enum FormattingContextType { fn propagate_layer_flag_from_child(layers_needed_for_descendants: &mut bool, kid: &mut Flow) { if kid.is_absolute_containing_block() { let kid_base = flow::mut_base(kid); - if kid_base.flags.needs_layer() { + if kid_base.flags.contains(NEEDS_LAYER) { *layers_needed_for_descendants = true } } else { let kid_base = flow::mut_base(kid); - if kid_base.flags.layers_needed_for_descendants() { + if kid_base.flags.contains(LAYERS_NEEDED_FOR_DESCENDANTS) { *layers_needed_for_descendants = true } } @@ -628,7 +633,7 @@ impl BlockFlow { /// This determines the algorithm used to calculate inline-size, block-size, and the /// relevant margins for this Block. pub fn block_type(&self) -> BlockType { - if self.base.flags.is_absolutely_positioned() { + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { if self.is_replaced_content() { AbsoluteReplacedType } else { @@ -704,7 +709,7 @@ impl BlockFlow { /// reference the CB. #[inline] pub fn containing_block_size(&mut self, viewport_size: Size2D) -> LogicalSize { - debug_assert!(self.base.flags.is_absolutely_positioned()); + debug_assert!(self.base.flags.contains(IS_ABSOLUTELY_POSITIONED)); if self.is_fixed() { // Initial containing block is the CB for the root LogicalSize::from_physical(self.base.writing_mode, viewport_size) @@ -832,7 +837,7 @@ impl BlockFlow { // Absolute positioning establishes a block formatting context. Don't propagate floats // in or out. (But do propagate them between kids.) - if self.base.flags.is_absolutely_positioned() || + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) || margins_may_collapse != MarginsMayCollapse { self.base.floats = Floats::new(self.fragment.style.writing_mode); } @@ -847,7 +852,7 @@ impl BlockFlow { let can_collapse_block_start_margin_with_kids = margins_may_collapse == MarginsMayCollapse && - !self.base.flags.is_absolutely_positioned() && + !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && self.fragment.border_padding.block_start == Au(0); margin_collapse_info.initialize_block_start_margin( &self.fragment, @@ -857,7 +862,7 @@ impl BlockFlow { let mut floats = self.base.floats.clone(); let mut layers_needed_for_descendants = false; for kid in self.base.child_iter() { - if flow::base(kid).flags.is_absolutely_positioned() { + if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) { // Assume that the *hypothetical box* for an absolute flow starts immediately // after the block-end border edge of the previous flow. kid.as_block().hypothetical_position.b = cur_b; @@ -914,8 +919,8 @@ impl BlockFlow { translate_including_floats(&mut cur_b, delta, &mut floats); // Clear past the floats that came in, if necessary. - let clearance = match (flow::base(kid).flags.clears_left(), - flow::base(kid).flags.clears_right()) { + let clearance = match (flow::base(kid).flags.contains(CLEARS_LEFT), + flow::base(kid).flags.contains(CLEARS_RIGHT)) { (false, false) => Au(0), (true, false) => floats.clearance(ClearLeft), (false, true) => floats.clearance(ClearRight), @@ -947,7 +952,7 @@ impl BlockFlow { // Mark ourselves for layerization if that will be necessary to paint in the proper // order (CSS 2.1, Appendix E). - self.base.flags.set_layers_needed_for_descendants(layers_needed_for_descendants); + self.base.flags.set(LAYERS_NEEDED_FOR_DESCENDANTS, layers_needed_for_descendants); // Collect various offsets needed by absolutely positioned descendants. (&mut *self as &mut Flow).collect_static_block_offsets_from_children(); @@ -955,7 +960,7 @@ impl BlockFlow { // Add in our block-end margin and compute our collapsible margins. let can_collapse_block_end_margin_with_kids = margins_may_collapse == MarginsMayCollapse && - !self.base.flags.is_absolutely_positioned() && + !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && self.fragment.border_padding.block_end == Au(0); let (collapsible_margins, delta) = margin_collapse_info.finish_and_compute_collapsible_margins( @@ -977,16 +982,16 @@ impl BlockFlow { } if is_root || self.formatting_context_type() != NonformattingContext || - self.base.flags.is_absolutely_positioned() { + self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { // The content block-size includes all the floats per CSS 2.1 ยง 10.6.7. The easiest // way to handle this is to just treat it as clearance. block_size = block_size + floats.clearance(ClearBoth); } - if self.base.flags.is_absolutely_positioned() { + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { // Fixed position layers get layers. if self.is_fixed() { - self.base.flags.set_needs_layer(true) + self.base.flags.insert(NEEDS_LAYER); } // Store the content block-size for use in calculating the absolute flow's @@ -1029,7 +1034,7 @@ impl BlockFlow { self.fragment.border_box.size.block = cur_b; self.fragment.border_box.start.b = Au(0); - if !self.base.flags.is_absolutely_positioned() { + if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { self.base.position.size.block = cur_b; } @@ -1061,7 +1066,7 @@ impl BlockFlow { // has not been calculated yet. (See `calculate_absolute_block_size_and_margins` for that.) // Also don't remove the dirty bits if we're a block formatting context since our inline // size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.) - if !self.base.flags.is_absolutely_positioned() && + if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && self.formatting_context_type() == NonformattingContext { self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } @@ -1107,7 +1112,7 @@ impl BlockFlow { Au(0), self.fragment.margin.block_start); - if !self.base.flags.is_absolutely_positioned() { + if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { self.base.position = self.base.position.translate(&float_offset) .translate(&margin_offset); } @@ -1248,8 +1253,8 @@ impl BlockFlow { content_inline_size: Au, optional_column_inline_sizes: Option<&[ColumnInlineSize]>) { // Keep track of whether floats could impact each child. - let mut inline_start_floats_impact_child = self.base.flags.impacted_by_left_floats(); - let mut inline_end_floats_impact_child = self.base.flags.impacted_by_right_floats(); + let mut inline_start_floats_impact_child = self.base.flags.contains(IMPACTED_BY_LEFT_FLOATS); + let mut inline_end_floats_impact_child = self.base.flags.contains(IMPACTED_BY_RIGHT_FLOATS); let absolute_static_i_offset = if self.is_positioned() { // This flow is the containing block. The static inline offset will be the inline-start @@ -1316,7 +1321,7 @@ impl BlockFlow { // and its inline-size is our content inline-size. { let kid_base = flow::mut_base(kid); - if !kid_base.flags.is_absolutely_positioned() { + if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) { kid_base.position.start.i = inline_start_content_edge } kid_base.block_container_inline_size = content_inline_size; @@ -1326,11 +1331,11 @@ impl BlockFlow { } // Determine float impaction. - if flow::base(kid).flags.clears_left() { + if flow::base(kid).flags.contains(CLEARS_LEFT) { inline_start_floats_impact_child = false; inline_size_of_preceding_left_floats = Au(0); } - if flow::base(kid).flags.clears_right() { + if flow::base(kid).flags.contains(CLEARS_RIGHT) { inline_end_floats_impact_child = false; inline_size_of_preceding_right_floats = Au(0); } @@ -1338,11 +1343,11 @@ impl BlockFlow { { let kid_base = flow::mut_base(kid); inline_start_floats_impact_child = inline_start_floats_impact_child || - kid_base.flags.has_left_floated_descendants(); + kid_base.flags.contains(HAS_LEFT_FLOATED_DESCENDANTS); inline_end_floats_impact_child = inline_end_floats_impact_child || - kid_base.flags.has_right_floated_descendants(); - kid_base.flags.set_impacted_by_left_floats(inline_start_floats_impact_child); - kid_base.flags.set_impacted_by_right_floats(inline_end_floats_impact_child); + kid_base.flags.contains(HAS_RIGHT_FLOATED_DESCENDANTS); + kid_base.flags.set(IMPACTED_BY_LEFT_FLOATS, inline_start_floats_impact_child); + kid_base.flags.set(IMPACTED_BY_RIGHT_FLOATS, inline_end_floats_impact_child); } if kid.is_block_flow() { @@ -1468,8 +1473,8 @@ impl Flow for BlockFlow { let _scope = layout_debug_scope!("block::bubble_inline_sizes {:x}", self.base.debug_id()); let mut flags = self.base.flags; - flags.set_has_left_floated_descendants(false); - flags.set_has_right_floated_descendants(false); + flags.remove(HAS_LEFT_FLOATED_DESCENDANTS); + flags.remove(HAS_RIGHT_FLOATED_DESCENDANTS); // If this block has a fixed width, just use that for the minimum // and preferred width, rather than bubbling up children inline @@ -1484,7 +1489,7 @@ impl Flow for BlockFlow { let mut left_float_width = Au(0); let mut right_float_width = Au(0); for kid in self.base.child_iter() { - let is_absolutely_positioned = flow::base(kid).flags.is_absolutely_positioned(); + let is_absolutely_positioned = flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED); let child_base = flow::mut_base(kid); let float_kind = child_base.flags.float_kind(); if !is_absolutely_positioned && !fixed_width { @@ -1523,8 +1528,8 @@ impl Flow for BlockFlow { match self.fragment.style().get_box().float { float::none => {} - float::left => flags.set_has_left_floated_descendants(true), - float::right => flags.set_has_right_floated_descendants(true), + float::left => flags.insert(HAS_LEFT_FLOATED_DESCENDANTS), + float::right => flags.insert(HAS_RIGHT_FLOATED_DESCENDANTS), } self.base.flags = flags } @@ -1557,8 +1562,8 @@ impl Flow for BlockFlow { self.base.writing_mode, layout_context.shared.screen_size).inline; // The root element is never impacted by floats. - self.base.flags.set_impacted_by_left_floats(false); - self.base.flags.set_impacted_by_right_floats(false); + self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS); + self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS); } // Our inline-size was set to the inline-size of the containing block by the flow's parent. @@ -1569,8 +1574,8 @@ impl Flow for BlockFlow { match self.formatting_context_type() { NonformattingContext => {} BlockFormattingContext => { - self.base.flags.set_impacted_by_left_floats(false); - self.base.flags.set_impacted_by_right_floats(false); + self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS); + self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS); // We can't actually compute the inline-size of this block now, because floats // might affect it. Speculate that its inline-size is equal to the inline-size @@ -1581,8 +1586,8 @@ impl Flow for BlockFlow { self.inline_size_of_preceding_right_floats; } OtherFormattingContext => { - self.base.flags.set_impacted_by_left_floats(false); - self.base.flags.set_impacted_by_right_floats(false); + self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS); + self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS); } } @@ -1613,7 +1618,7 @@ impl Flow for BlockFlow { } let is_formatting_context = self.formatting_context_type() != NonformattingContext; - if !self.base.flags.is_absolutely_positioned() && is_formatting_context { + if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && is_formatting_context { self.assign_inline_position_for_formatting_context(); } @@ -1647,7 +1652,7 @@ impl Flow for BlockFlow { let containing_block_block_size = self.base.block_container_explicit_block_size.unwrap_or(Au(0)); self.fragment.assign_replaced_block_size_if_necessary(containing_block_block_size); - if !self.base.flags.is_absolutely_positioned() { + if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { self.base.position.size.block = self.fragment.border_box.size.block; } } else if self.is_root() || self.is_float() || self.is_inline_block() { @@ -1668,7 +1673,7 @@ impl Flow for BlockFlow { self.base.clip_rect = MAX_RECT } - if self.base.flags.is_absolutely_positioned() { + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { let position_start = self.base.position.start.to_physical(self.base.writing_mode, container_size); @@ -1718,7 +1723,7 @@ impl Flow for BlockFlow { .stacking_relative_position_of_absolute_containing_block }, relative_containing_block_size: self.fragment.content_box().size, - layers_needed_for_positioned_flows: self.base.flags.layers_needed_for_descendants(), + layers_needed_for_positioned_flows: self.base.flags.contains(LAYERS_NEEDED_FOR_DESCENDANTS), }; // Compute the origin and clipping rectangle for children. @@ -1733,7 +1738,7 @@ impl Flow for BlockFlow { // Process children. let writing_mode = self.base.writing_mode; for kid in self.base.child_iter() { - if !flow::base(kid).flags.is_absolutely_positioned() { + if !flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) { let kid_base = flow::mut_base(kid); kid_base.stacking_relative_position = origin_for_children + @@ -1760,7 +1765,7 @@ impl Flow for BlockFlow { /// /// Currently happens only for absolutely positioned flows. fn is_store_overflow_delayed(&mut self) -> bool { - self.base.flags.is_absolutely_positioned() + self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) } fn is_root(&self) -> bool { @@ -1801,7 +1806,7 @@ impl Flow for BlockFlow { } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { - if self.base.flags.is_absolutely_positioned() && + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && self.fragment.style().logical_position().inline_start == LPA_Auto && self.fragment.style().logical_position().inline_end == LPA_Auto { self.base.position.start.i = inline_position @@ -1809,7 +1814,7 @@ impl Flow for BlockFlow { } fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) { - if self.base.flags.is_absolutely_positioned() && + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && self.fragment.style().logical_position().block_start == LPA_Auto && self.fragment.style().logical_position().block_end == LPA_Auto { self.base.position.start.b = block_position @@ -1821,7 +1826,7 @@ impl Flow for BlockFlow { // TODO(#2009, pcwalton): This is a pseudo-stacking context. We need to merge `z-index: // auto` kids into the parent stacking context, when that is supported. self.build_display_list_for_floating_block(layout_context) - } else if self.base.flags.is_absolutely_positioned() { + } else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { self.build_display_list_for_absolutely_positioned_block(layout_context) } else { self.build_display_list_for_block(layout_context, BlockLevel) diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 7315d435200f..cc08c173b041 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -19,6 +19,7 @@ use context::LayoutContext; use floats::FloatKind; use flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils}; use flow::{Descendants, AbsDescendants}; +use flow::{IS_ABSOLUTELY_POSITIONED}; use flow; use flow_ref::FlowRef; use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment}; @@ -527,7 +528,7 @@ impl<'a> FlowConstructor<'a> { // Set up the absolute descendants. let is_positioned = flow.as_block().is_positioned(); - let is_absolutely_positioned = flow::base(&*flow).flags.is_absolutely_positioned(); + let is_absolutely_positioned = flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED); if is_positioned { // This is the containing block for all the absolute descendants. flow.set_absolute_descendants(abs_descendants); @@ -842,7 +843,7 @@ impl<'a> FlowConstructor<'a> { wrapper_flow.finish(); let is_positioned = wrapper_flow.as_block().is_positioned(); let is_fixed_positioned = wrapper_flow.as_block().is_fixed(); - let is_absolutely_positioned = flow::base(&*wrapper_flow).flags.is_absolutely_positioned(); + let is_absolutely_positioned = flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED); if is_positioned { // This is the containing block for all the absolute descendants. wrapper_flow.set_absolute_descendants(abs_descendants); diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 069493058b06..5f98aae70b71 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -13,6 +13,7 @@ use block::BlockFlow; use context::LayoutContext; use flow::{mod, Flow}; +use flow::{IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER}; use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment}; use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragment, InlineBlockFragment}; use fragment::{ScannedTextFragment, ScannedTextFragmentInfo, TableFragment}; @@ -809,7 +810,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { &self.base.clip_rect); for kid in self.base.children.iter_mut() { - if flow::base(kid).flags.is_absolutely_positioned() { + if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) { // All absolute flows will be handled by their containing block. continue } @@ -846,7 +847,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let z_index = self.fragment.style().get_box().z_index.number_or_zero(); if !self.base.absolute_position_info.layers_needed_for_positioned_flows && - !self.base.flags.needs_layer() { + !self.base.flags.contains(NEEDS_LAYER) { // We didn't need a layer. self.base.display_list_building_result = StackingContextResult(Arc::new(StackingContext::new(display_list, diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 41cc5570a60a..64357ab90a64 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -256,7 +256,7 @@ pub trait Flow: fmt::Show + ToString + Sync { } fn is_positioned(&self) -> bool { - self.is_relatively_positioned() || base(self).flags.is_absolutely_positioned() + self.is_relatively_positioned() || base(self).flags.contains(IS_ABSOLUTELY_POSITIONED) } fn is_relatively_positioned(&self) -> bool { @@ -457,86 +457,66 @@ pub trait PostorderFlowTraversal { } } -/// Flags used in flows, tightly packed to save space. -#[deriving(Clone, Encodable)] -pub struct FlowFlags(pub u16); +bitflags! { + #[doc = "Flags used in flows."] + flags FlowFlags: u16 { + // floated descendants flags + #[doc = "Whether this flow has descendants that float left in the same block formatting"] + #[doc = "context."] + const HAS_LEFT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0001, + #[doc = "Whether this flow has descendants that float right in the same block formatting"] + #[doc = "context."] + const HAS_RIGHT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0010, + #[doc = "Whether this flow is impacted by floats to the left in the same block formatting"] + #[doc = "context (i.e. its height depends on some prior flows with `float: left`)."] + const IMPACTED_BY_LEFT_FLOATS = 0b0000_0000_0000_0100, + #[doc = "Whether this flow is impacted by floats to the right in the same block"] + #[doc = "formatting context (i.e. its height depends on some prior flows with `float:"] + #[doc = "right`)."] + const IMPACTED_BY_RIGHT_FLOATS = 0b0000_0000_0000_1000, + + // text align flags + #[doc = "Whether this flow contains a flow that has its own layer within the same absolute"] + #[doc = "containing block."] + const LAYERS_NEEDED_FOR_DESCENDANTS = 0b0000_0000_0001_0000, + #[doc = "Whether this flow must have its own layer. Even if this flag is not set, it might"] + #[doc = "get its own layer if it's deemed to be likely to overlap flows with their own"] + #[doc = "layer."] + const NEEDS_LAYER = 0b0000_0000_0010_0000, + #[doc = "Whether this flow is absolutely positioned. This is checked all over layout, so a"] + #[doc = "virtual call is too expensive."] + const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0100_0000, + #[doc = "Whether this flow clears to the left. This is checked all over layout, so a"] + #[doc = "virtual call is too expensive."] + const CLEARS_LEFT = 0b0000_0000_1000_0000, + #[doc = "Whether this flow clears to the right. This is checked all over layout, so a"] + #[doc = "virtual call is too expensive."] + const CLEARS_RIGHT = 0b0000_0001_0000_0000, + #[doc = "Whether this flow is left-floated. This is checked all over layout, so a"] + #[doc = "virtual call is too expensive."] + const FLOATS_LEFT = 0b0000_0010_0000_0000, + #[doc = "Whether this flow is right-floated. This is checked all over layout, so a"] + #[doc = "virtual call is too expensive."] + const FLOATS_RIGHT = 0b0000_0100_0000_0000, + #[doc = "Text alignment."] + const TEXT_ALIGN = 0b0000_1000_0000_0000, + } +} +// NB: If you update this field, you must update the the floated descendants flags. /// The bitmask of flags that represent the `has_left_floated_descendants` and /// `has_right_floated_descendants` fields. -/// -/// NB: If you update this field, you must update the bitfields below. -static HAS_FLOATED_DESCENDANTS_BITMASK: u16 = 0b0000_0000_0000_0011; - -// Whether this flow has descendants that float left in the same block formatting context. -bitfield!(FlowFlags, - has_left_floated_descendants, - set_has_left_floated_descendants, - 0b0000_0000_0000_0001) - -// Whether this flow has descendants that float right in the same block formatting context. -bitfield!(FlowFlags, - has_right_floated_descendants, - set_has_right_floated_descendants, - 0b0000_0000_0000_0010) - -// Whether this flow is impacted by floats to the left in the same block formatting context (i.e. -// its block-size depends on some prior flows with `float: left`). -bitfield!(FlowFlags, - impacted_by_left_floats, - set_impacted_by_left_floats, - 0b0000_0000_0000_0100) - -// Whether this flow is impacted by floats to the right in the same block formatting context (i.e. -// its block-size depends on some prior flows with `float: right`). -bitfield!(FlowFlags, impacted_by_right_floats, set_impacted_by_right_floats, 0b0000_0000_0000_1000) +static HAS_FLOATED_DESCENDANTS_BITMASK: FlowFlags = FlowFlags { bits: 0b0000_0011 }; + +// NB: If you update this field, you must update the the text align flags. /// The bitmask of flags that represent the text alignment field. -/// -/// NB: If you update this field, you must update the bitfields below. -static TEXT_ALIGN_BITMASK: u16 = 0b0000_0000_0011_0000; +static TEXT_ALIGN_BITMASK: FlowFlags = FlowFlags { bits: 0b0011_0000 }; /// The number of bits we must shift off to handle the text alignment field. -/// -/// NB: If you update this field, you must update the bitfields below. -static TEXT_ALIGN_SHIFT: u16 = 4; - -// Whether this flow contains a flow that has its own layer within the same absolute containing -// block. -bitfield!(FlowFlags, - layers_needed_for_descendants, - set_layers_needed_for_descendants, - 0b0000_0000_0100_0000) - -// Whether this flow must have its own layer. Even if this flag is not set, it might get its own -// layer if it's deemed to be likely to overlap flows with their own layer. -bitfield!(FlowFlags, needs_layer, set_needs_layer, 0b0000_0000_1000_0000) - -// Whether this flow is absolutely positioned. This is checked all over layout, so a virtual call -// is too expensive. -bitfield!(FlowFlags, is_absolutely_positioned, set_is_absolutely_positioned, 0b0000_0001_0000_0000) - -// Whether this flow is left-floated. This is checked all over layout, so a virtual call is too -// expensive. -bitfield!(FlowFlags, floats_left, set_floats_left, 0b0000_0010_0000_0000) - -// Whether this flow is right-floated. This is checked all over layout, so a virtual call is too -// expensive. -bitfield!(FlowFlags, floats_right, set_floats_right, 0b0000_0100_0000_0000) - -// Whether this flow clears to the left. This is checked all over layout, so a virtual call is too -// expensive. -bitfield!(FlowFlags, clears_left, set_clears_left, 0b0000_1000_0000_0000) - -// Whether this flow clears to the right. This is checked all over layout, so a virtual call is too -// expensive. -bitfield!(FlowFlags, clears_right, set_clears_right, 0b0001_0000_0000_0000) +static TEXT_ALIGN_SHIFT: uint = 4; impl FlowFlags { - /// Creates a new set of flow flags. - pub fn new() -> FlowFlags { - FlowFlags(0) - } - /// Propagates text alignment flags from an appropriate parent flow per CSS 2.1. /// /// FIXME(#2265, pcwalton): It would be cleaner and faster to make this a derived CSS property @@ -547,40 +527,43 @@ impl FlowFlags { #[inline] pub fn text_align(self) -> text_align::T { - let FlowFlags(ff) = self; - FromPrimitive::from_u16((ff & TEXT_ALIGN_BITMASK) >> TEXT_ALIGN_SHIFT as uint).unwrap() + FromPrimitive::from_u16((self & TEXT_ALIGN_BITMASK).bits() >> TEXT_ALIGN_SHIFT).unwrap() } #[inline] pub fn set_text_align(&mut self, value: text_align::T) { - let FlowFlags(ff) = *self; - *self = FlowFlags((ff & !TEXT_ALIGN_BITMASK) | ((value as u16) << TEXT_ALIGN_SHIFT as uint)) + *self = (*self & !TEXT_ALIGN_BITMASK) | FlowFlags::from_bits(value as u16 << TEXT_ALIGN_SHIFT).unwrap(); } #[inline] pub fn set_text_align_override(&mut self, parent: FlowFlags) { - let FlowFlags(ff) = *self; - let FlowFlags(pff) = parent; - *self = FlowFlags(ff | (pff & TEXT_ALIGN_BITMASK)) + self.insert(parent & TEXT_ALIGN_BITMASK); } #[inline] pub fn union_floated_descendants_flags(&mut self, other: FlowFlags) { - let FlowFlags(my_flags) = *self; - let FlowFlags(other_flags) = other; - *self = FlowFlags(my_flags | (other_flags & HAS_FLOATED_DESCENDANTS_BITMASK)) + self.insert(other & HAS_FLOATED_DESCENDANTS_BITMASK); } #[inline] pub fn impacted_by_floats(&self) -> bool { - self.impacted_by_left_floats() || self.impacted_by_right_floats() + self.contains(IMPACTED_BY_LEFT_FLOATS) || self.contains(IMPACTED_BY_RIGHT_FLOATS) + } + + #[inline] + pub fn set(&mut self, flags: FlowFlags, value: bool) { + if value { + self.insert(flags); + } else { + self.remove(flags); + } } #[inline] pub fn float_kind(&self) -> float::T { - if self.floats_left() { + if self.contains(FLOATS_LEFT) { float::left - } else if self.floats_right() { + } else if self.contains(FLOATS_RIGHT) { float::right } else { float::none @@ -589,7 +572,7 @@ impl FlowFlags { #[inline] pub fn clears_floats(&self) -> bool { - self.clears_left() || self.clears_right() + self.contains(CLEARS_LEFT) || self.contains(CLEARS_RIGHT) } } @@ -854,29 +837,29 @@ impl Drop for BaseFlow { impl BaseFlow { #[inline] pub fn new(node: Option, writing_mode: WritingMode) -> BaseFlow { - let mut flags = FlowFlags::new(); + let mut flags = FlowFlags::empty(); match node { None => {} Some(node) => { let node_style = node.style(); match node_style.get_box().position { position::absolute | position::fixed => { - flags.set_is_absolutely_positioned(true) + flags.insert(IS_ABSOLUTELY_POSITIONED) } _ => {} } match node_style.get_box().float { float::none => {} - float::left => flags.set_floats_left(true), - float::right => flags.set_floats_right(true), + float::left => flags.insert(FLOATS_LEFT), + float::right => flags.insert(FLOATS_RIGHT), } match node_style.get_box().clear { clear::none => {} - clear::left => flags.set_clears_left(true), - clear::right => flags.set_clears_right(true), + clear::left => flags.insert(CLEARS_LEFT), + clear::right => flags.insert(CLEARS_RIGHT), clear::both => { - flags.set_clears_left(true); - flags.set_clears_right(true); + flags.insert(CLEARS_LEFT); + flags.insert(CLEARS_RIGHT); } } } @@ -1211,7 +1194,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow + 'a { let mut gives_absolute_offsets = true; if kid.is_block_like() { let kid_block = kid.as_block(); - if kid_block.is_fixed() || kid_block.base.flags.is_absolutely_positioned() { + if kid_block.is_fixed() || kid_block.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { // It won't contribute any offsets for descendants because it would be the // containing block for them. gives_absolute_offsets = false; diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index f332797cbfca..bf2fcacf66d4 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use flow::{mod, Flow}; +use flow::{IS_ABSOLUTELY_POSITIONED}; use std::fmt; use std::sync::Arc; @@ -183,13 +184,13 @@ pub trait LayoutDamageComputation { impl<'a> LayoutDamageComputation for &'a mut Flow+'a { fn compute_layout_damage(self) -> SpecialRestyleDamage { let mut special_damage = SpecialRestyleDamage::empty(); - let is_absolutely_positioned = flow::base(self).flags.is_absolutely_positioned(); + let is_absolutely_positioned = flow::base(self).flags.contains(IS_ABSOLUTELY_POSITIONED); { let self_base = flow::mut_base(self); for kid in self_base.children.iter_mut() { let child_is_absolutely_positioned = - flow::base(kid).flags.is_absolutely_positioned(); + flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED); flow::mut_base(kid).restyle_damage .insert(self_base.restyle_damage.damage_for_child( is_absolutely_positioned, diff --git a/components/layout/inline.rs b/components/layout/inline.rs index d1a6b22b992b..78e89b31b31a 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -9,6 +9,7 @@ use context::LayoutContext; use display_list_builder::{ContentLevel, DisplayListResult, FragmentDisplayListBuilding}; use floats::{FloatLeft, Floats, PlacementInfo}; use flow::{BaseFlow, FlowClass, Flow, InlineFlowClass, MutableFlowUtils}; +use flow::{IS_ABSOLUTELY_POSITIONED}; use flow; use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment}; use fragment::{FragmentBoundsIterator, ScannedTextFragment, ScannedTextFragmentInfo}; @@ -1115,7 +1116,7 @@ impl Flow for InlineFlow { // Assign block sizes for any inline-block descendants. for kid in self.base.child_iter() { - if flow::base(kid).flags.is_absolutely_positioned() || kid.is_float() { + if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) || kid.is_float() { continue } kid.assign_block_size_for_inorder_child_if_necessary(layout_context); diff --git a/components/layout/table.rs b/components/layout/table.rs index 8be9f9811abd..773e18faf05d 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -12,6 +12,7 @@ use construct::FlowConstructor; use context::LayoutContext; use floats::FloatKind; use flow::{TableFlowClass, FlowClass, Flow, ImmutableFlowUtils}; +use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; use fragment::{Fragment, FragmentBoundsIterator}; use layout_debug; use model::{IntrinsicISizes, IntrinsicISizesContribution}; @@ -290,8 +291,8 @@ impl Flow for TableFlow { } // As tables are always wrapped inside a table wrapper, they are never impacted by floats. - self.block_flow.base.flags.set_impacted_by_left_floats(false); - self.block_flow.base.flags.set_impacted_by_right_floats(false); + self.block_flow.base.flags.remove(IMPACTED_BY_LEFT_FLOATS); + self.block_flow.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS); self.block_flow.propagate_assigned_inline_size_to_children( inline_start_content_edge, diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 2902326413c8..57a34b2f216d 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -19,6 +19,7 @@ use construct::FlowConstructor; use context::LayoutContext; use floats::FloatKind; use flow::{TableWrapperFlowClass, FlowClass, Flow, ImmutableFlowUtils}; +use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; use fragment::{Fragment, FragmentBoundsIterator}; use table::ColumnInlineSize; use wrapper::ThreadSafeLayoutNode; @@ -260,8 +261,8 @@ impl Flow for TableWrapperFlow { // Table wrappers are essentially block formatting contexts and are therefore never // impacted by floats. - self.block_flow.base.flags.set_impacted_by_left_floats(false); - self.block_flow.base.flags.set_impacted_by_right_floats(false); + self.block_flow.base.flags.remove(IMPACTED_BY_LEFT_FLOATS); + self.block_flow.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS); // Our inline-size was set to the inline-size of the containing block by the flow's parent. // Now compute the real value. diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index a821bcea84ba..aa4ba7fd865c 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -35,7 +35,6 @@ use syntax::parse::token::intern; pub mod jstraceable; pub mod lints; -mod macros; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension(intern("dom_struct"), Modifier(box jstraceable::expand_dom_struct)); diff --git a/components/plugins/macros.rs b/components/plugins/macros.rs deleted file mode 100644 index c4807f4dc498..000000000000 --- a/components/plugins/macros.rs +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#[macro_export] -macro_rules! bitfield( - ($bitfieldname:ident, $getter:ident, $setter:ident, $value:expr) => ( - impl $bitfieldname { - #[inline] - pub fn $getter(self) -> bool { - let $bitfieldname(this) = self; - (this & $value) != 0 - } - - #[inline] - pub fn $setter(&mut self, value: bool) { - let $bitfieldname(this) = *self; - *self = $bitfieldname((this & !$value) | (if value { $value } else { 0 })) - } - } - ) -)