diff options
24 files changed, 332 insertions, 271 deletions
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index f200aa86607..c6b1727d1d5 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -31,6 +31,7 @@ profile_traits = {path = "../profile_traits"} range = {path = "../range"} rustc-serialize = "0.3" script = {path = "../script"} +script_layout_interface = {path = "../script_layout_interface"} script_traits = {path = "../script_traits"} selectors = {version = "0.6", features = ["heap_size"]} serde_json = "0.7" diff --git a/components/layout/animation.rs b/components/layout/animation.rs index e9a530e7d90..cc87a2824a4 100644 --- a/components/layout/animation.rs +++ b/components/layout/animation.rs @@ -6,9 +6,9 @@ use flow::{self, Flow}; use gfx::display_list::OpaqueNode; -use incremental::RestyleDamage; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; +use script_layout_interface::restyle_damage::RestyleDamage; use script_traits::{AnimationState, LayoutMsg as ConstellationMsg}; use std::collections::HashMap; use std::collections::hash_map::Entry; diff --git a/components/layout/block.rs b/components/layout/block.rs index 6571d7d708a..9fc527d98d5 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -45,12 +45,12 @@ use fragment::SpecificFragmentInfo; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, HAS_LAYER, Overflow}; use gfx::display_list::{ClippingRegion, StackingContext}; use gfx_traits::{LayerId, StackingContextId}; -use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT}; use layout_debug; use layout_thread::DISPLAY_PORT_SIZE_FACTOR; use model::{CollapsibleMargins, MaybeAuto, specified, specified_or_none}; use model::{self, IntrinsicISizes, MarginCollapseInfo}; use rustc_serialize::{Encodable, Encoder}; +use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT}; use std::cmp::{max, min}; use std::fmt; use std::sync::Arc; diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 49546fb2663..3066f8f6ae5 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -28,7 +28,6 @@ use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo}; use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo}; use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use gfx::display_list::OpaqueNode; -use incremental::{BUBBLE_ISIZES, RECONSTRUCT_FLOW, RestyleDamage}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, InlineFragmentNodeFlags}; use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT}; use list_item::{ListItemFlow, ListStyleTypeContent}; @@ -37,6 +36,7 @@ use parallel; use script::layout_interface::is_image_data; use script::layout_interface::{CharacterDataTypeId, ElementTypeId}; use script::layout_interface::{HTMLElementTypeId, NodeTypeId}; +use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW, RestyleDamage}; use std::borrow::ToOwned; use std::collections::LinkedList; use std::marker::PhantomData; diff --git a/components/layout/data.rs b/components/layout/data.rs index 10c72667aae..d189814f788 100644 --- a/components/layout/data.rs +++ b/components/layout/data.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use construct::ConstructionResult; -use incremental::RestyleDamage; +use script_layout_interface::restyle_damage::RestyleDamage; use style::servo::PrivateStyleData; /// Data that layout associates with a node. diff --git a/components/layout/flex.rs b/components/layout/flex.rs index b977124bf80..dd279bbdfdf 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -19,9 +19,9 @@ use flow_ref::{self, FlowRef}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use gfx::display_list::StackingContext; use gfx_traits::StackingContextId; -use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; use layout_debug; use model::{IntrinsicISizes, MaybeAuto, MinMaxConstraint}; +use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW}; use std::cmp::max; use std::sync::Arc; use style::computed_values::flex_direction; diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 350092acc90..79aa1daaaa5 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -36,12 +36,12 @@ use flow_ref::{self, FlowRef, WeakFlowRef}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo}; use gfx::display_list::{ClippingRegion, StackingContext}; use gfx_traits::{LayerId, LayerType, StackingContextId}; -use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage}; use inline::InlineFlow; use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo}; use multicol::MulticolFlow; use parallel::FlowParallelInfo; use rustc_serialize::{Encodable, Encoder}; +use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage}; use std::iter::Zip; use std::slice::IterMut; use std::sync::Arc; diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 80664d720c8..9aa7cf43338 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -18,7 +18,6 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode}; use gfx::text::glyph::ByteIndex; use gfx::text::text_run::{TextRun, TextRunSlice}; use gfx_traits::{FragmentType, LayerId, LayerType, StackingContextId}; -use incremental::{RECONSTRUCT_FLOW, RestyleDamage}; use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo}; use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT}; use ipc_channel::ipc::IpcSender; @@ -31,6 +30,7 @@ use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; use range::*; use rustc_serialize::{Encodable, Encoder}; use script::layout_interface::HTMLCanvasData; +use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, RestyleDamage}; use std::borrow::ToOwned; use std::cmp::{max, min}; use std::collections::LinkedList; diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs index a7e9c8f463a..b6264859faa 100644 --- a/components/layout/generated_content.rs +++ b/components/layout/generated_content.rs @@ -13,7 +13,7 @@ use flow::InorderFlowTraversal; use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils}; use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use gfx::display_list::OpaqueNode; -use incremental::{RESOLVE_GENERATED_CONTENT, RestyleDamage}; +use script_layout_interface::restyle_damage::{RESOLVE_GENERATED_CONTENT, RestyleDamage}; use smallvec::SmallVec; use std::collections::{HashMap, LinkedList}; use std::sync::Arc; diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index a95a60e002a..14644be6ddc 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -3,46 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, IS_ABSOLUTELY_POSITIONED}; -use std::fmt; -use std::sync::Arc; -use style::computed_values::{display, float}; +use script_layout_interface::restyle_damage::{RestyleDamage, REFLOW, RECONSTRUCT_FLOW}; +use style::computed_values::float; use style::dom::TRestyleDamage; -use style::properties::{ComputedValues, ServoComputedValues}; - -bitflags! { - #[doc = "Individual layout actions that may be necessary after restyling."] - pub flags RestyleDamage: u8 { - #[doc = "Repaint the node itself."] - #[doc = "Currently unused; need to decide how this propagates."] - const REPAINT = 0x01, - - #[doc = "Recompute the overflow regions (bounding box of object and all descendants)."] - #[doc = "Propagates down the flow tree because the computation is bottom-up."] - const STORE_OVERFLOW = 0x02, - - #[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."] - #[doc = "Propagates down the flow tree because the computation is"] - #[doc = "bottom-up."] - const BUBBLE_ISIZES = 0x04, - - #[doc = "Recompute actual inline-sizes and block-sizes, only taking out-of-flow children \ - into account. \ - Propagates up the flow tree because the computation is top-down."] - const REFLOW_OUT_OF_FLOW = 0x08, - - #[doc = "Recompute actual inline_sizes and block_sizes."] - #[doc = "Propagates up the flow tree because the computation is"] - #[doc = "top-down."] - const REFLOW = 0x10, - - #[doc = "Re-resolve generated content. \ - Propagates up the flow tree because the computation is inorder."] - const RESOLVE_GENERATED_CONTENT = 0x20, - - #[doc = "The entire flow needs to be reconstructed."] - const RECONSTRUCT_FLOW = 0x40 - } -} bitflags! { pub flags SpecialRestyleDamage: u8 { @@ -52,221 +15,6 @@ bitflags! { } } -impl TRestyleDamage for RestyleDamage { - type ConcreteComputedValues = ServoComputedValues; - fn compute(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> - RestyleDamage { compute_damage(old, new) } - - /// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed. - /// - /// Use this instead of `RestyleDamage::all()` because `RestyleDamage::all()` will result in - /// unnecessary sequential resolution of generated content. - fn rebuild_and_reflow() -> RestyleDamage { - REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW - } -} - - -impl RestyleDamage { - /// Supposing a flow has the given `position` property and this damage, returns the damage that - /// we should add to the *parent* of this flow. - pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage { - if child_is_absolutely_positioned { - self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT) - } else { - self & (REPAINT | STORE_OVERFLOW | REFLOW | REFLOW_OUT_OF_FLOW | - RESOLVE_GENERATED_CONTENT) - } - } - - /// Supposing the *parent* of a flow with the given `position` property has this damage, - /// returns the damage that we should add to this flow. - pub fn damage_for_child(self, - parent_is_absolutely_positioned: bool, - child_is_absolutely_positioned: bool) - -> RestyleDamage { - match (parent_is_absolutely_positioned, child_is_absolutely_positioned) { - (false, true) => { - // Absolute children are out-of-flow and therefore insulated from changes. - // - // FIXME(pcwalton): Au contraire, if the containing block dimensions change! - self & REPAINT - } - (true, false) => { - // Changing the position of an absolutely-positioned block requires us to reflow - // its kids. - if self.contains(REFLOW_OUT_OF_FLOW) { - self | REFLOW - } else { - self - } - } - _ => { - // TODO(pcwalton): Take floatedness into account. - self & (REPAINT | REFLOW) - } - } - } -} - -impl fmt::Display for RestyleDamage { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - let mut first_elem = true; - - let to_iter = - [ (REPAINT, "Repaint") - , (STORE_OVERFLOW, "StoreOverflow") - , (BUBBLE_ISIZES, "BubbleISizes") - , (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow") - , (REFLOW, "Reflow") - , (RESOLVE_GENERATED_CONTENT, "ResolveGeneratedContent") - , (RECONSTRUCT_FLOW, "ReconstructFlow") - ]; - - for &(damage, damage_str) in &to_iter { - if self.contains(damage) { - if !first_elem { try!(write!(f, " | ")); } - try!(write!(f, "{}", damage_str)); - first_elem = false; - } - } - - if first_elem { - try!(write!(f, "NoDamage")); - } - - Ok(()) - } -} - -// NB: We need the braces inside the RHS due to Rust #8012. This particular -// version of this macro might be safe anyway, but we want to avoid silent -// breakage on modifications. -macro_rules! add_if_not_equal( - ($old:ident, $new:ident, $damage:ident, - [ $($effect:ident),* ], [ $($style_struct_getter:ident.$name:ident),* ]) => ({ - if $( ($old.$style_struct_getter().$name != $new.$style_struct_getter().$name) )||* { - $damage.insert($($effect)|*); - true - } else { - false - } - }) -); - -pub fn compute_damage(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> RestyleDamage { - let old: &ServoComputedValues = match old { - None => return RestyleDamage::rebuild_and_reflow(), - Some(cv) => &**cv, - }; - - let mut damage = RestyleDamage::empty(); - - // This should check every CSS property, as enumerated in the fields of - // http://doc.servo.org/style/properties/struct.ServoComputedValues.html - - // FIXME: Test somehow that every property is included. - - add_if_not_equal!(old, new, damage, - [ - REPAINT, - STORE_OVERFLOW, - BUBBLE_ISIZES, - REFLOW_OUT_OF_FLOW, - REFLOW, - RECONSTRUCT_FLOW - ], [ - get_box.float, get_box.display, get_box.position, get_counters.content, - get_counters.counter_reset, get_counters.counter_increment, - get_inheritedbox._servo_under_display_none, - get_list.quotes, get_list.list_style_type, - - // If these text or font properties change, we need to reconstruct the flow so that - // text shaping is re-run. - get_inheritedtext.letter_spacing, get_inheritedtext.text_rendering, - get_inheritedtext.text_transform, get_inheritedtext.word_spacing, - get_inheritedtext.overflow_wrap, get_inheritedtext.text_justify, - get_inheritedtext.white_space, get_inheritedtext.word_break, get_text.text_overflow, - get_font.font_family, get_font.font_style, get_font.font_variant, get_font.font_weight, - get_font.font_size, get_font.font_stretch, - get_inheritedbox.direction, get_inheritedbox.writing_mode, - get_inheritedbox.text_orientation, - get_text.text_decoration, get_text.unicode_bidi, - get_inheritedtable.empty_cells, get_inheritedtable.caption_side, - get_column.column_width, get_column.column_count - ]) || (new.get_box().display == display::T::inline && - add_if_not_equal!(old, new, damage, - [REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW, - RECONSTRUCT_FLOW], [ - // For inline boxes only, border/padding styles are used in flow construction (to decide - // whether to create fragments for empty flows). - get_border.border_top_width, get_border.border_right_width, - get_border.border_bottom_width, get_border.border_left_width, - get_padding.padding_top, get_padding.padding_right, - get_padding.padding_bottom, get_padding.padding_left - ])) || add_if_not_equal!(old, new, damage, - [ REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW ], - [get_border.border_top_width, get_border.border_right_width, - get_border.border_bottom_width, get_border.border_left_width, - get_margin.margin_top, get_margin.margin_right, - get_margin.margin_bottom, get_margin.margin_left, - get_padding.padding_top, get_padding.padding_right, - get_padding.padding_bottom, get_padding.padding_left, - get_position.width, get_position.height, - get_inheritedtext.line_height, - get_inheritedtext.text_align, get_inheritedtext.text_indent, - get_table.table_layout, - get_inheritedtable.border_collapse, - get_inheritedtable.border_spacing, - get_column.column_gap, - get_position.flex_direction, - get_position.flex_wrap, - get_position.justify_content, - get_position.align_items, - get_position.align_content, - get_position.order, - get_position.flex_basis, - get_position.flex_grow, - get_position.flex_shrink, - get_position.align_self - ]) || add_if_not_equal!(old, new, damage, - [ REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW ], [ - get_position.top, get_position.left, - get_position.right, get_position.bottom - ]) || add_if_not_equal!(old, new, damage, - [ REPAINT ], [ - get_color.color, get_background.background_color, - get_background.background_image, get_background.background_position, - get_background.background_repeat, get_background.background_attachment, - get_background.background_clip, get_background.background_origin, - get_background.background_size, - get_border.border_top_color, get_border.border_right_color, - get_border.border_bottom_color, get_border.border_left_color, - get_border.border_top_style, get_border.border_right_style, - get_border.border_bottom_style, get_border.border_left_style, - get_border.border_top_left_radius, get_border.border_top_right_radius, - get_border.border_bottom_left_radius, get_border.border_bottom_right_radius, - get_position.z_index, get_box._servo_overflow_clip_box, - get_inheritedtext._servo_text_decorations_in_effect, - get_pointing.cursor, get_pointing.pointer_events, - get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter, - get_effects.transform, get_effects.backface_visibility, get_effects.transform_style, - get_effects.transform_origin, get_effects.perspective, get_effects.perspective_origin, - get_effects.mix_blend_mode, get_inheritedbox.image_rendering, - - // Note: May require REFLOW et al. if `visibility: collapse` is implemented. - get_inheritedbox.visibility - ]); - - // If the layer requirements of this flow have changed due to the value - // of the transform, then reflow is required to rebuild the layers. - if old.transform_requires_layer() != new.transform_requires_layer() { - damage.insert(RestyleDamage::rebuild_and_reflow()); - } - - damage -} - pub trait LayoutDamageComputation { fn compute_layout_damage(self) -> SpecialRestyleDamage; fn reflow_entire_document(self); diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 5387f943070..e0e390557db 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -21,10 +21,11 @@ use gfx::display_list::{OpaqueNode, StackingContext}; use gfx::font::FontMetrics; use gfx::font_context::FontContext; use gfx_traits::StackingContextId; -use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RESOLVE_GENERATED_CONTENT}; use layout_debug; use model::IntrinsicISizesContribution; use range::{Range, RangeIndex}; +use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW}; +use script_layout_interface::restyle_damage::{REPAINT, RESOLVE_GENERATED_CONTENT}; use std::cmp::max; use std::collections::VecDeque; use std::sync::Arc; diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index bedc72791c6..abe3fd7d33a 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -29,8 +29,7 @@ use gfx::font_context; use gfx::paint_thread::LayoutToPaintMsg; use gfx_traits::{color, Epoch, FragmentType, LayerId, ScrollPolicy, StackingContextId}; use heapsize::HeapSizeOf; -use incremental::LayoutDamageComputation; -use incremental::{REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW, REFLOW, REFLOW_ENTIRE_DOCUMENT}; +use incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use layout_debug; @@ -51,6 +50,7 @@ use script::layout_interface::OpaqueStyleAndLayoutData; use script::layout_interface::{LayoutRPC, OffsetParentResponse, NodeOverflowResponse, MarginStyleResponse}; use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow}; use script::reporter::CSSErrorReporter; +use script_layout_interface::restyle_damage::{REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW, REFLOW}; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{StackingContextScrollState, UntrustedNodeAddress}; use sequential; diff --git a/components/layout/lib.rs b/components/layout/lib.rs index 88f08610eba..62da36cff87 100644 --- a/components/layout/lib.rs +++ b/components/layout/lib.rs @@ -47,6 +47,7 @@ extern crate profile_traits; extern crate range; extern crate rustc_serialize; extern crate script; +extern crate script_layout_interface; extern crate script_traits; extern crate selectors; extern crate serde_json; diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index de079325e69..be0620b817d 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -19,8 +19,8 @@ use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, GeneratedC use generated_content; use gfx::display_list::StackingContext; use gfx_traits::StackingContextId; -use incremental::RESOLVE_GENERATED_CONTENT; use inline::InlineMetrics; +use script_layout_interface::restyle_damage::RESOLVE_GENERATED_CONTENT; use std::sync::Arc; use style::computed_values::{list_style_type, position}; use style::logical_geometry::LogicalSize; diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 6663843f572..a761251b77f 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -16,7 +16,7 @@ use flow_ref::{self, FlowRef}; use fragment::FragmentBorderBoxIterator; use generated_content::ResolveGeneratedContent; use gfx::display_list::{DisplayItem, StackingContext}; -use incremental::{REFLOW, STORE_OVERFLOW}; +use script_layout_interface::restyle_damage::{REFLOW, STORE_OVERFLOW}; use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList, ComputeAbsolutePositions}; use util::opts; diff --git a/components/layout/table.rs b/components/layout/table.rs index 5b7f26eb9d9..14845532ef0 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -18,9 +18,9 @@ use flow_list::MutFlowListIterator; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use gfx::display_list::StackingContext; use gfx_traits::StackingContextId; -use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; use layout_debug; use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto}; +use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW}; use std::cmp; use std::fmt; use std::sync::Arc; diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index a579ecb6c12..1038328b7af 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -16,9 +16,9 @@ use flow::{self, Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use gfx::display_list::StackingContext; use gfx_traits::StackingContextId; -use incremental::REFLOW; use layout_debug; use model::MaybeAuto; +use script_layout_interface::restyle_damage::REFLOW; use std::fmt; use std::sync::Arc; use style::computed_values::{border_collapse, border_top_style, vertical_align}; diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index bd07e1f72bb..b1ccaf638c3 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -10,7 +10,7 @@ use display_list_builder::DisplayListBuildState; use flow::{CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils, PostorderFlowTraversal}; use flow::{PreorderFlowTraversal, self}; use gfx::display_list::OpaqueNode; -use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage}; +use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage}; use std::mem; use style::context::StyleContext; use style::matching::MatchMethods; diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 3c18e909bae..7a20337607e 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -35,7 +35,6 @@ use data::{LayoutDataFlags, PrivateLayoutData}; use gfx::display_list::OpaqueNode; use gfx::text::glyph::ByteIndex; use gfx_traits::{LayerId, LayerType}; -use incremental::RestyleDamage; use msg::constellation_msg::PipelineId; use opaque_node::OpaqueNodeMethods; use range::Range; @@ -45,6 +44,7 @@ use script::layout_interface::{HTMLCanvasData, HTMLElementTypeId, LayoutCharacte use script::layout_interface::{LayoutDocumentHelpers, LayoutElementHelpers, LayoutJS}; use script::layout_interface::{LayoutNodeHelpers, Node, NodeTypeId, OpaqueStyleAndLayoutData}; use script::layout_interface::{RawLayoutElementHelpers, Text, TrustedNodeAddress}; +use script_layout_interface::restyle_damage::RestyleDamage; use selectors::matching::{DeclarationBlock, ElementFlags}; use selectors::parser::{AttrSelector, NamespaceConstraint}; use smallvec::VecLike; diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml new file mode 100644 index 00000000000..3069b1a3b8d --- /dev/null +++ b/components/script_layout_interface/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "script_layout_interface" +version = "0.0.1" +authors = ["The Servo Project Developers"] +publish = false + +[lib] +name = "script_layout_interface" +path = "lib.rs" + +[dependencies] +bitflags = "0.7" +plugins = {path = "../plugins"} +style = {path = "../style"} diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs new file mode 100644 index 00000000000..1aed95b6210 --- /dev/null +++ b/components/script_layout_interface/lib.rs @@ -0,0 +1,18 @@ +/* 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/. */ + +//! This module contains traits in script used generically in the rest of Servo. +//! The traits are here instead of in script so that these modules won't have +//! to depend on script. + +#![deny(unsafe_code)] +#![feature(plugin)] +#![plugin(plugins)] + +#[allow(unused_extern_crates)] +#[macro_use] +extern crate bitflags; +extern crate style; + +pub mod restyle_damage; diff --git a/components/script_layout_interface/restyle_damage.rs b/components/script_layout_interface/restyle_damage.rs new file mode 100644 index 00000000000..56a068a2237 --- /dev/null +++ b/components/script_layout_interface/restyle_damage.rs @@ -0,0 +1,258 @@ +/* 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/. */ + +use std::fmt; +use std::sync::Arc; +use style::computed_values::display; +use style::dom::TRestyleDamage; +use style::properties::{ComputedValues, ServoComputedValues}; + +bitflags! { + #[doc = "Individual layout actions that may be necessary after restyling."] + pub flags RestyleDamage: u8 { + #[doc = "Repaint the node itself."] + #[doc = "Currently unused; need to decide how this propagates."] + const REPAINT = 0x01, + + #[doc = "Recompute the overflow regions (bounding box of object and all descendants)."] + #[doc = "Propagates down the flow tree because the computation is bottom-up."] + const STORE_OVERFLOW = 0x02, + + #[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."] + #[doc = "Propagates down the flow tree because the computation is"] + #[doc = "bottom-up."] + const BUBBLE_ISIZES = 0x04, + + #[doc = "Recompute actual inline-sizes and block-sizes, only taking out-of-flow children \ + into account. \ + Propagates up the flow tree because the computation is top-down."] + const REFLOW_OUT_OF_FLOW = 0x08, + + #[doc = "Recompute actual inline_sizes and block_sizes."] + #[doc = "Propagates up the flow tree because the computation is"] + #[doc = "top-down."] + const REFLOW = 0x10, + + #[doc = "Re-resolve generated content. \ + Propagates up the flow tree because the computation is inorder."] + const RESOLVE_GENERATED_CONTENT = 0x20, + + #[doc = "The entire flow needs to be reconstructed."] + const RECONSTRUCT_FLOW = 0x40 + } +} + +impl TRestyleDamage for RestyleDamage { + type ConcreteComputedValues = ServoComputedValues; + fn compute(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> + RestyleDamage { compute_damage(old, new) } + + /// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed. + /// + /// Use this instead of `RestyleDamage::all()` because `RestyleDamage::all()` will result in + /// unnecessary sequential resolution of generated content. + fn rebuild_and_reflow() -> RestyleDamage { + REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW + } +} + +impl RestyleDamage { + /// Supposing a flow has the given `position` property and this damage, returns the damage that + /// we should add to the *parent* of this flow. + pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage { + if child_is_absolutely_positioned { + self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT) + } else { + self & (REPAINT | STORE_OVERFLOW | REFLOW | REFLOW_OUT_OF_FLOW | + RESOLVE_GENERATED_CONTENT) + } + } + + /// Supposing the *parent* of a flow with the given `position` property has this damage, + /// returns the damage that we should add to this flow. + pub fn damage_for_child(self, + parent_is_absolutely_positioned: bool, + child_is_absolutely_positioned: bool) + -> RestyleDamage { + match (parent_is_absolutely_positioned, child_is_absolutely_positioned) { + (false, true) => { + // Absolute children are out-of-flow and therefore insulated from changes. + // + // FIXME(pcwalton): Au contraire, if the containing block dimensions change! + self & REPAINT + } + (true, false) => { + // Changing the position of an absolutely-positioned block requires us to reflow + // its kids. + if self.contains(REFLOW_OUT_OF_FLOW) { + self | REFLOW + } else { + self + } + } + _ => { + // TODO(pcwalton): Take floatedness into account. + self & (REPAINT | REFLOW) + } + } + } +} + +impl fmt::Display for RestyleDamage { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + let mut first_elem = true; + + let to_iter = + [ (REPAINT, "Repaint") + , (STORE_OVERFLOW, "StoreOverflow") + , (BUBBLE_ISIZES, "BubbleISizes") + , (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow") + , (REFLOW, "Reflow") + , (RESOLVE_GENERATED_CONTENT, "ResolveGeneratedContent") + , (RECONSTRUCT_FLOW, "ReconstructFlow") + ]; + + for &(damage, damage_str) in &to_iter { + if self.contains(damage) { + if !first_elem { try!(write!(f, " | ")); } + try!(write!(f, "{}", damage_str)); + first_elem = false; + } + } + + if first_elem { + try!(write!(f, "NoDamage")); + } + + Ok(()) + } +} + +// NB: We need the braces inside the RHS due to Rust #8012. This particular +// version of this macro might be safe anyway, but we want to avoid silent +// breakage on modifications. +macro_rules! add_if_not_equal( + ($old:ident, $new:ident, $damage:ident, + [ $($effect:ident),* ], [ $($style_struct_getter:ident.$name:ident),* ]) => ({ + if $( ($old.$style_struct_getter().$name != $new.$style_struct_getter().$name) )||* { + $damage.insert($($effect)|*); + true + } else { + false + } + }) +); + +fn compute_damage(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> RestyleDamage { + let old: &ServoComputedValues = match old { + None => return RestyleDamage::rebuild_and_reflow(), + Some(cv) => &**cv, + }; + + let mut damage = RestyleDamage::empty(); + + // This should check every CSS property, as enumerated in the fields of + // http://doc.servo.org/style/properties/struct.ServoComputedValues.html + + // FIXME: Test somehow that every property is included. + + add_if_not_equal!(old, new, damage, + [ + REPAINT, + STORE_OVERFLOW, + BUBBLE_ISIZES, + REFLOW_OUT_OF_FLOW, + REFLOW, + RECONSTRUCT_FLOW + ], [ + get_box.float, get_box.display, get_box.position, get_counters.content, + get_counters.counter_reset, get_counters.counter_increment, + get_inheritedbox._servo_under_display_none, + get_list.quotes, get_list.list_style_type, + + // If these text or font properties change, we need to reconstruct the flow so that + // text shaping is re-run. + get_inheritedtext.letter_spacing, get_inheritedtext.text_rendering, + get_inheritedtext.text_transform, get_inheritedtext.word_spacing, + get_inheritedtext.overflow_wrap, get_inheritedtext.text_justify, + get_inheritedtext.white_space, get_inheritedtext.word_break, get_text.text_overflow, + get_font.font_family, get_font.font_style, get_font.font_variant, get_font.font_weight, + get_font.font_size, get_font.font_stretch, + get_inheritedbox.direction, get_inheritedbox.writing_mode, + get_inheritedbox.text_orientation, + get_text.text_decoration, get_text.unicode_bidi, + get_inheritedtable.empty_cells, get_inheritedtable.caption_side, + get_column.column_width, get_column.column_count + ]) || (new.get_box().display == display::T::inline && + add_if_not_equal!(old, new, damage, + [REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW, + RECONSTRUCT_FLOW], [ + // For inline boxes only, border/padding styles are used in flow construction (to decide + // whether to create fragments for empty flows). + get_border.border_top_width, get_border.border_right_width, + get_border.border_bottom_width, get_border.border_left_width, + get_padding.padding_top, get_padding.padding_right, + get_padding.padding_bottom, get_padding.padding_left + ])) || add_if_not_equal!(old, new, damage, + [ REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW ], + [get_border.border_top_width, get_border.border_right_width, + get_border.border_bottom_width, get_border.border_left_width, + get_margin.margin_top, get_margin.margin_right, + get_margin.margin_bottom, get_margin.margin_left, + get_padding.padding_top, get_padding.padding_right, + get_padding.padding_bottom, get_padding.padding_left, + get_position.width, get_position.height, + get_inheritedtext.line_height, + get_inheritedtext.text_align, get_inheritedtext.text_indent, + get_table.table_layout, + get_inheritedtable.border_collapse, + get_inheritedtable.border_spacing, + get_column.column_gap, + get_position.flex_direction, + get_position.flex_wrap, + get_position.justify_content, + get_position.align_items, + get_position.align_content, + get_position.order, + get_position.flex_basis, + get_position.flex_grow, + get_position.flex_shrink, + get_position.align_self + ]) || add_if_not_equal!(old, new, damage, + [ REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW ], [ + get_position.top, get_position.left, + get_position.right, get_position.bottom + ]) || add_if_not_equal!(old, new, damage, + [ REPAINT ], [ + get_color.color, get_background.background_color, + get_background.background_image, get_background.background_position, + get_background.background_repeat, get_background.background_attachment, + get_background.background_clip, get_background.background_origin, + get_background.background_size, + get_border.border_top_color, get_border.border_right_color, + get_border.border_bottom_color, get_border.border_left_color, + get_border.border_top_style, get_border.border_right_style, + get_border.border_bottom_style, get_border.border_left_style, + get_border.border_top_left_radius, get_border.border_top_right_radius, + get_border.border_bottom_left_radius, get_border.border_bottom_right_radius, + get_position.z_index, get_box._servo_overflow_clip_box, + get_inheritedtext._servo_text_decorations_in_effect, + get_pointing.cursor, get_pointing.pointer_events, + get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter, + get_effects.transform, get_effects.backface_visibility, get_effects.transform_style, + get_effects.transform_origin, get_effects.perspective, get_effects.perspective_origin, + get_effects.mix_blend_mode, get_inheritedbox.image_rendering, + + // Note: May require REFLOW et al. if `visibility: collapse` is implemented. + get_inheritedbox.visibility + ]); + + // If the layer requirements of this flow have changed due to the value + // of the transform, then reflow is required to rebuild the layers. + if old.transform_requires_layer() != new.transform_requires_layer() { + damage.insert(RestyleDamage::rebuild_and_reflow()); + } + + damage +} diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 83f29f58b55..d2e8c8a42e4 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1157,6 +1157,7 @@ dependencies = [ "range 0.0.1", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", + "script_layout_interface 0.0.1", "script_traits 0.0.1", "selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1925,6 +1926,15 @@ dependencies = [ ] [[package]] +name = "script_layout_interface" +version = "0.0.1" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plugins 0.0.1", + "style 0.0.1", +] + +[[package]] name = "script_tests" version = "0.0.1" dependencies = [ diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 4f38089fbc3..4edf3ccacc0 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -1070,6 +1070,7 @@ dependencies = [ "range 0.0.1", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "script 0.0.1", + "script_layout_interface 0.0.1", "script_traits 0.0.1", "selectors 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1783,6 +1784,15 @@ dependencies = [ ] [[package]] +name = "script_layout_interface" +version = "0.0.1" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plugins 0.0.1", + "style 0.0.1", +] + +[[package]] name = "script_traits" version = "0.0.1" dependencies = [ |