diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 370ebcdf22f6..e544567250c9 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -10,7 +10,7 @@ #![deny(unsafe_code)] -use app_units::{AU_PER_PX, Au}; +use app_units::{Au, AU_PER_PX}; use block::{BlockFlow, BlockStackingContextType}; use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg}; use context::LayoutContext; @@ -22,7 +22,7 @@ use fnv::FnvHashMap; use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo}; use fragment::SpecificFragmentInfo; use gfx::display_list; -use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDetails, BorderDisplayItem}; +use gfx::display_list::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR}; use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClipScrollNode}; use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling}; use gfx::display_list::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList}; @@ -33,7 +33,7 @@ use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, Stacki use gfx::display_list::{StackingContextType, StickyFrameData, TextDisplayItem, TextOrientation}; use gfx::display_list::WebRenderImageInfo; use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId}; -use inline::{InlineFragmentNodeFlags, InlineFlow}; +use inline::{InlineFlow, InlineFragmentNodeFlags}; use ipc_channel::ipc; use list_item::ListItemFlow; use model::{self, MaybeAuto}; @@ -91,12 +91,8 @@ trait ResolvePercentage { impl ResolvePercentage for NumberOrPercentage { fn resolve(&self, length: u32) -> u32 { match *self { - NumberOrPercentage::Percentage(p) => { - (p.0 * length as f32).round() as u32 - } - NumberOrPercentage::Number(n) => { - n.round() as u32 - } + NumberOrPercentage::Percentage(p) => (p.0 * length as f32).round() as u32, + NumberOrPercentage::Number(n) => n.round() as u32, } } } @@ -110,11 +106,12 @@ fn convert_repeat_mode(from: RepeatKeyword) -> RepeatMode { } } -fn establishes_containing_block_for_absolute(flags: StackingContextCollectionFlags, - positioning: StylePosition) - -> bool { +fn establishes_containing_block_for_absolute( + flags: StackingContextCollectionFlags, + positioning: StylePosition, +) -> bool { !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) && - StylePosition::Static != positioning + StylePosition::Static != positioning } trait RgbColor { @@ -127,20 +124,60 @@ impl RgbColor for ColorF { r: (r as f32) / (255.0 as f32), g: (g as f32) / (255.0 as f32), b: (b as f32) / (255.0 as f32), - a: 1.0 as f32 + a: 1.0 as f32, } } } static THREAD_TINT_COLORS: [ColorF; 8] = [ - ColorF { r: 6.0 / 255.0, g: 153.0 / 255.0, b: 198.0 / 255.0, a: 0.7 }, - ColorF { r: 255.0 / 255.0, g: 212.0 / 255.0, b: 83.0 / 255.0, a: 0.7 }, - ColorF { r: 116.0 / 255.0, g: 29.0 / 255.0, b: 109.0 / 255.0, a: 0.7 }, - ColorF { r: 204.0 / 255.0, g: 158.0 / 255.0, b: 199.0 / 255.0, a: 0.7 }, - ColorF { r: 242.0 / 255.0, g: 46.0 / 255.0, b: 121.0 / 255.0, a: 0.7 }, - ColorF { r: 116.0 / 255.0, g: 203.0 / 255.0, b: 196.0 / 255.0, a: 0.7 }, - ColorF { r: 255.0 / 255.0, g: 249.0 / 255.0, b: 201.0 / 255.0, a: 0.7 }, - ColorF { r: 137.0 / 255.0, g: 196.0 / 255.0, b: 78.0 / 255.0, a: 0.7 }, + ColorF { + r: 6.0 / 255.0, + g: 153.0 / 255.0, + b: 198.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 255.0 / 255.0, + g: 212.0 / 255.0, + b: 83.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 116.0 / 255.0, + g: 29.0 / 255.0, + b: 109.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 204.0 / 255.0, + g: 158.0 / 255.0, + b: 199.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 242.0 / 255.0, + g: 46.0 / 255.0, + b: 121.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 116.0 / 255.0, + g: 203.0 / 255.0, + b: 196.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 255.0 / 255.0, + g: 249.0 / 255.0, + b: 201.0 / 255.0, + a: 0.7, + }, + ColorF { + r: 137.0 / 255.0, + g: 196.0 / 255.0, + b: 78.0 / 255.0, + a: 0.7, + }, ]; fn get_cyclic(arr: &[T], index: usize) -> &T { @@ -249,12 +286,14 @@ impl StackingContextCollectionState { mem::replace(&mut self.next_stacking_context_id, next_stacking_context_id) } - fn add_stacking_context(&mut self, - parent_id: StackingContextId, - stacking_context: StackingContext) { + fn add_stacking_context( + &mut self, + parent_id: StackingContextId, + stacking_context: StackingContext, + ) { let info = self.stacking_context_info - .entry(parent_id) - .or_insert(StackingContextInfo::new()); + .entry(parent_id) + .or_insert(StackingContextInfo::new()); info.children.push(stacking_context); } @@ -266,8 +305,8 @@ impl StackingContextCollectionState { self.clip_scroll_nodes.push(clip_scroll_node); let index = ClipScrollNodeIndex(self.clip_scroll_nodes.len() - 1); let info = self.stacking_context_info - .entry(self.current_real_stacking_context_id) - .or_insert(StackingContextInfo::new()); + .entry(self.current_real_stacking_context_id) + .or_insert(StackingContextInfo::new()); info.clip_scroll_nodes.push(index); index } @@ -307,9 +346,10 @@ pub struct DisplayListBuildState<'a> { } impl<'a> DisplayListBuildState<'a> { - pub fn new(layout_context: &'a LayoutContext, - state: StackingContextCollectionState) - -> DisplayListBuildState<'a> { + pub fn new( + layout_context: &'a LayoutContext, + state: StackingContextCollectionState, + ) -> DisplayListBuildState<'a> { let root_clip_indices = ClippingAndScrolling::simple(ClipScrollNodeIndex(0)); DisplayListBuildState { layout_context: layout_context, @@ -325,7 +365,9 @@ impl<'a> DisplayListBuildState<'a> { } fn add_display_item(&mut self, display_item: DisplayItem) { - let items = self.items.entry(display_item.stacking_context_id()).or_insert(Vec::new()); + let items = self.items + .entry(display_item.stacking_context_id()) + .or_insert(Vec::new()); items.push(display_item); } @@ -339,33 +381,37 @@ impl<'a> DisplayListBuildState<'a> { fn is_background_or_border_of_clip_scroll_node(&self, section: DisplayListSection) -> bool { (section == DisplayListSection::BackgroundAndBorders || - section == DisplayListSection::BlockBackgroundsAndBorders) && - self.processing_scrolling_overflow_element + section == DisplayListSection::BlockBackgroundsAndBorders) && + self.processing_scrolling_overflow_element } - fn create_base_display_item(&self, - bounds: &Rect, - clip: LocalClip, - node: OpaqueNode, - cursor: Option, - section: DisplayListSection) - -> BaseDisplayItem { + fn create_base_display_item( + &self, + bounds: &Rect, + clip: LocalClip, + node: OpaqueNode, + cursor: Option, + section: DisplayListSection, + ) -> BaseDisplayItem { let clipping_and_scrolling = if self.is_background_or_border_of_clip_scroll_node(section) { - ClippingAndScrolling::simple( - self.parent_clip_scroll_node_index(self.current_clipping_and_scrolling.scrolling)) + ClippingAndScrolling::simple(self.parent_clip_scroll_node_index( + self.current_clipping_and_scrolling.scrolling, + )) } else { self.current_clipping_and_scrolling }; - BaseDisplayItem::new(&bounds, - DisplayItemMetadata { - node: node, - pointing: cursor, - }, - clip, - section, - self.current_stacking_context_id, - clipping_and_scrolling) + BaseDisplayItem::new( + &bounds, + DisplayItemMetadata { + node: node, + pointing: cursor, + }, + clip, + section, + self.current_stacking_context_id, + clipping_and_scrolling, + ) } pub fn to_display_list(mut self) -> DisplayList { @@ -380,65 +426,87 @@ impl<'a> DisplayListBuildState<'a> { } } - fn to_display_list_for_stacking_context(&mut self, - list: &mut Vec, - stacking_context: StackingContext) { - let mut child_items = self.items.remove(&stacking_context.id).unwrap_or(Vec::new()); + fn to_display_list_for_stacking_context( + &mut self, + list: &mut Vec, + stacking_context: StackingContext, + ) { + let mut child_items = self.items + .remove(&stacking_context.id) + .unwrap_or(Vec::new()); child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section)); child_items.reverse(); - let mut info = self.stacking_context_info.remove(&stacking_context.id) - .unwrap_or_else(StackingContextInfo::new); + let mut info = self.stacking_context_info + .remove(&stacking_context.id) + .unwrap_or_else(StackingContextInfo::new); info.children.sort(); if stacking_context.context_type != StackingContextType::Real { - list.extend(info.clip_scroll_nodes.into_iter().map(|index| index.to_define_item())); + list.extend( + info.clip_scroll_nodes + .into_iter() + .map(|index| index.to_define_item()), + ); self.to_display_list_for_items(list, child_items, info.children); } else { let (push_item, pop_item) = stacking_context.to_display_list_items(); list.push(push_item); - list.extend(info.clip_scroll_nodes.into_iter().map(|index| index.to_define_item())); + list.extend( + info.clip_scroll_nodes + .into_iter() + .map(|index| index.to_define_item()), + ); self.to_display_list_for_items(list, child_items, info.children); list.push(pop_item); } } - fn to_display_list_for_items(&mut self, - list: &mut Vec, - mut child_items: Vec, - child_stacking_contexts: Vec) { + fn to_display_list_for_items( + &mut self, + list: &mut Vec, + mut child_items: Vec, + child_stacking_contexts: Vec, + ) { // Properly order display items that make up a stacking context. "Steps" here // refer to the steps in CSS 2.1 Appendix E. // Steps 1 and 2: Borders and background for the root. - while child_items.last().map_or(false, - |child| child.section() == DisplayListSection::BackgroundAndBorders) { + while child_items.last().map_or(false, |child| { + child.section() == DisplayListSection::BackgroundAndBorders + }) { list.push(child_items.pop().unwrap()); } // Step 3: Positioned descendants with negative z-indices. let mut child_stacking_contexts = child_stacking_contexts.into_iter().peekable(); - while child_stacking_contexts.peek().map_or(false, |child| child.z_index < 0) { + while child_stacking_contexts + .peek() + .map_or(false, |child| child.z_index < 0) + { let context = child_stacking_contexts.next().unwrap(); self.to_display_list_for_stacking_context(list, context); } // Step 4: Block backgrounds and borders. - while child_items.last().map_or(false, - |child| child.section() == DisplayListSection::BlockBackgroundsAndBorders) { + while child_items.last().map_or(false, |child| { + child.section() == DisplayListSection::BlockBackgroundsAndBorders + }) { list.push(child_items.pop().unwrap()); } // Step 5: Floats. - while child_stacking_contexts.peek().map_or(false, - |child| child.context_type == StackingContextType::PseudoFloat) { + while child_stacking_contexts.peek().map_or(false, |child| { + child.context_type == StackingContextType::PseudoFloat + }) { let context = child_stacking_contexts.next().unwrap(); self.to_display_list_for_stacking_context(list, context); } // Step 6 & 7: Content and inlines that generate stacking contexts. - while child_items.last().map_or(false, - |child| child.section() == DisplayListSection::Content) { + while child_items.last().map_or(false, |child| { + child.section() == DisplayListSection::Content + }) { list.push(child_items.pop().unwrap()); } @@ -464,17 +532,20 @@ pub enum IdType { } pub trait FragmentDisplayListBuilding { - fn collect_stacking_contexts_for_blocklike_fragment(&mut self, - state: &mut StackingContextCollectionState) - -> bool; + fn collect_stacking_contexts_for_blocklike_fragment( + &mut self, + state: &mut StackingContextCollectionState, + ) -> bool; /// Adds the display items necessary to paint the background of this fragment to the display /// list if necessary. - fn build_display_list_for_background_if_applicable(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - display_list_section: DisplayListSection, - absolute_bounds: &Rect); + fn build_display_list_for_background_if_applicable( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + display_list_section: DisplayListSection, + absolute_bounds: &Rect, + ); /// Determines where to place an element background image or gradient. /// @@ -486,38 +557,43 @@ pub trait FragmentDisplayListBuilding { style: &ComputedValues, absolute_bounds: Rect, intrinsic_size: Option>, - index: usize + index: usize, ) -> BackgroundPlacement; /// Adds the display items necessary to paint a webrender image of this fragment to the /// appropriate section of the display list. - fn build_display_list_for_webrender_image(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - display_list_section: DisplayListSection, - absolute_bounds: Rect, - webrender_image: WebRenderImageInfo, - index: usize); + fn build_display_list_for_webrender_image( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + display_list_section: DisplayListSection, + absolute_bounds: Rect, + webrender_image: WebRenderImageInfo, + index: usize, + ); /// Calculates the webrender image for a paint worklet. /// Returns None if the worklet is not registered. /// If the worklet has missing image URLs, it passes them to the image cache for loading. - fn get_webrender_image_for_paint_worklet(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - paint_worklet: &PaintWorklet, - size: Size2D) - -> Option; + fn get_webrender_image_for_paint_worklet( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + paint_worklet: &PaintWorklet, + size: Size2D, + ) -> Option; /// Adds the display items necessary to paint the background linear gradient of this fragment /// to the appropriate section of the display list. - fn build_display_list_for_background_gradient(&self, - state: &mut DisplayListBuildState, - display_list_section: DisplayListSection, - absolute_bounds: Rect, - gradient: &Gradient, - style: &ComputedValues, - index: usize); + fn build_display_list_for_background_gradient( + &self, + state: &mut DisplayListBuildState, + display_list_section: DisplayListSection, + absolute_bounds: Rect, + gradient: &Gradient, + style: &ComputedValues, + index: usize, + ); /// Adds the display items necessary to paint the borders of this fragment to a display list if /// necessary. @@ -534,35 +610,43 @@ pub trait FragmentDisplayListBuilding { /// Adds the display items necessary to paint the outline of this fragment to the display list /// if necessary. - fn build_display_list_for_outline_if_applicable(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - bounds: &Rect, - clip: &Rect); + fn build_display_list_for_outline_if_applicable( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + bounds: &Rect, + clip: &Rect, + ); /// Adds the display items necessary to paint the box shadow of this fragment to the display /// list if necessary. - fn build_display_list_for_box_shadow_if_applicable(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - display_list_section: DisplayListSection, - absolute_bounds: &Rect, - clip: &Rect); + fn build_display_list_for_box_shadow_if_applicable( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + display_list_section: DisplayListSection, + absolute_bounds: &Rect, + clip: &Rect, + ); /// Adds display items necessary to draw debug boxes around a scanned text fragment. - fn build_debug_borders_around_text_fragments(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - stacking_relative_border_box: &Rect, - stacking_relative_content_box: &Rect, - text_fragment: &ScannedTextFragmentInfo, - clip: &Rect); + fn build_debug_borders_around_text_fragments( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + stacking_relative_border_box: &Rect, + stacking_relative_content_box: &Rect, + text_fragment: &ScannedTextFragmentInfo, + clip: &Rect, + ); /// Adds display items necessary to draw debug boxes around this fragment. - fn build_debug_borders_around_fragment(&self, - state: &mut DisplayListBuildState, - stacking_relative_border_box: &Rect, - clip: &Rect); + fn build_debug_borders_around_fragment( + &self, + state: &mut DisplayListBuildState, + stacking_relative_border_box: &Rect, + clip: &Rect, + ); /// Adds the display items for this fragment to the given display list. /// @@ -576,46 +660,56 @@ pub trait FragmentDisplayListBuilding { /// * `relative_containing_block_size`: The size of the containing block that /// `position: relative` makes use of. /// * `clip`: The region to clip the display items to. - fn build_display_list(&mut self, - state: &mut DisplayListBuildState, - stacking_relative_flow_origin: &Vector2D, - relative_containing_block_size: &LogicalSize, - relative_containing_block_mode: WritingMode, - border_painting_mode: BorderPaintingMode, - display_list_section: DisplayListSection, - clip: &Rect); + fn build_display_list( + &mut self, + state: &mut DisplayListBuildState, + stacking_relative_flow_origin: &Vector2D, + relative_containing_block_size: &LogicalSize, + relative_containing_block_mode: WritingMode, + border_painting_mode: BorderPaintingMode, + display_list_section: DisplayListSection, + clip: &Rect, + ); /// Builds the display items necessary to paint the selection and/or caret for this fragment, /// if any. - fn build_display_items_for_selection_if_necessary(&self, - state: &mut DisplayListBuildState, - stacking_relative_border_box: &Rect, - display_list_section: DisplayListSection, - clip: &Rect); + fn build_display_items_for_selection_if_necessary( + &self, + state: &mut DisplayListBuildState, + stacking_relative_border_box: &Rect, + display_list_section: DisplayListSection, + clip: &Rect, + ); /// Creates the text display item for one text fragment. This can be called multiple times for /// one fragment if there are text shadows. /// /// `text_shadow` will be `Some` if this is rendering a shadow. - fn build_display_list_for_text_fragment(&self, - state: &mut DisplayListBuildState, - text_fragment: &ScannedTextFragmentInfo, - stacking_relative_content_box: &Rect, - text_shadows: &[SimpleShadow], - clip: &Rect); + fn build_display_list_for_text_fragment( + &self, + state: &mut DisplayListBuildState, + text_fragment: &ScannedTextFragmentInfo, + stacking_relative_content_box: &Rect, + text_shadows: &[SimpleShadow], + clip: &Rect, + ); /// Creates the display item for a text decoration: underline, overline, or line-through. - fn build_display_list_for_text_decoration(&self, - state: &mut DisplayListBuildState, - color: &RGBA, - stacking_relative_box: &LogicalRect, - clip: &Rect); + fn build_display_list_for_text_decoration( + &self, + state: &mut DisplayListBuildState, + color: &RGBA, + stacking_relative_box: &LogicalRect, + clip: &Rect, + ); /// A helper method that `build_display_list` calls to create per-fragment-type display items. - fn build_fragment_type_specific_display_items(&mut self, - state: &mut DisplayListBuildState, - stacking_relative_border_box: &Rect, - clip: &Rect); + fn build_fragment_type_specific_display_items( + &mut self, + state: &mut DisplayListBuildState, + stacking_relative_border_box: &Rect, + clip: &Rect, + ); /// Creates a stacking context for associated fragment. fn create_stacking_context( @@ -624,7 +718,7 @@ pub trait FragmentDisplayListBuilding { base_flow: &BaseFlow, scroll_policy: ScrollPolicy, context_type: StackingContextType, - parent_clipping_and_scrolling: ClippingAndScrolling + parent_clipping_and_scrolling: ClippingAndScrolling, ) -> StackingContext; fn unique_id(&self, id_type: IdType) -> u64; @@ -646,10 +740,21 @@ fn handle_overlapping_radii(size: &Size2D, radii: &BorderRadii) -> Borde } let top_factor = scale_factor(radii.top_left.width, radii.top_right.width, size.width); - let bottom_factor = scale_factor(radii.bottom_left.width, radii.bottom_right.width, size.width); + let bottom_factor = scale_factor( + radii.bottom_left.width, + radii.bottom_right.width, + size.width, + ); let left_factor = scale_factor(radii.top_left.height, radii.bottom_left.height, size.height); - let right_factor = scale_factor(radii.top_right.height, radii.bottom_right.height, size.height); - let min_factor = top_factor.min(bottom_factor).min(left_factor).min(right_factor); + let right_factor = scale_factor( + radii.top_right.height, + radii.bottom_right.height, + size.height, + ); + let min_factor = top_factor + .min(bottom_factor) + .min(left_factor) + .min(right_factor); if min_factor < 1.0 { radii.scale_by(min_factor) } else { @@ -657,30 +762,43 @@ fn handle_overlapping_radii(size: &Size2D, radii: &BorderRadii) -> Borde } } -fn build_border_radius(abs_bounds: &Rect, - border_style: &style_structs::Border) - -> BorderRadii { +fn build_border_radius( + abs_bounds: &Rect, + border_style: &style_structs::Border, +) -> BorderRadii { // 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. - handle_overlapping_radii(&abs_bounds.size, &BorderRadii { - top_left: model::specified_border_radius(border_style.border_top_left_radius, - abs_bounds.size), - top_right: model::specified_border_radius(border_style.border_top_right_radius, - abs_bounds.size), - bottom_right: model::specified_border_radius(border_style.border_bottom_right_radius, - abs_bounds.size), - bottom_left: model::specified_border_radius(border_style.border_bottom_left_radius, - abs_bounds.size), - }) + handle_overlapping_radii( + &abs_bounds.size, + &BorderRadii { + top_left: model::specified_border_radius( + border_style.border_top_left_radius, + abs_bounds.size, + ), + top_right: model::specified_border_radius( + border_style.border_top_right_radius, + abs_bounds.size, + ), + bottom_right: model::specified_border_radius( + border_style.border_bottom_right_radius, + abs_bounds.size, + ), + bottom_left: model::specified_border_radius( + border_style.border_bottom_left_radius, + abs_bounds.size, + ), + }, + ) } /// Get the border radius for the rectangle inside of a rounded border. This is useful /// for building the clip for the content inside the border. -fn build_border_radius_for_inner_rect(outer_rect: &Rect, - style: &ComputedValues) - -> BorderRadii { +fn build_border_radius_for_inner_rect( + outer_rect: &Rect, + style: &ComputedValues, +) -> BorderRadii { let radii = build_border_radius(&outer_rect, style.get_border()); if radii.is_square() { return radii; @@ -693,9 +811,10 @@ fn build_border_radius_for_inner_rect(outer_rect: &Rect, calculate_inner_border_radii(radii, border_widths) } -fn build_inner_border_box_for_border_rect(border_box: &Rect, - style: &ComputedValues) - -> Rect { +fn build_inner_border_box_for_border_rect( + border_box: &Rect, + style: &ComputedValues, +) -> Rect { let border_widths = style.logical_border_width().to_physical(style.writing_mode); let mut inner_border_box = *border_box; inner_border_box.origin.x += border_widths.left; @@ -705,17 +824,17 @@ fn build_inner_border_box_for_border_rect(border_box: &Rect, inner_border_box } -fn convert_gradient_stops(gradient_items: &[GradientItem], - total_length: Au) -> Vec { +fn convert_gradient_stops(gradient_items: &[GradientItem], total_length: Au) -> Vec { // Determine the position of each stop per CSS-IMAGES § 3.4. // Only keep the color stops, discard the color interpolation hints. - let mut stop_items = gradient_items.iter().filter_map(|item| { - match *item { + let mut stop_items = gradient_items + .iter() + .filter_map(|item| match *item { GenericGradientItem::ColorStop(ref stop) => Some(*stop), _ => None, - } - }).collect::>(); + }) + .collect::>(); assert!(stop_items.len() >= 2); @@ -743,8 +862,9 @@ fn convert_gradient_stops(gradient_items: &[GradientItem], let mut last_stop_position = stop_items.first().unwrap().position.unwrap(); for stop in stop_items.iter_mut().skip(1) { if let Some(pos) = stop.position { - if position_to_offset(last_stop_position, total_length) - > position_to_offset(pos, total_length) { + if position_to_offset(last_stop_position, total_length) > + position_to_offset(pos, total_length) + { stop.position = Some(last_stop_position); } last_stop_position = stop.position.unwrap(); @@ -785,76 +905,69 @@ fn convert_gradient_stops(gradient_items: &[GradientItem], stop_run.start_offset + stop_run_length * (i - stop_run.start_index) as f32 / ((2 + stop_run.stop_count) as f32) - } + }, Some(position) => { stop_run = None; position_to_offset(position, total_length) - } + }, }; assert!(offset.is_finite()); stops.push(GradientStop { offset: offset, - color: stop.color.to_gfx_color() + color: stop.color.to_gfx_color(), }) } stops } -fn convert_linear_gradient(size: Size2D, - stops: &[GradientItem], - direction: LineDirection, - repeating: bool) - -> display_list::Gradient { +fn convert_linear_gradient( + size: Size2D, + stops: &[GradientItem], + direction: LineDirection, + repeating: bool, +) -> display_list::Gradient { let angle = match direction { LineDirection::Angle(angle) => angle.radians(), - LineDirection::Horizontal(x) => { - match x { - X::Left => Angle::Deg(270.).radians(), - X::Right => Angle::Deg(90.).radians(), - } + LineDirection::Horizontal(x) => match x { + X::Left => Angle::Deg(270.).radians(), + X::Right => Angle::Deg(90.).radians(), }, - LineDirection::Vertical(y) => { - match y { - Y::Top => Angle::Deg(0.).radians(), - Y::Bottom => Angle::Deg(180.).radians(), - } + LineDirection::Vertical(y) => match y { + Y::Top => Angle::Deg(0.).radians(), + Y::Bottom => Angle::Deg(180.).radians(), }, LineDirection::Corner(horizontal, vertical) => { // This the angle for one of the diagonals of the box. Our angle // will either be this one, this one + PI, or one of the other // two perpendicular angles. - let atan = (size.height.to_f32_px() / - size.width.to_f32_px()).atan(); + let atan = (size.height.to_f32_px() / size.width.to_f32_px()).atan(); match (horizontal, vertical) { - (X::Right, Y::Bottom) - => f32::consts::PI - atan, - (X::Left, Y::Bottom) - => f32::consts::PI + atan, - (X::Right, Y::Top) - => atan, - (X::Left, Y::Top) - => -atan, + (X::Right, Y::Bottom) => f32::consts::PI - atan, + (X::Left, Y::Bottom) => f32::consts::PI + atan, + (X::Right, Y::Top) => atan, + (X::Left, Y::Top) => -atan, } - } + }, }; // Get correct gradient line length, based on: // https://drafts.csswg.org/css-images-3/#linear-gradients let dir = Point2D::new(angle.sin(), -angle.cos()); - let line_length = (dir.x * size.width.to_f32_px()).abs() + - (dir.y * size.height.to_f32_px()).abs(); + let line_length = + (dir.x * size.width.to_f32_px()).abs() + (dir.y * size.height.to_f32_px()).abs(); let inv_dir_length = 1.0 / (dir.x * dir.x + dir.y * dir.y).sqrt(); // This is the vector between the center and the ending point; i.e. half // of the distance between the starting point and the ending point. - let delta = Vector2D::new(Au::from_f32_px(dir.x * inv_dir_length * line_length / 2.0), - Au::from_f32_px(dir.y * inv_dir_length * line_length / 2.0)); + let delta = Vector2D::new( + Au::from_f32_px(dir.x * inv_dir_length * line_length / 2.0), + Au::from_f32_px(dir.y * inv_dir_length * line_length / 2.0), + ); // This is the length of the gradient line. - let length = Au::from_f32_px( - (delta.x.to_f32_px() * 2.0).hypot(delta.y.to_f32_px() * 2.0)); + let length = Au::from_f32_px((delta.x.to_f32_px() * 2.0).hypot(delta.y.to_f32_px() * 2.0)); let mut stops = convert_gradient_stops(stops, length); @@ -875,14 +988,17 @@ fn convert_linear_gradient(size: Size2D, } } -fn convert_radial_gradient(size: Size2D, - stops: &[GradientItem], - shape: EndingShape, - center: Position, - repeating: bool) - -> display_list::RadialGradient { - let center = Point2D::new(center.horizontal.to_used_value(size.width), - center.vertical.to_used_value(size.height)); +fn convert_radial_gradient( + size: Size2D, + stops: &[GradientItem], + shape: EndingShape, + center: Position, + repeating: bool, +) -> display_list::RadialGradient { + let center = Point2D::new( + center.horizontal.to_used_value(size.width), + center.vertical.to_used_value(size.height), + ); let radius = match shape { GenericEndingShape::Circle(Circle::Radius(length)) => { let length = Au::from(length); @@ -929,10 +1045,13 @@ fn convert_radial_gradient(size: Size2D, fn fix_gradient_stops(stops: &mut Vec) { if stops.first().unwrap().offset > 0.0 { let color = stops.first().unwrap().color; - stops.insert(0, GradientStop { - offset: 0.0, - color: color, - }) + stops.insert( + 0, + GradientStop { + offset: 0.0, + color: color, + }, + ) } if stops.last().unwrap().offset < 1.0 { let color = stops.last().unwrap().color; @@ -945,7 +1064,8 @@ fn fix_gradient_stops(stops: &mut Vec) { /// Returns the the distance to the nearest or farthest corner depending on the comperator. fn get_distance_to_corner(size: &Size2D, center: &Point2D, cmp: F) -> Au - where F: Fn(Au, Au) -> Au +where + F: Fn(Au, Au) -> Au, { let dist = get_distance_to_sides(size, center, cmp); Au::from_f32_px(dist.width.to_f32_px().hypot(dist.height.to_f32_px())) @@ -955,7 +1075,8 @@ fn get_distance_to_corner(size: &Size2D, center: &Point2D, cmp: F) -> /// /// The first return value is horizontal distance the second vertical distance. fn get_distance_to_sides(size: &Size2D, center: &Point2D, cmp: F) -> Size2D - where F: Fn(Au, Au) -> Au +where + F: Fn(Au, Au) -> Au, { let top_side = center.y; let right_side = size.width - center.x; @@ -966,30 +1087,34 @@ fn get_distance_to_sides(size: &Size2D, center: &Point2D, cmp: F) -> /// Returns the radius for an ellipse with the same ratio as if it was matched to the sides. fn get_ellipse_radius(size: &Size2D, center: &Point2D, cmp: F) -> Size2D - where F: Fn(Au, Au) -> Au +where + F: Fn(Au, Au) -> Au, { let dist = get_distance_to_sides(size, center, cmp); - Size2D::new(dist.width.scale_by(::std::f32::consts::FRAC_1_SQRT_2 * 2.0), - dist.height.scale_by(::std::f32::consts::FRAC_1_SQRT_2 * 2.0)) + Size2D::new( + dist.width.scale_by(::std::f32::consts::FRAC_1_SQRT_2 * 2.0), + dist.height + .scale_by(::std::f32::consts::FRAC_1_SQRT_2 * 2.0), + ) } /// Determines the radius of a circle if it was not explictly provided. /// -fn convert_circle_size_keyword(keyword: ShapeExtent, - size: &Size2D, - center: &Point2D) -> Size2D { +fn convert_circle_size_keyword( + keyword: ShapeExtent, + size: &Size2D, + center: &Point2D, +) -> Size2D { let radius = match keyword { ShapeExtent::ClosestSide | ShapeExtent::Contain => { let dist = get_distance_to_sides(size, center, ::std::cmp::min); ::std::cmp::min(dist.width, dist.height) - } + }, ShapeExtent::FarthestSide => { let dist = get_distance_to_sides(size, center, ::std::cmp::max); ::std::cmp::max(dist.width, dist.height) - } - ShapeExtent::ClosestCorner => { - get_distance_to_corner(size, center, ::std::cmp::min) }, + ShapeExtent::ClosestCorner => get_distance_to_corner(size, center, ::std::cmp::min), ShapeExtent::FarthestCorner | ShapeExtent::Cover => { get_distance_to_corner(size, center, ::std::cmp::max) }, @@ -999,19 +1124,17 @@ fn convert_circle_size_keyword(keyword: ShapeExtent, /// Determines the radius of an ellipse if it was not explictly provided. /// -fn convert_ellipse_size_keyword(keyword: ShapeExtent, - size: &Size2D, - center: &Point2D) -> Size2D { +fn convert_ellipse_size_keyword( + keyword: ShapeExtent, + size: &Size2D, + center: &Point2D, +) -> Size2D { match keyword { ShapeExtent::ClosestSide | ShapeExtent::Contain => { get_distance_to_sides(size, center, ::std::cmp::min) }, - ShapeExtent::FarthestSide => { - get_distance_to_sides(size, center, ::std::cmp::max) - }, - ShapeExtent::ClosestCorner => { - get_ellipse_radius(size, center, ::std::cmp::min) - }, + ShapeExtent::FarthestSide => get_distance_to_sides(size, center, ::std::cmp::max), + ShapeExtent::ClosestCorner => get_ellipse_radius(size, center, ::std::cmp::min), ShapeExtent::FarthestCorner | ShapeExtent::Cover => { get_ellipse_radius(size, center, ::std::cmp::max) }, @@ -1032,7 +1155,7 @@ fn calculate_inner_bounds(mut bounds: Rect, offsets: SideOffsets2D) -> R fn calculate_inner_border_radii( mut radii: BorderRadii, - offsets: SideOffsets2D + offsets: SideOffsets2D, ) -> BorderRadii { radii.top_left.width = cmp::max(Au(0), radii.top_left.width - offsets.left); radii.bottom_left.width = cmp::max(Au(0), radii.bottom_left.width - offsets.left); @@ -1048,73 +1171,84 @@ fn calculate_inner_border_radii( radii } - /// For a given area and an image compute how big the /// image should be displayed on the background. -fn compute_background_image_size(bg_size: BackgroundSize, - bounds_size: Size2D, - intrinsic_size: Option>) - -> Size2D { +fn compute_background_image_size( + bg_size: BackgroundSize, + bounds_size: Size2D, + intrinsic_size: Option>, +) -> Size2D { match intrinsic_size { - None => { - match bg_size { - BackgroundSize::Cover | BackgroundSize::Contain => bounds_size, - BackgroundSize::Explicit { width, height } => { - Size2D::new( - MaybeAuto::from_style(width, bounds_size.width) - .specified_or_default(bounds_size.width), - MaybeAuto::from_style(height, bounds_size.height) - .specified_or_default(bounds_size.height) - ) - } - } - } + None => match bg_size { + BackgroundSize::Cover | BackgroundSize::Contain => bounds_size, + BackgroundSize::Explicit { width, height } => Size2D::new( + MaybeAuto::from_style(width, bounds_size.width) + .specified_or_default(bounds_size.width), + MaybeAuto::from_style(height, bounds_size.height) + .specified_or_default(bounds_size.height), + ), + }, Some(own_size) => { // If `image_aspect_ratio` < `bounds_aspect_ratio`, the image is tall; otherwise, it is // wide. let image_aspect_ratio = own_size.width.to_f32_px() / own_size.height.to_f32_px(); - let bounds_aspect_ratio = bounds_size.width.to_f32_px() / bounds_size.height.to_f32_px(); + let bounds_aspect_ratio = + bounds_size.width.to_f32_px() / bounds_size.height.to_f32_px(); match (bg_size, image_aspect_ratio < bounds_aspect_ratio) { - (BackgroundSize::Contain, false) | (BackgroundSize::Cover, true) => { - Size2D::new(bounds_size.width, - bounds_size.width.scale_by(image_aspect_ratio.recip())) - } + (BackgroundSize::Contain, false) | (BackgroundSize::Cover, true) => Size2D::new( + bounds_size.width, + bounds_size.width.scale_by(image_aspect_ratio.recip()), + ), - (BackgroundSize::Contain, true) | (BackgroundSize::Cover, false) => { - Size2D::new(bounds_size.height.scale_by(image_aspect_ratio), - bounds_size.height) - } + (BackgroundSize::Contain, true) | (BackgroundSize::Cover, false) => Size2D::new( + bounds_size.height.scale_by(image_aspect_ratio), + bounds_size.height, + ), - (BackgroundSize::Explicit { width, height: LengthOrPercentageOrAuto::Auto }, _) => { + ( + BackgroundSize::Explicit { + width, + height: LengthOrPercentageOrAuto::Auto, + }, + _, + ) => { let width = MaybeAuto::from_style(width, bounds_size.width) - .specified_or_default(own_size.width); + .specified_or_default(own_size.width); Size2D::new(width, width.scale_by(image_aspect_ratio.recip())) - } + }, - (BackgroundSize::Explicit { width: LengthOrPercentageOrAuto::Auto, height }, _) => { + ( + BackgroundSize::Explicit { + width: LengthOrPercentageOrAuto::Auto, + height, + }, + _, + ) => { let height = MaybeAuto::from_style(height, bounds_size.height) - .specified_or_default(own_size.height); + .specified_or_default(own_size.height); Size2D::new(height.scale_by(image_aspect_ratio), height) - } + }, - (BackgroundSize::Explicit { width, height }, _) => { - Size2D::new(MaybeAuto::from_style(width, bounds_size.width) - .specified_or_default(own_size.width), - MaybeAuto::from_style(height, bounds_size.height) - .specified_or_default(own_size.height)) - } + (BackgroundSize::Explicit { width, height }, _) => Size2D::new( + MaybeAuto::from_style(width, bounds_size.width) + .specified_or_default(own_size.width), + MaybeAuto::from_style(height, bounds_size.height) + .specified_or_default(own_size.height), + ), } - } + }, } } -fn tile_image_round(position: &mut Au, - size: &mut Au, - absolute_anchor_origin: Au, - image_size: &mut Au) { +fn tile_image_round( + position: &mut Au, + size: &mut Au, + absolute_anchor_origin: Au, + image_size: &mut Au, +) { if *size == Au(0) || *image_size == Au(0) { *position = Au(0); - *size =Au(0); + *size = Au(0); return; } @@ -1123,11 +1257,13 @@ fn tile_image_round(position: &mut Au, tile_image(position, size, absolute_anchor_origin, *image_size); } -fn tile_image_spaced(position: &mut Au, - size: &mut Au, - tile_spacing: &mut Au, - absolute_anchor_origin: Au, - image_size: Au) { +fn tile_image_spaced( + position: &mut Au, + size: &mut Au, + tile_spacing: &mut Au, + absolute_anchor_origin: Au, + image_size: Au, +) { if *size == Au(0) || image_size == Au(0) { *position = Au(0); *size = Au(0); @@ -1138,10 +1274,7 @@ fn tile_image_spaced(position: &mut Au, // Per the spec, if the space available is not enough for two images, just tile as // normal but only display a single tile. if image_size * 2 >= *size { - tile_image(position, - size, - absolute_anchor_origin, - image_size); + tile_image(position, size, absolute_anchor_origin, image_size); *tile_spacing = Au(0); *size = image_size; return; @@ -1161,17 +1294,14 @@ fn tile_image_spaced(position: &mut Au, } /// Tile an image -fn tile_image(position: &mut Au, - size: &mut Au, - absolute_anchor_origin: Au, - image_size: Au) { +fn tile_image(position: &mut Au, size: &mut Au, absolute_anchor_origin: Au, image_size: Au) { // Avoid division by zero below! // Images with a zero width or height are not displayed. // Therefore the positions do not matter and can be left unchanged. // NOTE: A possible optimization is not to build // display items in this case at all. if image_size == Au(0) { - return + return; } let delta_pixels = absolute_anchor_origin - *position; @@ -1186,84 +1316,84 @@ fn tile_image(position: &mut Au, /// For either the x or the y axis ajust various values to account for tiling. /// /// This is done separately for both axes because the repeat keywords may differ. -fn tile_image_axis(repeat: BackgroundRepeatKeyword, - position: &mut Au, - size: &mut Au, - tile_size: &mut Au, - tile_spacing: &mut Au, - offset: Au, - clip_origin: Au, - clip_size: Au) -{ +fn tile_image_axis( + repeat: BackgroundRepeatKeyword, + position: &mut Au, + size: &mut Au, + tile_size: &mut Au, + tile_spacing: &mut Au, + offset: Au, + clip_origin: Au, + clip_size: Au, +) { let absolute_anchor_origin = *position + offset; match repeat { BackgroundRepeatKeyword::NoRepeat => { *position += offset; *size = *tile_size; - } + }, BackgroundRepeatKeyword::Repeat => { *position = clip_origin; *size = clip_size; tile_image(position, size, absolute_anchor_origin, *tile_size); - } + }, BackgroundRepeatKeyword::Space => { tile_image_spaced( position, size, tile_spacing, absolute_anchor_origin, - *tile_size); + *tile_size, + ); let combined_tile_size = *tile_size + *tile_spacing; *position = clip_origin; *size = clip_size; tile_image(position, size, absolute_anchor_origin, combined_tile_size); - } + }, BackgroundRepeatKeyword::Round => { - tile_image_round( - position, - size, - absolute_anchor_origin, - tile_size); + tile_image_round(position, size, absolute_anchor_origin, tile_size); *position = clip_origin; *size = clip_size; tile_image(position, size, absolute_anchor_origin, *tile_size); - } + }, } } impl FragmentDisplayListBuilding for Fragment { - fn collect_stacking_contexts_for_blocklike_fragment(&mut self, - state: &mut StackingContextCollectionState) - -> bool { + fn collect_stacking_contexts_for_blocklike_fragment( + &mut self, + state: &mut StackingContextCollectionState, + ) -> bool { match self.specific { SpecificFragmentInfo::InlineBlock(ref mut block_flow) => { let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref); block_flow.collect_stacking_contexts(state); true - } + }, SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => { let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref); block_flow.collect_stacking_contexts(state); true - } + }, SpecificFragmentInfo::InlineAbsolute(ref mut block_flow) => { let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref); block_flow.collect_stacking_contexts(state); true - } + }, // FIXME: In the future, if #15144 is fixed we can remove this case. See #18510. - SpecificFragmentInfo::TruncatedFragment(ref mut info) => { - info.full.collect_stacking_contexts_for_blocklike_fragment(state) - } + SpecificFragmentInfo::TruncatedFragment(ref mut info) => info.full + .collect_stacking_contexts_for_blocklike_fragment(state), _ => false, } } - fn build_display_list_for_background_if_applicable(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - display_list_section: DisplayListSection, - absolute_bounds: &Rect) { + fn build_display_list_for_background_if_applicable( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + display_list_section: DisplayListSection, + absolute_bounds: &Rect, + ) { // FIXME: This causes a lot of background colors to be displayed when they are clearly not // needed. We could use display list optimization to clean this up, but it still seems // inefficient. What we really want is something like "nearest ancestor element that @@ -1276,47 +1406,52 @@ impl FragmentDisplayListBuilding for Fragment { let mut bounds = *absolute_bounds; // This is the clip for the color (which is the last element in the bg array) - let color_clip = get_cyclic(&background.background_clip.0, - background.background_image.0.len() - 1); + let color_clip = get_cyclic( + &background.background_clip.0, + background.background_image.0.len() - 1, + ); // Adjust the clipping region as necessary to account for `border-radius`. let mut border_radii = build_border_radius(absolute_bounds, style.get_border()); match *color_clip { - BackgroundClip::BorderBox => {} + BackgroundClip::BorderBox => {}, BackgroundClip::PaddingBox => { let border = style.logical_border_width().to_physical(style.writing_mode); bounds = calculate_inner_bounds(bounds, border); border_radii = calculate_inner_border_radii(border_radii, border); - } + }, BackgroundClip::ContentBox => { let border_padding = self.border_padding.to_physical(style.writing_mode); bounds = calculate_inner_bounds(bounds, border_padding); border_radii = calculate_inner_border_radii(border_radii, border_padding); - } + }, } let clip = if !border_radii.is_square() { - LocalClip::RoundedRect(bounds.to_rectf(), ComplexClipRegion::new( + LocalClip::RoundedRect( bounds.to_rectf(), - border_radii.to_border_radius(), - ClipMode::Clip, - )) + ComplexClipRegion::new( + bounds.to_rectf(), + border_radii.to_border_radius(), + ClipMode::Clip, + ), + ) } else { LocalClip::Rect(bounds.to_rectf()) }; - - let base = state.create_base_display_item(&bounds, - clip, - self.node, - style.get_cursor(Cursor::Default), - display_list_section); - state.add_display_item( - DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { - base: base, - color: background_color.to_gfx_color(), - }))); + let base = state.create_base_display_item( + &bounds, + clip, + self.node, + style.get_cursor(Cursor::Default), + display_list_section, + ); + state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { + base: base, + color: background_color.to_gfx_color(), + }))); // The background image is painted on top of the background color. // Implements background image, per spec: @@ -1324,63 +1459,73 @@ impl FragmentDisplayListBuilding for Fragment { let background = style.get_background(); for (i, background_image) in background.background_image.0.iter().enumerate().rev() { match *background_image { - Either::First(_) => {} + Either::First(_) => {}, Either::Second(Image::Gradient(ref gradient)) => { - self.build_display_list_for_background_gradient(state, - display_list_section, - *absolute_bounds, - gradient, - style, - i); - } + self.build_display_list_for_background_gradient( + state, + display_list_section, + *absolute_bounds, + gradient, + style, + i, + ); + }, Either::Second(Image::Url(ref image_url)) => { if let Some(url) = image_url.url() { - let webrender_image = state.layout_context - .get_webrender_image_for_url(self.node, - url.clone(), - UsePlaceholder::No); + let webrender_image = state.layout_context.get_webrender_image_for_url( + self.node, + url.clone(), + UsePlaceholder::No, + ); if let Some(webrender_image) = webrender_image { - self.build_display_list_for_webrender_image(state, - style, - display_list_section, - *absolute_bounds, - webrender_image, - i); + self.build_display_list_for_webrender_image( + state, + style, + display_list_section, + *absolute_bounds, + webrender_image, + i, + ); } } - } + }, Either::Second(Image::PaintWorklet(ref paint_worklet)) => { let bounding_box = self.border_box - style.logical_border_width(); let bounding_box_size = bounding_box.size.to_physical(style.writing_mode); - let background_size = get_cyclic(&style.get_background().background_size.0, i).clone(); + let background_size = + get_cyclic(&style.get_background().background_size.0, i).clone(); let size = match background_size { - BackgroundSize::Explicit { width, height } => { - Size2D::new(MaybeAuto::from_style(width, bounding_box_size.width) - .specified_or_default(bounding_box_size.width), - MaybeAuto::from_style(height, bounding_box_size.height) - .specified_or_default(bounding_box_size.height)) - }, + BackgroundSize::Explicit { width, height } => Size2D::new( + MaybeAuto::from_style(width, bounding_box_size.width) + .specified_or_default(bounding_box_size.width), + MaybeAuto::from_style(height, bounding_box_size.height) + .specified_or_default(bounding_box_size.height), + ), _ => bounding_box_size, }; - let webrender_image = self.get_webrender_image_for_paint_worklet(state, - style, - paint_worklet, - size); + let webrender_image = self.get_webrender_image_for_paint_worklet( + state, + style, + paint_worklet, + size, + ); if let Some(webrender_image) = webrender_image { - self.build_display_list_for_webrender_image(state, - style, - display_list_section, - *absolute_bounds, - webrender_image, - i); + self.build_display_list_for_webrender_image( + state, + style, + display_list_section, + *absolute_bounds, + webrender_image, + i, + ); } - } + }, Either::Second(Image::Rect(_)) => { // TODO: Implement `-moz-image-rect` - } + }, Either::Second(Image::Element(_)) => { // TODO: Implement `-moz-element` - } + }, } } } @@ -1391,7 +1536,7 @@ impl FragmentDisplayListBuilding for Fragment { style: &ComputedValues, absolute_bounds: Rect, intrinsic_size: Option>, - index: usize + index: usize, ) -> BackgroundPlacement { let bg = style.get_background(); let bg_attachment = *get_cyclic(&bg.background_attachment.0, index); @@ -1447,7 +1592,7 @@ impl FragmentDisplayListBuilding for Fragment { &mut tile_spacing.width, pos_x, css_clip.origin.x, - css_clip.size.width + css_clip.size.width, ); tile_image_axis( bg_repeat.1, @@ -1457,38 +1602,43 @@ impl FragmentDisplayListBuilding for Fragment { &mut tile_spacing.height, pos_y, css_clip.origin.y, - css_clip.size.height + css_clip.size.height, ); - BackgroundPlacement { bounds, tile_size, tile_spacing, css_clip } + BackgroundPlacement { + bounds, + tile_size, + tile_spacing, + css_clip, + } } - fn build_display_list_for_webrender_image(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - display_list_section: DisplayListSection, - absolute_bounds: Rect, - webrender_image: WebRenderImageInfo, - index: usize) { + fn build_display_list_for_webrender_image( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + display_list_section: DisplayListSection, + absolute_bounds: Rect, + webrender_image: WebRenderImageInfo, + index: usize, + ) { debug!("(building display list) building background image"); let image = Size2D::new( Au::from_px(webrender_image.width as i32), - Au::from_px(webrender_image.height as i32)); - let placement = self.compute_background_placement( - state, - style, - absolute_bounds, - Some(image), - index + Au::from_px(webrender_image.height as i32), ); + let placement = + self.compute_background_placement(state, style, absolute_bounds, Some(image), index); // Create the image display item. - let base = state.create_base_display_item(&placement.bounds, - LocalClip::Rect(placement.css_clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - display_list_section); + let base = state.create_base_display_item( + &placement.bounds, + LocalClip::Rect(placement.css_clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + display_list_section, + ); debug!("(building display list) adding background image."); state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { @@ -1499,29 +1649,36 @@ impl FragmentDisplayListBuilding for Fragment { tile_spacing: placement.tile_spacing, image_rendering: style.get_inheritedbox().image_rendering.clone(), }))); - } - fn get_webrender_image_for_paint_worklet(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - paint_worklet: &PaintWorklet, - size_in_au: Size2D) - -> Option - { + fn get_webrender_image_for_paint_worklet( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + paint_worklet: &PaintWorklet, + size_in_au: Size2D, + ) -> Option { let device_pixel_ratio = state.layout_context.style_context.device_pixel_ratio(); - let size_in_px = TypedSize2D::new(size_in_au.width.to_f32_px(), size_in_au.height.to_f32_px()); + let size_in_px = + TypedSize2D::new(size_in_au.width.to_f32_px(), size_in_au.height.to_f32_px()); // TODO: less copying. let name = paint_worklet.name.clone(); - let arguments = paint_worklet.arguments.iter() + let arguments = paint_worklet + .arguments + .iter() .map(|argument| argument.to_css_string()) .collect(); let draw_result = match state.layout_context.registered_painters.get(&name) { Some(painter) => { - debug!("Drawing a paint image {}({},{}).", name, size_in_px.width, size_in_px.height); - let properties = painter.properties().iter() + debug!( + "Drawing a paint image {}({},{}).", + name, size_in_px.width, size_in_px.height + ); + let properties = painter + .properties() + .iter() .filter_map(|(name, id)| id.as_shorthand().err().map(|id| (name, id))) .map(|(name, id)| (name.clone(), style.computed_value_to_string(id))) .collect(); @@ -1543,7 +1700,11 @@ impl FragmentDisplayListBuilding for Fragment { for url in draw_result.missing_image_urls.into_iter() { debug!("Requesting missing image URL {}.", url); - state.layout_context.get_webrender_image_for_url(self.node, url, UsePlaceholder::No); + state.layout_context.get_webrender_image_for_url( + self.node, + url, + UsePlaceholder::No, + ); } Some(webrender_image) } else { @@ -1551,22 +1712,25 @@ impl FragmentDisplayListBuilding for Fragment { } } - fn build_display_list_for_background_gradient(&self, - state: &mut DisplayListBuildState, - display_list_section: DisplayListSection, - absolute_bounds: Rect, - gradient: &Gradient, - style: &ComputedValues, - index: usize) - { - let placement = self.compute_background_placement( - state, style, absolute_bounds, None, index); + fn build_display_list_for_background_gradient( + &self, + state: &mut DisplayListBuildState, + display_list_section: DisplayListSection, + absolute_bounds: Rect, + gradient: &Gradient, + style: &ComputedValues, + index: usize, + ) { + let placement = + self.compute_background_placement(state, style, absolute_bounds, None, index); - let base = state.create_base_display_item(&placement.bounds, - LocalClip::Rect(placement.css_clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - display_list_section); + let base = state.create_base_display_item( + &placement.bounds, + LocalClip::Rect(placement.css_clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + display_list_section, + ); let display_item = match gradient.kind { GradientKind::Linear(angle_or_corner) => { @@ -1574,38 +1738,42 @@ impl FragmentDisplayListBuilding for Fragment { placement.tile_size, &gradient.items[..], angle_or_corner, - gradient.repeating); + gradient.repeating, + ); DisplayItem::Gradient(Box::new(GradientDisplayItem { base: base, gradient: gradient, tile: placement.tile_size, tile_spacing: placement.tile_spacing, })) - } + }, GradientKind::Radial(shape, center, _angle) => { let gradient = convert_radial_gradient( placement.tile_size, &gradient.items[..], shape, center, - gradient.repeating); + gradient.repeating, + ); DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem { base: base, gradient: gradient, tile: placement.tile_size, tile_spacing: placement.tile_spacing, })) - } + }, }; state.add_display_item(display_item); } - fn build_display_list_for_box_shadow_if_applicable(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - display_list_section: DisplayListSection, - absolute_bounds: &Rect, - clip: &Rect) { + fn build_display_list_for_box_shadow_if_applicable( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + display_list_section: DisplayListSection, + absolute_bounds: &Rect, + clip: &Rect, + ) { // NB: According to CSS-BACKGROUNDS, box shadows render in *reverse* order (front to back). for box_shadow in style.get_effects().box_shadow.0.iter().rev() { let bounds = shadow_bounds( @@ -1617,18 +1785,26 @@ impl FragmentDisplayListBuilding for Fragment { Au::from(box_shadow.spread), ); - let base = state.create_base_display_item(&bounds, - LocalClip::from(clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - display_list_section); + let base = state.create_base_display_item( + &bounds, + LocalClip::from(clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + display_list_section, + ); let border_radius = build_border_radius(absolute_bounds, style.get_border()); state.add_display_item(DisplayItem::BoxShadow(Box::new(BoxShadowDisplayItem { base: base, box_bounds: *absolute_bounds, - color: box_shadow.base.color.unwrap_or(style.get_color().color).to_gfx_color(), - offset: Vector2D::new(Au::from(box_shadow.base.horizontal), - Au::from(box_shadow.base.vertical)), + color: box_shadow + .base + .color + .unwrap_or(style.get_color().color) + .to_gfx_color(), + offset: Vector2D::new( + Au::from(box_shadow.base.horizontal), + Au::from(box_shadow.base.vertical), + ), blur_radius: Au::from(box_shadow.base.blur), spread_radius: Au::from(box_shadow.spread), border_radius, @@ -1649,7 +1825,7 @@ impl FragmentDisplayListBuilding for Fragment { border_painting_mode: BorderPaintingMode, bounds: &Rect, display_list_section: DisplayListSection, - clip: &Rect + clip: &Rect, ) { let mut border = style.logical_border_width(); @@ -1658,37 +1834,45 @@ impl FragmentDisplayListBuilding for Fragment { } match border_painting_mode { - BorderPaintingMode::Separate => {} + BorderPaintingMode::Separate => {}, BorderPaintingMode::Collapse(collapsed_borders) => { collapsed_borders.adjust_border_widths_for_painting(&mut border) - } + }, BorderPaintingMode::Hidden => return, } if border.is_zero() { // TODO: check if image-border-outset is zero - return + return; } let border_style_struct = style.get_border(); - let mut colors = SideOffsets2D::new(border_style_struct.border_top_color, - border_style_struct.border_right_color, - border_style_struct.border_bottom_color, - border_style_struct.border_left_color); - let mut border_style = SideOffsets2D::new(border_style_struct.border_top_style, - border_style_struct.border_right_style, - border_style_struct.border_bottom_style, - border_style_struct.border_left_style); + let mut colors = SideOffsets2D::new( + border_style_struct.border_top_color, + border_style_struct.border_right_color, + border_style_struct.border_bottom_color, + border_style_struct.border_left_color, + ); + let mut border_style = SideOffsets2D::new( + border_style_struct.border_top_style, + border_style_struct.border_right_style, + border_style_struct.border_bottom_style, + border_style_struct.border_left_style, + ); if let BorderPaintingMode::Collapse(collapsed_borders) = border_painting_mode { - collapsed_borders.adjust_border_colors_and_styles_for_painting(&mut colors, - &mut border_style, - style.writing_mode); + collapsed_borders.adjust_border_colors_and_styles_for_painting( + &mut colors, + &mut border_style, + style.writing_mode, + ); } - let colors = SideOffsets2D::new(style.resolve_color(colors.top), - style.resolve_color(colors.right), - style.resolve_color(colors.bottom), - style.resolve_color(colors.left)); + let colors = SideOffsets2D::new( + style.resolve_color(colors.top), + style.resolve_color(colors.right), + style.resolve_color(colors.bottom), + style.resolve_color(colors.left), + ); // If this border collapses, then we draw outside the boundaries we were given. let mut bounds = *bounds; @@ -1697,11 +1881,13 @@ impl FragmentDisplayListBuilding for Fragment { } // Append the border to the display list. - let base = state.create_base_display_item(&bounds, - LocalClip::from(clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - display_list_section); + let base = state.create_base_display_item( + &bounds, + LocalClip::from(clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + display_list_section, + ); match border_style_struct.border_image_source { Either::First(_) => { @@ -1709,22 +1895,26 @@ impl FragmentDisplayListBuilding for Fragment { base: base, border_widths: border.to_physical(style.writing_mode), details: BorderDetails::Normal(NormalBorder { - color: SideOffsets2D::new(colors.top.to_gfx_color(), - colors.right.to_gfx_color(), - colors.bottom.to_gfx_color(), - colors.left.to_gfx_color()), + color: SideOffsets2D::new( + colors.top.to_gfx_color(), + colors.right.to_gfx_color(), + colors.bottom.to_gfx_color(), + colors.left.to_gfx_color(), + ), style: border_style, radius: build_border_radius(&bounds, border_style_struct), }), }))); - } + }, Either::Second(Image::Gradient(ref gradient)) => { match gradient.kind { GradientKind::Linear(angle_or_corner) => { - let grad = convert_linear_gradient(bounds.size, - &gradient.items[..], - angle_or_corner, - gradient.repeating); + let grad = convert_linear_gradient( + bounds.size, + &gradient.items[..], + angle_or_corner, + gradient.repeating, + ); state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { base: base, @@ -1736,13 +1926,15 @@ impl FragmentDisplayListBuilding for Fragment { outset: SideOffsets2D::zero(), }), }))); - } + }, GradientKind::Radial(shape, center, _angle) => { - let grad = convert_radial_gradient(bounds.size, - &gradient.items[..], - shape, - center, - gradient.repeating); + let grad = convert_radial_gradient( + bounds.size, + &gradient.items[..], + shape, + center, + gradient.repeating, + ); state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { base: base, border_widths: border.to_physical(style.writing_mode), @@ -1752,18 +1944,17 @@ impl FragmentDisplayListBuilding for Fragment { // TODO(gw): Support border-image-outset outset: SideOffsets2D::zero(), - }), + }, + ), }))); - } + }, } - } + }, Either::Second(Image::PaintWorklet(ref paint_worklet)) => { // TODO: this size should be increased by border-image-outset let size = self.border_box.size.to_physical(style.writing_mode); - let webrender_image = self.get_webrender_image_for_paint_worklet(state, - style, - paint_worklet, - size); + let webrender_image = + self.get_webrender_image_for_paint_worklet(state, style, paint_worklet, size); if let Some(webrender_image) = webrender_image { let corners = &border_style_struct.border_image_slice.offsets; @@ -1773,30 +1964,37 @@ impl FragmentDisplayListBuilding for Fragment { details: BorderDetails::Image(ImageBorder { image: webrender_image, fill: border_style_struct.border_image_slice.fill, - slice: SideOffsets2D::new(corners.0.resolve(webrender_image.height), - corners.1.resolve(webrender_image.width), - corners.2.resolve(webrender_image.height), - corners.3.resolve(webrender_image.width)), + slice: SideOffsets2D::new( + corners.0.resolve(webrender_image.height), + corners.1.resolve(webrender_image.width), + corners.2.resolve(webrender_image.height), + corners.3.resolve(webrender_image.width), + ), // TODO(gw): Support border-image-outset outset: SideOffsets2D::zero(), - repeat_horizontal: convert_repeat_mode(border_style_struct.border_image_repeat.0), - repeat_vertical: convert_repeat_mode(border_style_struct.border_image_repeat.1), + repeat_horizontal: convert_repeat_mode( + border_style_struct.border_image_repeat.0, + ), + repeat_vertical: convert_repeat_mode( + border_style_struct.border_image_repeat.1, + ), }), }))); } - } + }, Either::Second(Image::Rect(..)) => { // TODO: Handle border-image with `-moz-image-rect`. - } + }, Either::Second(Image::Element(..)) => { // TODO: Handle border-image with `-moz-element`. - } + }, Either::Second(Image::Url(ref image_url)) => { if let Some(url) = image_url.url() { - let webrender_image = state.layout_context - .get_webrender_image_for_url(self.node, - url.clone(), - UsePlaceholder::No); + let webrender_image = state.layout_context.get_webrender_image_for_url( + self.node, + url.clone(), + UsePlaceholder::No, + ); if let Some(webrender_image) = webrender_image { let corners = &border_style_struct.border_image_slice.offsets; @@ -1806,38 +2004,46 @@ impl FragmentDisplayListBuilding for Fragment { details: BorderDetails::Image(ImageBorder { image: webrender_image, fill: border_style_struct.border_image_slice.fill, - slice: SideOffsets2D::new(corners.0.resolve(webrender_image.height), - corners.1.resolve(webrender_image.width), - corners.2.resolve(webrender_image.height), - corners.3.resolve(webrender_image.width)), + slice: SideOffsets2D::new( + corners.0.resolve(webrender_image.height), + corners.1.resolve(webrender_image.width), + corners.2.resolve(webrender_image.height), + corners.3.resolve(webrender_image.width), + ), // TODO(gw): Support border-image-outset outset: SideOffsets2D::zero(), - repeat_horizontal: convert_repeat_mode(border_style_struct.border_image_repeat.0), - repeat_vertical: convert_repeat_mode(border_style_struct.border_image_repeat.1), + repeat_horizontal: convert_repeat_mode( + border_style_struct.border_image_repeat.0, + ), + repeat_vertical: convert_repeat_mode( + border_style_struct.border_image_repeat.1, + ), }), }))); } } - } + }, } } - fn build_display_list_for_outline_if_applicable(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - bounds: &Rect, - clip: &Rect) { + fn build_display_list_for_outline_if_applicable( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + bounds: &Rect, + clip: &Rect, + ) { use style::values::specified::outline::OutlineStyle; let width = Au::from(style.get_outline().outline_width); if width == Au(0) { - return + return; } let outline_style = match style.get_outline().outline_style { OutlineStyle::Auto => BorderStyle::Solid, OutlineStyle::Other(BorderStyle::None) => return, - OutlineStyle::Other(border_style) => border_style + OutlineStyle::Other(border_style) => border_style, }; // Outlines are not accounted for in the dimensions of the border box, so adjust the @@ -1850,12 +2056,16 @@ impl FragmentDisplayListBuilding for Fragment { bounds.size.height = bounds.size.height + offset + offset; // Append the outline to the display list. - let color = style.resolve_color(style.get_outline().outline_color).to_gfx_color(); - let base = state.create_base_display_item(&bounds, - LocalClip::from(clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - DisplayListSection::Outlines); + let color = style + .resolve_color(style.get_outline().outline_color) + .to_gfx_color(); + let base = state.create_base_display_item( + &bounds, + LocalClip::from(clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + DisplayListSection::Outlines, + ); state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { base: base, border_widths: SideOffsets2D::new_all_same(width), @@ -1867,22 +2077,26 @@ impl FragmentDisplayListBuilding for Fragment { }))); } - fn build_debug_borders_around_text_fragments(&self, - state: &mut DisplayListBuildState, - style: &ComputedValues, - stacking_relative_border_box: &Rect, - stacking_relative_content_box: &Rect, - text_fragment: &ScannedTextFragmentInfo, - clip: &Rect) { + fn build_debug_borders_around_text_fragments( + &self, + state: &mut DisplayListBuildState, + style: &ComputedValues, + stacking_relative_border_box: &Rect, + stacking_relative_content_box: &Rect, + text_fragment: &ScannedTextFragmentInfo, + clip: &Rect, + ) { // FIXME(pcwalton, #2795): Get the real container size. let container_size = Size2D::zero(); // Compute the text fragment bounds and draw a border surrounding them. - let base = state.create_base_display_item(stacking_relative_border_box, - LocalClip::from(clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - DisplayListSection::Content); + let base = state.create_base_display_item( + stacking_relative_border_box, + LocalClip::from(clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + DisplayListSection::Content, + ); state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { base: base, border_widths: SideOffsets2D::new_all_same(Au::from_px(1)), @@ -1894,18 +2108,22 @@ impl FragmentDisplayListBuilding for Fragment { }))); // Draw a rectangle representing the baselines. - let mut baseline = LogicalRect::from_physical(self.style.writing_mode, - *stacking_relative_content_box, - container_size); + let mut baseline = LogicalRect::from_physical( + self.style.writing_mode, + *stacking_relative_content_box, + container_size, + ); baseline.start.b = baseline.start.b + text_fragment.run.ascent(); baseline.size.block = Au(0); let baseline = baseline.to_physical(self.style.writing_mode, container_size); - let base = state.create_base_display_item(&baseline, - LocalClip::from(clip.to_rectf()), - self.node, - style.get_cursor(Cursor::Default), - DisplayListSection::Content); + let base = state.create_base_display_item( + &baseline, + LocalClip::from(clip.to_rectf()), + self.node, + style.get_cursor(Cursor::Default), + DisplayListSection::Content, + ); state.add_display_item(DisplayItem::Line(Box::new(LineDisplayItem { base: base, color: ColorF::rgb(0, 200, 0), @@ -1913,16 +2131,20 @@ impl FragmentDisplayListBuilding for Fragment { }))); } - fn build_debug_borders_around_fragment(&self, - state: &mut DisplayListBuildState, - stacking_relative_border_box: &Rect, - clip: &Rect) { + fn build_debug_borders_around_fragment( + &self, + state: &mut DisplayListBuildState, + stacking_relative_border_box: &Rect, + clip: &Rect, + ) { // This prints a debug border around the border of this fragment. - let base = state.create_base_display_item(stacking_relative_border_box, - LocalClip::from(clip.to_rectf()), - self.node, - self.style.get_cursor(Cursor::Default), - DisplayListSection::Content); + let base = state.create_base_display_item( + stacking_relative_border_box, + LocalClip::from(clip.to_rectf()), + self.node, + self.style.get_cursor(Cursor::Default), + DisplayListSection::Content, + ); state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { base: base, border_widths: SideOffsets2D::new_all_same(Au::from_px(1)), @@ -1934,15 +2156,17 @@ impl FragmentDisplayListBuilding for Fragment { }))); } - fn build_display_items_for_selection_if_necessary(&self, - state: &mut DisplayListBuildState, - stacking_relative_border_box: &Rect, - display_list_section: DisplayListSection, - clip: &Rect) { + fn build_display_items_for_selection_if_necessary( + &self, + state: &mut DisplayListBuildState, + stacking_relative_border_box: &Rect, + display_list_section: DisplayListSection, + clip: &Rect, + ) { let scanned_text_fragment_info = match self.specific { SpecificFragmentInfo::ScannedText(ref scanned_text_fragment_info) => { scanned_text_fragment_info - } + }, _ => return, }; @@ -1952,17 +2176,17 @@ impl FragmentDisplayListBuilding for Fragment { if scanned_text_fragment_info.selected() { let style = self.selected_style(); let background_color = style.resolve_color(style.get_background().background_color); - let base = state.create_base_display_item(stacking_relative_border_box, - LocalClip::from(clip.to_rectf()), - self.node, - self.style.get_cursor(Cursor::Default), - display_list_section); - state.add_display_item( - DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { - base: base, - color: background_color.to_gfx_color(), - })) + let base = state.create_base_display_item( + stacking_relative_border_box, + LocalClip::from(clip.to_rectf()), + self.node, + self.style.get_cursor(Cursor::Default), + display_list_section, ); + state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { + base: base, + color: background_color.to_gfx_color(), + }))); } // Draw a caret at the insertion point. @@ -1970,66 +2194,82 @@ impl FragmentDisplayListBuilding for Fragment { Some(insertion_point_index) => insertion_point_index, None => return, }; - let range = Range::new(scanned_text_fragment_info.range.begin(), - insertion_point_index - scanned_text_fragment_info.range.begin()); + let range = Range::new( + scanned_text_fragment_info.range.begin(), + insertion_point_index - scanned_text_fragment_info.range.begin(), + ); let advance = scanned_text_fragment_info.run.advance_for_range(&range); let insertion_point_bounds; let cursor; if !self.style.writing_mode.is_vertical() { - insertion_point_bounds = - Rect::new(Point2D::new(stacking_relative_border_box.origin.x + advance, - stacking_relative_border_box.origin.y), - Size2D::new(INSERTION_POINT_LOGICAL_WIDTH, - stacking_relative_border_box.size.height)); + insertion_point_bounds = Rect::new( + Point2D::new( + stacking_relative_border_box.origin.x + advance, + stacking_relative_border_box.origin.y, + ), + Size2D::new( + INSERTION_POINT_LOGICAL_WIDTH, + stacking_relative_border_box.size.height, + ), + ); cursor = Cursor::Text; } else { - insertion_point_bounds = - Rect::new(Point2D::new(stacking_relative_border_box.origin.x, - stacking_relative_border_box.origin.y + advance), - Size2D::new(stacking_relative_border_box.size.width, - INSERTION_POINT_LOGICAL_WIDTH)); + insertion_point_bounds = Rect::new( + Point2D::new( + stacking_relative_border_box.origin.x, + stacking_relative_border_box.origin.y + advance, + ), + Size2D::new( + stacking_relative_border_box.size.width, + INSERTION_POINT_LOGICAL_WIDTH, + ), + ); cursor = Cursor::VerticalText; }; - let base = state.create_base_display_item(&insertion_point_bounds, - LocalClip::from(clip.to_rectf()), - self.node, - self.style.get_cursor(cursor), - display_list_section); + let base = state.create_base_display_item( + &insertion_point_bounds, + LocalClip::from(clip.to_rectf()), + self.node, + self.style.get_cursor(cursor), + display_list_section, + ); state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { base: base, color: self.style().get_color().color.to_gfx_color(), }))); } - fn build_display_list(&mut self, - state: &mut DisplayListBuildState, - stacking_relative_flow_origin: &Vector2D, - relative_containing_block_size: &LogicalSize, - relative_containing_block_mode: WritingMode, - border_painting_mode: BorderPaintingMode, - display_list_section: DisplayListSection, - clip: &Rect) { + fn build_display_list( + &mut self, + state: &mut DisplayListBuildState, + stacking_relative_flow_origin: &Vector2D, + relative_containing_block_size: &LogicalSize, + relative_containing_block_mode: WritingMode, + border_painting_mode: BorderPaintingMode, + display_list_section: DisplayListSection, + clip: &Rect, + ) { self.restyle_damage.remove(ServoRestyleDamage::REPAINT); if self.style().get_inheritedbox().visibility != Visibility::Visible { - return + return; } // Compute the fragment position relative to the parent stacking context. If the fragment // itself establishes a stacking context, then the origin of its position will be (0, 0) // for the purposes of this computation. - let stacking_relative_border_box = - self.stacking_relative_border_box(stacking_relative_flow_origin, - relative_containing_block_size, - relative_containing_block_mode, - CoordinateSystem::Own); - - debug!("Fragment::build_display_list at rel={:?}, abs={:?}, flow origin={:?}: {:?}", - self.border_box, - stacking_relative_border_box, - stacking_relative_flow_origin, - self); + let stacking_relative_border_box = self.stacking_relative_border_box( + stacking_relative_flow_origin, + relative_containing_block_size, + relative_containing_block_mode, + CoordinateSystem::Own, + ); + + debug!( + "Fragment::build_display_list at rel={:?}, abs={:?}, flow origin={:?}: {:?}", + self.border_box, stacking_relative_border_box, stacking_relative_flow_origin, self + ); // Check the clip rect. If there's nothing to render at all, don't even construct display // list items. @@ -2057,10 +2297,10 @@ impl FragmentDisplayListBuilding for Fragment { state, &*node.style, Some(InlineNodeBorderInfo { - is_first_fragment_of_element: - node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT), - is_last_fragment_of_element: - node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT), + is_first_fragment_of_element: node.flags + .contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT), + is_last_fragment_of_element: node.flags + .contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT), }), border_painting_mode, &stacking_relative_border_box, @@ -2117,32 +2357,34 @@ impl FragmentDisplayListBuilding for Fragment { if self.is_primary_fragment() { // Paint the selection point if necessary. Even an empty text fragment may have an // insertion point, so we do this even if `empty_rect` is true. - self.build_display_items_for_selection_if_necessary(state, - &stacking_relative_border_box, - display_list_section, - clip); + self.build_display_items_for_selection_if_necessary( + state, + &stacking_relative_border_box, + display_list_section, + clip, + ); } if empty_rect { - return + return; } debug!("Fragment::build_display_list: intersected. Adding display item..."); // Create special per-fragment-type display items. - self.build_fragment_type_specific_display_items(state, - &stacking_relative_border_box, - clip); + self.build_fragment_type_specific_display_items(state, &stacking_relative_border_box, clip); if opts::get().show_debug_fragment_borders { - self.build_debug_borders_around_fragment(state, &stacking_relative_border_box, clip) + self.build_debug_borders_around_fragment(state, &stacking_relative_border_box, clip) } } - fn build_fragment_type_specific_display_items(&mut self, - state: &mut DisplayListBuildState, - stacking_relative_border_box: &Rect, - clip: &Rect) { + fn build_fragment_type_specific_display_items( + &mut self, + state: &mut DisplayListBuildState, + stacking_relative_border_box: &Rect, + clip: &Rect, + ) { // Compute the context box position relative to the parent stacking context. let stacking_relative_content_box = self.stacking_relative_content_box(stacking_relative_border_box); @@ -2153,10 +2395,12 @@ impl FragmentDisplayListBuilding for Fragment { if !radii.is_square() { LocalClip::RoundedRect( stacking_relative_border_box.to_rectf(), - ComplexClipRegion::new(stacking_relative_content_box.to_rectf(), - radii.to_border_radius(), - ClipMode::Clip, - )) + ComplexClipRegion::new( + stacking_relative_content_box.to_rectf(), + radii.to_border_radius(), + ClipMode::Clip, + ), + ) } else { LocalClip::Rect(stacking_relative_border_box.to_rectf()) } @@ -2164,41 +2408,50 @@ impl FragmentDisplayListBuilding for Fragment { match self.specific { SpecificFragmentInfo::TruncatedFragment(ref truncated_fragment) - if truncated_fragment.text_info.is_some() => { + if truncated_fragment.text_info.is_some() => + { let text_fragment = truncated_fragment.text_info.as_ref().unwrap(); // Create the main text display item. - self.build_display_list_for_text_fragment(state, - &text_fragment, - &stacking_relative_content_box, - &self.style.get_inheritedtext().text_shadow.0, - clip); + self.build_display_list_for_text_fragment( + state, + &text_fragment, + &stacking_relative_content_box, + &self.style.get_inheritedtext().text_shadow.0, + clip, + ); if opts::get().show_debug_fragment_borders { - self.build_debug_borders_around_text_fragments(state, - self.style(), - stacking_relative_border_box, - &stacking_relative_content_box, - &text_fragment, - clip); + self.build_debug_borders_around_text_fragments( + state, + self.style(), + stacking_relative_border_box, + &stacking_relative_content_box, + &text_fragment, + clip, + ); } } SpecificFragmentInfo::ScannedText(ref text_fragment) => { // Create the main text display item. - self.build_display_list_for_text_fragment(state, - &text_fragment, - &stacking_relative_content_box, - &self.style.get_inheritedtext().text_shadow.0, - clip); + self.build_display_list_for_text_fragment( + state, + &text_fragment, + &stacking_relative_content_box, + &self.style.get_inheritedtext().text_shadow.0, + clip, + ); if opts::get().show_debug_fragment_borders { - self.build_debug_borders_around_text_fragments(state, - self.style(), - stacking_relative_border_box, - &stacking_relative_content_box, - &text_fragment, - clip); + self.build_debug_borders_around_text_fragments( + state, + self.style(), + stacking_relative_border_box, + &stacking_relative_content_box, + &text_fragment, + clip, + ); } - } + }, SpecificFragmentInfo::Generic | SpecificFragmentInfo::GeneratedContent(..) | SpecificFragmentInfo::Table | @@ -2213,11 +2466,13 @@ impl FragmentDisplayListBuilding for Fragment { SpecificFragmentInfo::TruncatedFragment(_) | SpecificFragmentInfo::Svg(_) => { if opts::get().show_debug_fragment_borders { - self.build_debug_borders_around_fragment(state, - stacking_relative_border_box, - clip); + self.build_debug_borders_around_fragment( + state, + stacking_relative_border_box, + clip, + ); } - } + }, SpecificFragmentInfo::Iframe(ref fragment_info) => { if !stacking_relative_content_box.is_empty() { let browsing_context_id = match fragment_info.browsing_context_id { @@ -2234,20 +2489,24 @@ impl FragmentDisplayListBuilding for Fragment { build_local_clip(&self.style), self.node, self.style.get_cursor(Cursor::Default), - DisplayListSection::Content); + DisplayListSection::Content, + ); let item = DisplayItem::Iframe(Box::new(IframeDisplayItem { base: base, iframe: pipeline_id, })); - let size = Size2D::new(item.bounds().size.width.to_f32_px(), - item.bounds().size.height.to_f32_px()); - state.iframe_sizes.push((browsing_context_id, - TypedSize2D::from_untyped(&size))); + let size = Size2D::new( + item.bounds().size.width.to_f32_px(), + item.bounds().size.height.to_f32_px(), + ); + state + .iframe_sizes + .push((browsing_context_id, TypedSize2D::from_untyped(&size))); state.add_display_item(item); } - } + }, SpecificFragmentInfo::Image(ref mut image_fragment) => { // Place the image into the display list. if let Some(ref image) = image_fragment.image { @@ -2256,7 +2515,8 @@ impl FragmentDisplayListBuilding for Fragment { build_local_clip(&self.style), self.node, self.style.get_cursor(Cursor::Default), - DisplayListSection::Content); + DisplayListSection::Content, + ); state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { base: base, webrender_image: WebRenderImageInfo::from_image(image), @@ -2266,27 +2526,24 @@ impl FragmentDisplayListBuilding for Fragment { image_rendering: self.style.get_inheritedbox().image_rendering.clone(), }))); } - } + }, SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => { let computed_width = canvas_fragment_info.dom_width.to_px(); let computed_height = canvas_fragment_info.dom_height.to_px(); let (image_key, format) = match canvas_fragment_info.source { - CanvasFragmentSource::WebGL(image_key) => { - (image_key, PixelFormat::BGRA8) + CanvasFragmentSource::WebGL(image_key) => (image_key, PixelFormat::BGRA8), + CanvasFragmentSource::Image(ref ipc_renderer) => match *ipc_renderer { + Some(ref ipc_renderer) => { + let ipc_renderer = ipc_renderer.lock().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); + ipc_renderer + .send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender))) + .unwrap(); + (receiver.recv().unwrap().image_key, PixelFormat::BGRA8) + }, + None => return, }, - CanvasFragmentSource::Image(ref ipc_renderer) => { - match *ipc_renderer { - Some(ref ipc_renderer) => { - let ipc_renderer = ipc_renderer.lock().unwrap(); - let (sender, receiver) = ipc::channel().unwrap(); - ipc_renderer.send(CanvasMsg::FromLayout( - FromLayoutMsg::SendData(sender))).unwrap(); - (receiver.recv().unwrap().image_key, PixelFormat::BGRA8) - }, - None => return, - } - } }; let base = state.create_base_display_item( @@ -2294,7 +2551,8 @@ impl FragmentDisplayListBuilding for Fragment { build_local_clip(&self.style), self.node, self.style.get_cursor(Cursor::Default), - DisplayListSection::Content); + DisplayListSection::Content, + ); let display_item = DisplayItem::Image(Box::new(ImageDisplayItem { base: base, webrender_image: WebRenderImageInfo { @@ -2310,13 +2568,13 @@ impl FragmentDisplayListBuilding for Fragment { })); state.add_display_item(display_item); - } + }, SpecificFragmentInfo::UnscannedText(_) => { panic!("Shouldn't see unscanned fragments here.") - } + }, SpecificFragmentInfo::TableColumn(_) => { panic!("Shouldn't see table column fragments here.") - } + }, } } @@ -2326,21 +2584,28 @@ impl FragmentDisplayListBuilding for Fragment { base_flow: &BaseFlow, scroll_policy: ScrollPolicy, context_type: StackingContextType, - parent_clipping_and_scrolling: ClippingAndScrolling + parent_clipping_and_scrolling: ClippingAndScrolling, ) -> StackingContext { - let border_box = - self.stacking_relative_border_box(&base_flow.stacking_relative_position, - &base_flow.early_absolute_position_info - .relative_containing_block_size, - base_flow.early_absolute_position_info - .relative_containing_block_mode, - CoordinateSystem::Parent); + let border_box = self.stacking_relative_border_box( + &base_flow.stacking_relative_position, + &base_flow + .early_absolute_position_info + .relative_containing_block_size, + base_flow + .early_absolute_position_info + .relative_containing_block_mode, + CoordinateSystem::Parent, + ); // First, compute the offset of our border box (including relative positioning) // from our flow origin, since that is what `BaseFlow::overflow` is relative to. - let border_box_offset = - border_box.translate(&-base_flow.stacking_relative_position).origin; + let border_box_offset = border_box + .translate(&-base_flow.stacking_relative_position) + .origin; // Then, using that, compute our overflow region relative to our border box. - let overflow = base_flow.overflow.paint.translate(&-border_box_offset.to_vector()); + let overflow = base_flow + .overflow + .paint + .translate(&-border_box_offset.to_vector()); // Create the filter pipeline. let effects = self.style().get_effects(); @@ -2356,21 +2621,26 @@ impl FragmentDisplayListBuilding for Fragment { &overflow, self.effective_z_index(), filters.into(), - self.style().get_effects().mix_blend_mode.to_mix_blend_mode(), + self.style() + .get_effects() + .mix_blend_mode + .to_mix_blend_mode(), self.transform_matrix(&border_box), self.style().get_used_transform_style().to_transform_style(), self.perspective_matrix(&border_box), scroll_policy, - parent_clipping_and_scrolling + parent_clipping_and_scrolling, ) } - fn build_display_list_for_text_fragment(&self, - state: &mut DisplayListBuildState, - text_fragment: &ScannedTextFragmentInfo, - stacking_relative_content_box: &Rect, - text_shadows: &[SimpleShadow], - clip: &Rect) { + fn build_display_list_for_text_fragment( + &self, + state: &mut DisplayListBuildState, + text_fragment: &ScannedTextFragmentInfo, + stacking_relative_content_box: &Rect, + text_shadows: &[SimpleShadow], + clip: &Rect, + ) { // NB: The order for painting text components (CSS Text Decoration Module Level 3) is: // shadows, underline, overline, text, text-emphasis, and then line-through. @@ -2382,7 +2652,6 @@ impl FragmentDisplayListBuilding for Fragment { self.style().get_color().color }; - // Determine the orientation and cursor to use. let (orientation, cursor) = if self.style.writing_mode.is_vertical() { // TODO: Distinguish between 'sideways-lr' and 'sideways-rl' writing modes in CSS @@ -2398,48 +2667,53 @@ impl FragmentDisplayListBuilding for Fragment { let container_size = Size2D::zero(); let metrics = &text_fragment.run.font_metrics; let baseline_origin = stacking_relative_content_box.origin + - LogicalPoint::new(self.style.writing_mode, - Au(0), - metrics.ascent).to_physical(self.style.writing_mode, - container_size).to_vector(); + LogicalPoint::new(self.style.writing_mode, Au(0), metrics.ascent) + .to_physical(self.style.writing_mode, container_size) + .to_vector(); // Base item for all text/shadows - let base = state.create_base_display_item(&stacking_relative_content_box, - LocalClip::from(clip.to_rectf()), - self.node, - self.style().get_cursor(cursor), - DisplayListSection::Content); + let base = state.create_base_display_item( + &stacking_relative_content_box, + LocalClip::from(clip.to_rectf()), + self.node, + self.style().get_cursor(cursor), + DisplayListSection::Content, + ); // NB: According to CSS-BACKGROUNDS, text shadows render in *reverse* order (front // to back). // Shadows for shadow in text_shadows.iter().rev() { - state.add_display_item(DisplayItem::PushTextShadow(Box::new(PushTextShadowDisplayItem { - base: base.clone(), - blur_radius: Au::from(shadow.blur), - offset: Vector2D::new(Au::from(shadow.horizontal), Au::from(shadow.vertical)), - color: shadow.color.unwrap_or(self.style().get_color().color).to_gfx_color(), - }))); + state.add_display_item(DisplayItem::PushTextShadow(Box::new( + PushTextShadowDisplayItem { + base: base.clone(), + blur_radius: Au::from(shadow.blur), + offset: Vector2D::new(Au::from(shadow.horizontal), Au::from(shadow.vertical)), + color: shadow + .color + .unwrap_or(self.style().get_color().color) + .to_gfx_color(), + }, + ))); } - // Create display items for text decorations. - let text_decorations = - self.style() - .get_inheritedtext() - ._servo_text_decorations_in_effect; - - let stacking_relative_content_box = - LogicalRect::from_physical(self.style.writing_mode, - *stacking_relative_content_box, - container_size); + let text_decorations = self.style() + .get_inheritedtext() + ._servo_text_decorations_in_effect; + + let stacking_relative_content_box = LogicalRect::from_physical( + self.style.writing_mode, + *stacking_relative_content_box, + container_size, + ); // Underline if text_decorations.underline { let mut stacking_relative_box = stacking_relative_content_box; - stacking_relative_box.start.b = stacking_relative_content_box.start.b + - metrics.ascent - metrics.underline_offset; + stacking_relative_box.start.b = + stacking_relative_content_box.start.b + metrics.ascent - metrics.underline_offset; stacking_relative_box.size.block = metrics.underline_size; self.build_display_list_for_text_decoration( state, @@ -2471,16 +2745,14 @@ impl FragmentDisplayListBuilding for Fragment { baseline_origin: baseline_origin, }))); - // TODO(#17715): emit text-emphasis marks here. // (just push another TextDisplayItem?) - // Line-Through if text_decorations.line_through { let mut stacking_relative_box = stacking_relative_content_box; - stacking_relative_box.start.b = stacking_relative_box.start.b + metrics.ascent - - metrics.strikeout_offset; + stacking_relative_box.start.b = + stacking_relative_box.start.b + metrics.ascent - metrics.strikeout_offset; stacking_relative_box.size.block = metrics.strikeout_size; self.build_display_list_for_text_decoration( state, @@ -2492,27 +2764,30 @@ impl FragmentDisplayListBuilding for Fragment { // Pop all the PushTextShadows if !text_shadows.is_empty() { - state.add_display_item(DisplayItem::PopAllTextShadows(Box::new(PopAllTextShadowsDisplayItem { - base: base.clone(), - }))); + state.add_display_item(DisplayItem::PopAllTextShadows(Box::new( + PopAllTextShadowsDisplayItem { base: base.clone() }, + ))); } } - fn build_display_list_for_text_decoration(&self, - state: &mut DisplayListBuildState, - color: &RGBA, - stacking_relative_box: &LogicalRect, - clip: &Rect) { + fn build_display_list_for_text_decoration( + &self, + state: &mut DisplayListBuildState, + color: &RGBA, + stacking_relative_box: &LogicalRect, + clip: &Rect, + ) { // FIXME(pcwalton, #2795): Get the real container size. let container_size = Size2D::zero(); - let stacking_relative_box = stacking_relative_box.to_physical(self.style.writing_mode, - container_size); + let stacking_relative_box = + stacking_relative_box.to_physical(self.style.writing_mode, container_size); let base = state.create_base_display_item( &stacking_relative_box, LocalClip::from(clip.to_rectf()), self.node, self.style.get_cursor(Cursor::Default), - DisplayListSection::Content); + DisplayListSection::Content, + ); state.add_display_item(DisplayItem::Line(Box::new(LineDisplayItem { base: base, @@ -2524,7 +2799,7 @@ impl FragmentDisplayListBuilding for Fragment { fn unique_id(&self, id_type: IdType) -> u64 { let fragment_type = self.fragment_type(); let id = match id_type { - IdType::StackingContext | IdType::OverflowClip => self.node.id() as usize, + IdType::StackingContext | IdType::OverflowClip => self.node.id() as usize, IdType::CSSClip => self as *const _ as usize, }; combine_id_with_fragment_type(id, fragment_type) as u64 @@ -2553,44 +2828,57 @@ bitflags! { } pub trait BlockFlowDisplayListBuilding { - fn collect_stacking_contexts_for_block(&mut self, - state: &mut StackingContextCollectionState, - flags: StackingContextCollectionFlags); - - fn transform_clip_to_coordinate_space(&mut self, - state: &mut StackingContextCollectionState, - preserved_state: &mut SavedStackingContextCollectionState); - fn setup_clipping_for_block(&mut self, - state: &mut StackingContextCollectionState, - preserved_state: &mut SavedStackingContextCollectionState, - stacking_context_type: BlockStackingContextType, - flags: StackingContextCollectionFlags) - -> ClippingAndScrolling; - fn setup_clip_scroll_node_for_position(&mut self, - state: &mut StackingContextCollectionState, - border_box: &Rect); - fn setup_clip_scroll_node_for_overflow(&mut self, - state: &mut StackingContextCollectionState, - border_box: &Rect); - fn setup_clip_scroll_node_for_css_clip(&mut self, - state: &mut StackingContextCollectionState, - preserved_state: &mut SavedStackingContextCollectionState, - stacking_relative_border_box: &Rect); + fn collect_stacking_contexts_for_block( + &mut self, + state: &mut StackingContextCollectionState, + flags: StackingContextCollectionFlags, + ); + + fn transform_clip_to_coordinate_space( + &mut self, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, + ); + fn setup_clipping_for_block( + &mut self, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, + stacking_context_type: BlockStackingContextType, + flags: StackingContextCollectionFlags, + ) -> ClippingAndScrolling; + fn setup_clip_scroll_node_for_position( + &mut self, + state: &mut StackingContextCollectionState, + border_box: &Rect, + ); + fn setup_clip_scroll_node_for_overflow( + &mut self, + state: &mut StackingContextCollectionState, + border_box: &Rect, + ); + fn setup_clip_scroll_node_for_css_clip( + &mut self, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, + stacking_relative_border_box: &Rect, + ); fn create_pseudo_stacking_context_for_block( &mut self, parent_stacking_context_id: StackingContextId, parent_clip_and_scroll_info: ClippingAndScrolling, - state: &mut StackingContextCollectionState + state: &mut StackingContextCollectionState, ); fn create_real_stacking_context_for_block( &mut self, parent_stacking_context_id: StackingContextId, parent_clipping_and_scrolling: ClippingAndScrolling, - state: &mut StackingContextCollectionState + state: &mut StackingContextCollectionState, + ); + fn build_display_list_for_block( + &mut self, + state: &mut DisplayListBuildState, + border_painting_mode: BorderPaintingMode, ); - fn build_display_list_for_block(&mut self, - state: &mut DisplayListBuildState, - border_painting_mode: BorderPaintingMode); fn block_stacking_context_type( &self, @@ -2627,7 +2915,11 @@ impl SavedStackingContextCollectionState { } fn switch_to_containing_block_clip(&mut self, state: &mut StackingContextCollectionState) { - let clip = state.containing_block_clip_stack.last().cloned().unwrap_or_else(max_rect); + let clip = state + .containing_block_clip_stack + .last() + .cloned() + .unwrap_or_else(max_rect); state.clip_stack.push(clip); self.clips_pushed += 1; } @@ -2636,21 +2928,24 @@ impl SavedStackingContextCollectionState { state.current_stacking_context_id = self.stacking_context_id; state.current_real_stacking_context_id = self.real_stacking_context_id; state.current_clipping_and_scrolling = self.clipping_and_scrolling; - state.containing_block_clipping_and_scrolling = self.containing_block_clipping_and_scrolling; + state.containing_block_clipping_and_scrolling = + self.containing_block_clipping_and_scrolling; state.parent_stacking_relative_content_box = self.stacking_relative_content_box; let truncate_length = state.clip_stack.len() - self.clips_pushed; state.clip_stack.truncate(truncate_length); - let truncate_length = state.containing_block_clip_stack.len() - - self.containing_block_clips_pushed; + let truncate_length = + state.containing_block_clip_stack.len() - self.containing_block_clips_pushed; state.containing_block_clip_stack.truncate(truncate_length); } - fn push_clip(&mut self, - state: &mut StackingContextCollectionState, - clip: &Rect, - positioning: StylePosition) { + fn push_clip( + &mut self, + state: &mut StackingContextCollectionState, + clip: &Rect, + positioning: StylePosition, + ) { let mut clip = *clip; if positioning != StylePosition::Fixed { if let Some(old_clip) = state.clip_stack.last() { @@ -2669,9 +2964,11 @@ impl SavedStackingContextCollectionState { } impl BlockFlowDisplayListBuilding for BlockFlow { - fn transform_clip_to_coordinate_space(&mut self, - state: &mut StackingContextCollectionState, - preserved_state: &mut SavedStackingContextCollectionState) { + fn transform_clip_to_coordinate_space( + &mut self, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, + ) { if state.clip_stack.is_empty() { return; } @@ -2681,8 +2978,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow { None => return, }; - let perspective = self.fragment.perspective_matrix(&border_box) - .unwrap_or_else(Transform3D::identity); + let perspective = self.fragment + .perspective_matrix(&border_box) + .unwrap_or_else(Transform3D::identity); let transform = transform.pre_mul(&perspective).inverse(); let origin = &border_box.origin; @@ -2692,27 +2990,36 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } match transform { - Some(transform) if transform.m13 != 0.0 || transform.m23 != 0.0 => { + Some(transform) if transform.m13 != 0.0 || transform.m23 != 0.0 => { // We cannot properly handle perspective transforms, because there may be a // situation where an element is transformed from outside the clip into the // clip region. Here we don't have enough information to detect when that is // happening. For the moment we just punt on trying to optimize the display // list for those cases. max_rect() - } + }, Some(transform) => { - let clip = Rect::new(Point2D::new((clip.origin.x - origin.x).to_f32_px(), - (clip.origin.y - origin.y).to_f32_px()), - Size2D::new(clip.size.width.to_f32_px(), - clip.size.height.to_f32_px())); + let clip = Rect::new( + Point2D::new( + (clip.origin.x - origin.x).to_f32_px(), + (clip.origin.y - origin.y).to_f32_px(), + ), + Size2D::new(clip.size.width.to_f32_px(), clip.size.height.to_f32_px()), + ); let clip = transform.transform_rect(&clip); - Rect::new(Point2D::new(Au::from_f32_px(clip.origin.x), - Au::from_f32_px(clip.origin.y)), - Size2D::new(Au::from_f32_px(clip.size.width), - Au::from_f32_px(clip.size.height))) - } + Rect::new( + Point2D::new( + Au::from_f32_px(clip.origin.x), + Au::from_f32_px(clip.origin.y), + ), + Size2D::new( + Au::from_f32_px(clip.size.width), + Au::from_f32_px(clip.size.height), + ), + ) + }, None => Rect::zero(), } }; @@ -2723,14 +3030,18 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } if let Some(clip) = state.containing_block_clip_stack.last().cloned() { - state.containing_block_clip_stack.push(transform_clip(&clip)); + state + .containing_block_clip_stack + .push(transform_clip(&clip)); preserved_state.containing_block_clips_pushed += 1; } } - fn collect_stacking_contexts_for_block(&mut self, - state: &mut StackingContextCollectionState, - flags: StackingContextCollectionFlags) { + fn collect_stacking_contexts_for_block( + &mut self, + state: &mut StackingContextCollectionState, + flags: StackingContextCollectionFlags, + ) { let mut preserved_state = SavedStackingContextCollectionState::new(state); let block_stacking_context_type = self.block_stacking_context_type(flags); @@ -2749,11 +3060,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // any scroll root that we create. If we create a scroll root, its index will be // stored in state.current_clipping_and_scrolling. If we create a stacking context, // we don't want it to be contained by its own scroll root. - let containing_clipping_and_scrolling = - self.setup_clipping_for_block(state, - &mut preserved_state, - block_stacking_context_type, - flags); + let containing_clipping_and_scrolling = self.setup_clipping_for_block( + state, + &mut preserved_state, + block_stacking_context_type, + flags, + ); if establishes_containing_block_for_absolute(flags, self.positioning()) { state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling; @@ -2762,44 +3074,46 @@ impl BlockFlowDisplayListBuilding for BlockFlow { match block_stacking_context_type { BlockStackingContextType::NonstackingContext => { self.base.collect_stacking_contexts_for_children(state); - } + }, BlockStackingContextType::PseudoStackingContext => { self.create_pseudo_stacking_context_for_block( preserved_state.stacking_context_id, containing_clipping_and_scrolling, - state + state, ); - } + }, BlockStackingContextType::StackingContext => { self.create_real_stacking_context_for_block( preserved_state.stacking_context_id, containing_clipping_and_scrolling, - state + state, ); - } + }, } preserved_state.restore(state); } - fn setup_clipping_for_block(&mut self, - state: &mut StackingContextCollectionState, - preserved_state: &mut SavedStackingContextCollectionState, - stacking_context_type: BlockStackingContextType, - flags: StackingContextCollectionFlags) - -> ClippingAndScrolling { + fn setup_clipping_for_block( + &mut self, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, + stacking_context_type: BlockStackingContextType, + flags: StackingContextCollectionFlags, + ) -> ClippingAndScrolling { // If this block is absolutely positioned, we should be clipped and positioned by // the scroll root of our nearest ancestor that establishes a containing block. let containing_clipping_and_scrolling = match self.positioning() { StylePosition::Absolute => { preserved_state.switch_to_containing_block_clip(state); - state.current_clipping_and_scrolling = state.containing_block_clipping_and_scrolling; + state.current_clipping_and_scrolling = + state.containing_block_clipping_and_scrolling; state.containing_block_clipping_and_scrolling - } + }, StylePosition::Fixed => { preserved_state.push_clip(state, &max_rect(), StylePosition::Fixed); state.current_clipping_and_scrolling - } + }, _ => state.current_clipping_and_scrolling, }; self.base.clipping_and_scrolling = Some(containing_clipping_and_scrolling); @@ -2817,8 +3131,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE) { self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box); self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box); - self.setup_clip_scroll_node_for_css_clip(state, preserved_state, - &stacking_relative_border_box); + self.setup_clip_scroll_node_for_css_clip( + state, + preserved_state, + &stacking_relative_border_box, + ); } self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect); @@ -2831,28 +3148,33 @@ impl BlockFlowDisplayListBuilding for BlockFlow { self.stacking_relative_border_box(CoordinateSystem::Own) }; state.parent_stacking_relative_content_box = - self.fragment.stacking_relative_content_box(&border_box) + self.fragment.stacking_relative_content_box(&border_box) } match self.positioning() { - StylePosition::Absolute | StylePosition::Relative | StylePosition::Fixed => - state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling, - _ => {} + StylePosition::Absolute | StylePosition::Relative | StylePosition::Fixed => { + state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling + }, + _ => {}, } containing_clipping_and_scrolling } - fn setup_clip_scroll_node_for_position(&mut self, - state: &mut StackingContextCollectionState, - border_box: &Rect) { + fn setup_clip_scroll_node_for_position( + &mut self, + state: &mut StackingContextCollectionState, + border_box: &Rect, + ) { if self.positioning() != StylePosition::Sticky { return; } let sticky_position = self.sticky_position(); if sticky_position.left == MaybeAuto::Auto && sticky_position.right == MaybeAuto::Auto && - sticky_position.top == MaybeAuto::Auto && sticky_position.bottom == MaybeAuto::Auto { + sticky_position.top == MaybeAuto::Auto && + sticky_position.bottom == MaybeAuto::Auto + { return; } @@ -2862,7 +3184,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // position in our parent's coordinate system. let border_box_in_parent = self.stacking_relative_border_box(CoordinateSystem::Parent); let margins = self.fragment.margin.to_physical( - self.base.early_absolute_position_info.relative_containing_block_mode); + self.base + .early_absolute_position_info + .relative_containing_block_mode, + ); // Position:sticky elements are always restricted based on the size and position of // their containing block, which for sticky items is like relative and statically @@ -2876,11 +3201,17 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // This is the minimum negative offset and then the maximum positive offset. We just // specify every edge, but if the corresponding margin is None, that offset has no effect. let vertical_offset_bounds = StickyOffsetBounds::new( - to_offset_bound(constraint_rect.min_y(), border_box_in_parent.min_y() - margins.top), + to_offset_bound( + constraint_rect.min_y(), + border_box_in_parent.min_y() - margins.top, + ), to_offset_bound(constraint_rect.max_y(), border_box_in_parent.max_y()), ); let horizontal_offset_bounds = StickyOffsetBounds::new( - to_offset_bound(constraint_rect.min_x(), border_box_in_parent.min_x() - margins.left), + to_offset_bound( + constraint_rect.min_x(), + border_box_in_parent.min_x() - margins.left, + ), to_offset_bound(constraint_rect.max_x(), border_box_in_parent.max_x()), ); @@ -2893,34 +3224,33 @@ impl BlockFlowDisplayListBuilding for BlockFlow { sticky_position.left.to_option().map(|v| v.to_f32_px()), ), vertical_offset_bounds, - horizontal_offset_bounds + horizontal_offset_bounds, }; - let new_clip_scroll_index = state.add_clip_scroll_node( - ClipScrollNode { - id: None, - parent_index: self.clipping_and_scrolling().scrolling, - clip: ClippingRegion::from_rect(border_box), - content_rect: Rect::zero(), - node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data), - }, - ); + let new_clip_scroll_index = state.add_clip_scroll_node(ClipScrollNode { + id: None, + parent_index: self.clipping_and_scrolling().scrolling, + clip: ClippingRegion::from_rect(border_box), + content_rect: Rect::zero(), + node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data), + }); let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index); self.base.clipping_and_scrolling = Some(new_clipping_and_scrolling); state.current_clipping_and_scrolling = new_clipping_and_scrolling; } - fn setup_clip_scroll_node_for_overflow(&mut self, - state: &mut StackingContextCollectionState, - border_box: &Rect) { + fn setup_clip_scroll_node_for_overflow( + &mut self, + state: &mut StackingContextCollectionState, + border_box: &Rect, + ) { if !self.overflow_style_may_require_clip_scroll_node() { return; } let content_box = self.fragment.stacking_relative_content_box(&border_box); - let has_scrolling_overflow = - self.base.overflow.scroll.origin != Point2D::zero() || + let has_scrolling_overflow = self.base.overflow.scroll.origin != Point2D::zero() || self.base.overflow.scroll.size.width > content_box.size.width || self.base.overflow.scroll.size.height > content_box.size.height || StyleOverflow::Hidden == self.fragment.style.get_box().overflow_x || @@ -2934,11 +3264,14 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // If we already have a scroll root for this flow, just return. This can happen // when fragments map to more than one flow, such as in the case of table // wrappers. We just accept the first scroll root in that case. - let new_clip_scroll_node_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip), - state.pipeline_id.to_webrender()); + let new_clip_scroll_node_id = ClipId::new( + self.fragment.unique_id(IdType::OverflowClip), + state.pipeline_id.to_webrender(), + ); let sensitivity = if StyleOverflow::Hidden == self.fragment.style.get_box().overflow_x && - StyleOverflow::Hidden == self.fragment.style.get_box().overflow_y { + StyleOverflow::Hidden == self.fragment.style.get_box().overflow_y + { ScrollSensitivity::Script } else { ScrollSensitivity::ScriptAndInputEvents @@ -2954,15 +3287,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size; let content_size = Size2D::new(content_size.x, content_size.y); - let new_clip_scroll_index = state.add_clip_scroll_node( - ClipScrollNode { - id: Some(new_clip_scroll_node_id), - parent_index: self.clipping_and_scrolling().scrolling, - clip: clip, - content_rect: Rect::new(content_box.origin, content_size), - node_type: ClipScrollNodeType::ScrollFrame(sensitivity), - }, - ); + let new_clip_scroll_index = state.add_clip_scroll_node(ClipScrollNode { + id: Some(new_clip_scroll_node_id), + parent_index: self.clipping_and_scrolling().scrolling, + clip: clip, + content_rect: Rect::new(content_box.origin, content_size), + node_type: ClipScrollNodeType::ScrollFrame(sensitivity), + }); let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index); self.base.clipping_and_scrolling = Some(new_clipping_and_scrolling); @@ -2971,10 +3302,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow { /// Adds a scroll root for a block to take the `clip` property into account /// per CSS 2.1 § 11.1.2. - fn setup_clip_scroll_node_for_css_clip(&mut self, - state: &mut StackingContextCollectionState, - preserved_state: &mut SavedStackingContextCollectionState, - stacking_relative_border_box: &Rect) { + fn setup_clip_scroll_node_for_css_clip( + &mut self, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, + stacking_relative_border_box: &Rect, + ) { // Account for `clip` per CSS 2.1 § 11.1.2. let style_clip_rect = match self.fragment.style().get_effects().clip { Either::First(style_clip_rect) => style_clip_rect, @@ -2984,32 +3317,36 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // CSS `clip` should only apply to position:absolute or positione:fixed elements. // CSS Masking Appendix A: "Applies to: Absolutely positioned elements." match self.positioning() { - StylePosition::Absolute | StylePosition::Fixed => {} + StylePosition::Absolute | StylePosition::Fixed => {}, _ => return, } - let clip_origin = Point2D::new(stacking_relative_border_box.origin.x + - style_clip_rect.left.map(Au::from).unwrap_or(Au(0)), - stacking_relative_border_box.origin.y + - style_clip_rect.top.map(Au::from).unwrap_or(Au(0))); - let right = style_clip_rect.right.map(Au::from) + let clip_origin = Point2D::new( + stacking_relative_border_box.origin.x + + style_clip_rect.left.map(Au::from).unwrap_or(Au(0)), + stacking_relative_border_box.origin.y + + style_clip_rect.top.map(Au::from).unwrap_or(Au(0)), + ); + let right = style_clip_rect + .right + .map(Au::from) .unwrap_or(stacking_relative_border_box.size.width); - let bottom = style_clip_rect.bottom.map(Au::from) + let bottom = style_clip_rect + .bottom + .map(Au::from) .unwrap_or(stacking_relative_border_box.size.height); let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y); let clip_rect = Rect::new(clip_origin, clip_size); preserved_state.push_clip(state, &clip_rect, self.positioning()); - let new_index = state.add_clip_scroll_node( - ClipScrollNode { - id: None, - parent_index: self.clipping_and_scrolling().scrolling, - clip: ClippingRegion::from_rect(&clip_rect), - content_rect: Rect::zero(), // content_rect isn't important for clips. - node_type: ClipScrollNodeType::Clip, - }, - ); + let new_index = state.add_clip_scroll_node(ClipScrollNode { + id: None, + parent_index: self.clipping_and_scrolling().scrolling, + clip: ClippingRegion::from_rect(&clip_rect), + content_rect: Rect::zero(), // content_rect isn't important for clips. + node_type: ClipScrollNodeType::Clip, + }); let new_indices = ClippingAndScrolling::new(new_index, new_index); self.base.clipping_and_scrolling = Some(new_indices); @@ -3020,27 +3357,34 @@ impl BlockFlowDisplayListBuilding for BlockFlow { &mut self, parent_stacking_context_id: StackingContextId, parent_clipping_and_scrolling: ClippingAndScrolling, - state: &mut StackingContextCollectionState + state: &mut StackingContextCollectionState, ) { - let creation_mode = if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || - self.fragment.style.get_box().position != StylePosition::Static { + let creation_mode = if self.base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || + self.fragment.style.get_box().position != StylePosition::Static + { StackingContextType::PseudoPositioned } else { assert!(self.base.flags.is_float()); StackingContextType::PseudoFloat }; - let new_context = self.fragment.create_stacking_context(self.base.stacking_context_id, - &self.base, - ScrollPolicy::Scrollable, - creation_mode, - parent_clipping_and_scrolling); + let new_context = self.fragment.create_stacking_context( + self.base.stacking_context_id, + &self.base, + ScrollPolicy::Scrollable, + creation_mode, + parent_clipping_and_scrolling, + ); state.add_stacking_context(parent_stacking_context_id, new_context); self.base.collect_stacking_contexts_for_children(state); - let children = state.stacking_context_info.get_mut(&self.base.stacking_context_id) - .map(|info| info.take_children()); + let children = state + .stacking_context_info + .get_mut(&self.base.stacking_context_id) + .map(|info| info.take_children()); if let Some(children) = children { for child in children { if child.context_type == StackingContextType::PseudoFloat { @@ -3056,7 +3400,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { &mut self, parent_stacking_context_id: StackingContextId, parent_clipping_and_scrolling: ClippingAndScrolling, - state: &mut StackingContextCollectionState + state: &mut StackingContextCollectionState, ) { let scroll_policy = if self.is_fixed() { ScrollPolicy::Fixed @@ -3069,19 +3413,24 @@ impl BlockFlowDisplayListBuilding for BlockFlow { &self.base, scroll_policy, StackingContextType::Real, - parent_clipping_and_scrolling + parent_clipping_and_scrolling, ); state.add_stacking_context(parent_stacking_context_id, stacking_context); self.base.collect_stacking_contexts_for_children(state); } - fn build_display_list_for_block(&mut self, - state: &mut DisplayListBuildState, - border_painting_mode: BorderPaintingMode) { + fn build_display_list_for_block( + &mut self, + state: &mut DisplayListBuildState, + border_painting_mode: BorderPaintingMode, + ) { let background_border_section = if self.base.flags.is_float() { DisplayListSection::BackgroundAndBorders - } else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + } else if self.base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { if self.fragment.establishes_stacking_context() { DisplayListSection::BackgroundAndBorders } else { @@ -3094,20 +3443,22 @@ impl BlockFlowDisplayListBuilding for BlockFlow { state.processing_scrolling_overflow_element = self.has_scrolling_overflow(); // Add the box that starts the block context. - self.fragment - .build_display_list(state, - &self.base.stacking_relative_position, - &self.base - .early_absolute_position_info - .relative_containing_block_size, - self.base - .early_absolute_position_info - .relative_containing_block_mode, - border_painting_mode, - background_border_section, - &self.base.clip); - - self.base.build_display_items_for_debugging_tint(state, self.fragment.node); + self.fragment.build_display_list( + state, + &self.base.stacking_relative_position, + &self.base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, + border_painting_mode, + background_border_section, + &self.base.clip, + ); + + self.base + .build_display_items_for_debugging_tint(state, self.fragment.node); state.processing_scrolling_overflow_element = false; } @@ -3122,19 +3473,22 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } if self.fragment.establishes_stacking_context() { - return BlockStackingContextType::StackingContext + return BlockStackingContextType::StackingContext; } - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - return BlockStackingContextType::PseudoStackingContext + if self.base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { + return BlockStackingContextType::PseudoStackingContext; } if self.fragment.style.get_box().position != StylePosition::Static { - return BlockStackingContextType::PseudoStackingContext + return BlockStackingContextType::PseudoStackingContext; } if self.base.flags.is_float() { - return BlockStackingContextType::PseudoStackingContext + return BlockStackingContextType::PseudoStackingContext; } BlockStackingContextType::NonstackingContext @@ -3143,9 +3497,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { pub trait InlineFlowDisplayListBuilding { fn collect_stacking_contexts_for_inline(&mut self, state: &mut StackingContextCollectionState); - fn build_display_list_for_inline_fragment_at_index(&mut self, - state: &mut DisplayListBuildState, - index: usize); + fn build_display_list_for_inline_fragment_at_index( + &mut self, + state: &mut DisplayListBuildState, + index: usize, + ); fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState); } @@ -3157,9 +3513,12 @@ impl InlineFlowDisplayListBuilding for InlineFlow { for fragment in self.fragments.fragments.iter_mut() { let previous_cb_clipping_and_scrolling = state.containing_block_clipping_and_scrolling; - if establishes_containing_block_for_absolute(StackingContextCollectionFlags::empty(), - fragment.style.get_box().position) { - state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling; + if establishes_containing_block_for_absolute( + StackingContextCollectionFlags::empty(), + fragment.style.get_box().position, + ) { + state.containing_block_clipping_and_scrolling = + state.current_clipping_and_scrolling; } if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) { @@ -3172,7 +3531,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow { &self.base, ScrollPolicy::Scrollable, StackingContextType::Real, - state.current_clipping_and_scrolling + state.current_clipping_and_scrolling, ); state.add_stacking_context(current_stacking_context_id, stacking_context); @@ -3183,30 +3542,36 @@ impl InlineFlowDisplayListBuilding for InlineFlow { state.containing_block_clipping_and_scrolling = previous_cb_clipping_and_scrolling; } - } - fn build_display_list_for_inline_fragment_at_index(&mut self, - state: &mut DisplayListBuildState, - index: usize) { + fn build_display_list_for_inline_fragment_at_index( + &mut self, + state: &mut DisplayListBuildState, + index: usize, + ) { let fragment = self.fragments.fragments.get_mut(index).unwrap(); - fragment.build_display_list(state, - &self.base.stacking_relative_position, - &self.base - .early_absolute_position_info - .relative_containing_block_size, - self.base - .early_absolute_position_info - .relative_containing_block_mode, - BorderPaintingMode::Separate, - DisplayListSection::Content, - &self.base.clip); + fragment.build_display_list( + state, + &self.base.stacking_relative_position, + &self.base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, + BorderPaintingMode::Separate, + DisplayListSection::Content, + &self.base.clip, + ); } fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState) { // TODO(#228): Once we form lines and have their cached bounds, we can be smarter and // not recurse on a line if nothing in it can intersect the dirty region. - debug!("Flow: building display list for {} inline fragments", self.fragments.len()); + debug!( + "Flow: building display list for {} inline fragments", + self.fragments.len() + ); // We iterate using an index here, because we want to avoid doing a doing // a double-borrow of self (one mutable for the method call and one immutable @@ -3214,8 +3579,10 @@ impl InlineFlowDisplayListBuilding for InlineFlow { for index in 0..self.fragments.fragments.len() { let (establishes_stacking_context, stacking_context_id) = { let fragment = self.fragments.fragments.get(index).unwrap(); - (self.base.stacking_context_id != fragment.stacking_context_id, - fragment.stacking_context_id) + ( + self.base.stacking_context_id != fragment.stacking_context_id, + fragment.stacking_context_id, + ) }; let parent_stacking_context_id = state.current_stacking_context_id; @@ -3231,8 +3598,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow { } if !self.fragments.fragments.is_empty() { - self.base.build_display_items_for_debugging_tint(state, - self.fragments.fragments[0].node); + self.base + .build_display_items_for_debugging_tint(state, self.fragments.fragments[0].node); } } } @@ -3245,23 +3612,26 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { fn build_display_list_for_list_item(&mut self, state: &mut DisplayListBuildState) { // Draw the marker, if applicable. for marker in &mut self.marker_fragments { - marker.build_display_list(state, - &self.block_flow.base.stacking_relative_position, - &self.block_flow - .base - .early_absolute_position_info - .relative_containing_block_size, - self.block_flow - .base - .early_absolute_position_info - .relative_containing_block_mode, - BorderPaintingMode::Separate, - DisplayListSection::Content, - &self.block_flow.base.clip); + marker.build_display_list( + state, + &self.block_flow.base.stacking_relative_position, + &self.block_flow + .base + .early_absolute_position_info + .relative_containing_block_size, + self.block_flow + .base + .early_absolute_position_info + .relative_containing_block_mode, + BorderPaintingMode::Separate, + DisplayListSection::Content, + &self.block_flow.base.clip, + ); } // Draw the rest of the block. - self.block_flow.build_display_list_for_block(state, BorderPaintingMode::Separate) + self.block_flow + .build_display_list_for_block(state, BorderPaintingMode::Separate) } } @@ -3272,28 +3642,34 @@ pub trait FlexFlowDisplayListBuilding { impl FlexFlowDisplayListBuilding for FlexFlow { fn build_display_list_for_flex(&mut self, state: &mut DisplayListBuildState) { // Draw the rest of the block. - self.as_mut_block().build_display_list_for_block(state, BorderPaintingMode::Separate) + self.as_mut_block() + .build_display_list_for_block(state, BorderPaintingMode::Separate) } } trait BaseFlowDisplayListBuilding { - fn build_display_items_for_debugging_tint(&self, - state: &mut DisplayListBuildState, - node: OpaqueNode); + fn build_display_items_for_debugging_tint( + &self, + state: &mut DisplayListBuildState, + node: OpaqueNode, + ); } impl BaseFlowDisplayListBuilding for BaseFlow { - fn build_display_items_for_debugging_tint(&self, - state: &mut DisplayListBuildState, - node: OpaqueNode) { + fn build_display_items_for_debugging_tint( + &self, + state: &mut DisplayListBuildState, + node: OpaqueNode, + ) { if !opts::get().show_debug_parallel_layout { - return + return; } let thread_id = self.thread_id; - let stacking_context_relative_bounds = - Rect::new(self.stacking_relative_position.to_point(), - self.position.size.to_physical(self.writing_mode)); + let stacking_context_relative_bounds = Rect::new( + self.stacking_relative_position.to_point(), + self.position.size.to_physical(self.writing_mode), + ); let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()]; color.a = 1.0; @@ -3302,7 +3678,8 @@ impl BaseFlowDisplayListBuilding for BaseFlow { LocalClip::from(self.clip.to_rectf()), node, None, - DisplayListSection::Content); + DisplayListSection::Content, + ); state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { base: base, border_widths: SideOffsets2D::new_all_same(Au::from_px(2)), @@ -3325,7 +3702,10 @@ impl ComputedValuesCursorUtility for ComputedValues { /// text display items it may be `TextCursor` or `VerticalTextCursor`. #[inline] fn get_cursor(&self, default_cursor: Cursor) -> Option { - match (self.get_pointing().pointer_events, self.get_pointing().cursor) { + match ( + self.get_pointing().pointer_events, + self.get_pointing().cursor, + ) { (PointerEvents::None, _) => None, (PointerEvents::Auto, cursor::Keyword::Auto) => Some(default_cursor), (PointerEvents::Auto, cursor::Keyword::Cursor(cursor)) => Some(cursor), @@ -3344,7 +3724,7 @@ struct StopRun { fn position_to_offset(position: LengthOrPercentage, total_length: Au) -> f32 { if total_length == Au(0) { - return 0.0 + return 0.0; } match position { LengthOrPercentage::Length(l) => l.to_i32_au() as f32 / total_length.0 as f32, @@ -3388,7 +3768,12 @@ pub trait ToGfxColor { impl ToGfxColor for RGBA { fn to_gfx_color(&self) -> ColorF { - ColorF::new(self.red_f32(), self.green_f32(), self.blue_f32(), self.alpha_f32()) + ColorF::new( + self.red_f32(), + self.green_f32(), + self.blue_f32(), + self.alpha_f32(), + ) } } diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs index ea224ad2078a..7cc0f4023db0 100644 --- a/components/layout/webrender_helpers.rs +++ b/components/layout/webrender_helpers.rs @@ -8,7 +8,7 @@ // completely converting layout to directly generate WebRender display lists, for example. use app_units::Au; -use euclid::{Point2D, Vector2D, Rect, SideOffsets2D, Size2D}; +use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D}; use gfx::display_list::{BorderDetails, BorderRadii, BoxShadowClipMode, ClipScrollNode}; use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingRegion, DisplayItem}; use gfx::display_list::{DisplayList, StackingContextType}; @@ -32,7 +32,7 @@ trait WebRenderDisplayItemConverter { builder: &mut DisplayListBuilder, clip_scroll_nodes: &[ClipScrollNode], clip_ids: &mut Vec>, - current_clip_and_scroll_info: &mut ClipAndScrollInfo + current_clip_and_scroll_info: &mut ClipAndScrollInfo, ); } @@ -196,17 +196,33 @@ impl ToFilterOps for Vec { let mut result = Vec::with_capacity(self.len()); for filter in self.iter() { match *filter { - GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius.px())), - GenericFilter::Brightness(amount) => result.push(webrender_api::FilterOp::Brightness(amount.0)), - GenericFilter::Contrast(amount) => result.push(webrender_api::FilterOp::Contrast(amount.0)), - GenericFilter::Grayscale(amount) => result.push(webrender_api::FilterOp::Grayscale(amount.0)), - GenericFilter::HueRotate(angle) => result.push(webrender_api::FilterOp::HueRotate(angle.radians())), - GenericFilter::Invert(amount) => result.push(webrender_api::FilterOp::Invert(amount.0)), + GenericFilter::Blur(radius) => { + result.push(webrender_api::FilterOp::Blur(radius.px())) + }, + GenericFilter::Brightness(amount) => { + result.push(webrender_api::FilterOp::Brightness(amount.0)) + }, + GenericFilter::Contrast(amount) => { + result.push(webrender_api::FilterOp::Contrast(amount.0)) + }, + GenericFilter::Grayscale(amount) => { + result.push(webrender_api::FilterOp::Grayscale(amount.0)) + }, + GenericFilter::HueRotate(angle) => { + result.push(webrender_api::FilterOp::HueRotate(angle.radians())) + }, + GenericFilter::Invert(amount) => { + result.push(webrender_api::FilterOp::Invert(amount.0)) + }, GenericFilter::Opacity(amount) => { result.push(webrender_api::FilterOp::Opacity(amount.0.into(), amount.0)); - } - GenericFilter::Saturate(amount) => result.push(webrender_api::FilterOp::Saturate(amount.0)), - GenericFilter::Sepia(amount) => result.push(webrender_api::FilterOp::Sepia(amount.0)), + }, + GenericFilter::Saturate(amount) => { + result.push(webrender_api::FilterOp::Saturate(amount.0)) + }, + GenericFilter::Sepia(amount) => { + result.push(webrender_api::FilterOp::Sepia(amount.0)) + }, GenericFilter::DropShadow(ref shadow) => match *shadow {}, } } @@ -229,9 +245,11 @@ impl ToTransformStyle for TransformStyle { impl WebRenderDisplayListConverter for DisplayList { fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder { - let mut builder = DisplayListBuilder::with_capacity(pipeline_id.to_webrender(), - self.bounds().size.to_sizef(), - 1024 * 1024); // 1 MB of space + let mut builder = DisplayListBuilder::with_capacity( + pipeline_id.to_webrender(), + self.bounds().size.to_sizef(), + 1024 * 1024, + ); // 1 MB of space let mut current_clip_and_scroll_info = pipeline_id.root_clip_and_scroll_info(); builder.push_clip_and_scroll_info(current_clip_and_scroll_info); @@ -245,7 +263,7 @@ impl WebRenderDisplayListConverter for DisplayList { &mut builder, &self.clip_scroll_nodes, &mut clip_ids, - &mut current_clip_and_scroll_info + &mut current_clip_and_scroll_info, ); } builder @@ -272,7 +290,7 @@ impl WebRenderDisplayItemConverter for DisplayItem { builder: &mut DisplayListBuilder, clip_scroll_nodes: &[ClipScrollNode], clip_ids: &mut Vec>, - current_clip_and_scroll_info: &mut ClipAndScrollInfo + current_clip_and_scroll_info: &mut ClipAndScrollInfo, ) { let get_id = |clip_ids: &[Option], index: ClipScrollNodeIndex| -> ClipId { match clip_ids[index.0] { @@ -297,12 +315,14 @@ impl WebRenderDisplayItemConverter for DisplayItem { match *self { DisplayItem::SolidColor(ref item) => { builder.push_rect(&self.prim_info(), item.color); - } + }, DisplayItem::Text(ref item) => { let mut origin = item.baseline_origin.clone(); - let mut glyphs = vec!(); + let mut glyphs = vec![]; - for slice in item.text_run.natural_word_slices_in_visual_order(&item.range) { + for slice in item.text_run + .natural_word_slices_in_visual_order(&item.range) + { for glyph in slice.glyphs.iter_glyphs_for_byte_range(&slice.range) { let glyph_advance = if glyph.char_is_space() { glyph.advance() + item.text_run.extra_word_spacing @@ -321,29 +341,32 @@ impl WebRenderDisplayItemConverter for DisplayItem { glyphs.push(glyph); } origin.x = origin.x + glyph_advance; - }; + } } if glyphs.len() > 0 { - builder.push_text(&self.prim_info(), - &glyphs, - item.text_run.font_key, - item.text_color, - None); + builder.push_text( + &self.prim_info(), + &glyphs, + item.text_run.font_key, + item.text_color, + None, + ); } - } + }, DisplayItem::Image(ref item) => { if let Some(id) = item.webrender_image.key { - if item.stretch_size.width > Au(0) && - item.stretch_size.height > Au(0) { - builder.push_image(&self.prim_info(), - item.stretch_size.to_sizef(), - item.tile_spacing.to_sizef(), - item.image_rendering.to_image_rendering(), - id); + if item.stretch_size.width > Au(0) && item.stretch_size.height > Au(0) { + builder.push_image( + &self.prim_info(), + item.stretch_size.to_sizef(), + item.tile_spacing.to_sizef(), + item.image_rendering.to_image_rendering(), + id, + ); } } - } + }, DisplayItem::Border(ref item) => { let widths = item.border_widths.to_border_widths(); @@ -373,26 +396,24 @@ impl WebRenderDisplayItemConverter for DisplayItem { bottom: bottom, radius: radius, }) - } - BorderDetails::Image(ref image) => { - match image.image.key { - None => return, - Some(key) => { - webrender_api::BorderDetails::Image(webrender_api::ImageBorder { - image_key: key, - patch: webrender_api::NinePatchDescriptor { - width: image.image.width, - height: image.image.height, - slice: image.slice, - }, - fill: image.fill, - outset: image.outset, - repeat_horizontal: image.repeat_horizontal, - repeat_vertical: image.repeat_vertical, - }) - } - } - } + }, + BorderDetails::Image(ref image) => match image.image.key { + None => return, + Some(key) => { + webrender_api::BorderDetails::Image(webrender_api::ImageBorder { + image_key: key, + patch: webrender_api::NinePatchDescriptor { + width: image.image.width, + height: image.image.height, + slice: image.slice, + }, + fill: image.fill, + outset: image.outset, + repeat_horizontal: image.repeat_horizontal, + repeat_vertical: image.repeat_vertical, + }) + }, + }, BorderDetails::Gradient(ref gradient) => { let extend_mode = if gradient.gradient.repeating { ExtendMode::Repeat @@ -401,32 +422,36 @@ impl WebRenderDisplayItemConverter for DisplayItem { }; webrender_api::BorderDetails::Gradient(webrender_api::GradientBorder { gradient: builder.create_gradient( - gradient.gradient.start_point.to_pointf(), - gradient.gradient.end_point.to_pointf(), - gradient.gradient.stops.clone(), - extend_mode), + gradient.gradient.start_point.to_pointf(), + gradient.gradient.end_point.to_pointf(), + gradient.gradient.stops.clone(), + extend_mode, + ), outset: gradient.outset, }) - } + }, BorderDetails::RadialGradient(ref gradient) => { let extend_mode = if gradient.gradient.repeating { ExtendMode::Repeat } else { ExtendMode::Clamp }; - webrender_api::BorderDetails::RadialGradient(webrender_api::RadialGradientBorder { - gradient: builder.create_radial_gradient( - gradient.gradient.center.to_pointf(), - gradient.gradient.radius.to_sizef(), - gradient.gradient.stops.clone(), - extend_mode), - outset: gradient.outset, - }) - } + webrender_api::BorderDetails::RadialGradient( + webrender_api::RadialGradientBorder { + gradient: builder.create_radial_gradient( + gradient.gradient.center.to_pointf(), + gradient.gradient.radius.to_sizef(), + gradient.gradient.stops.clone(), + extend_mode, + ), + outset: gradient.outset, + }, + ) + }, }; builder.push_border(&self.prim_info(), widths, details); - } + }, DisplayItem::Gradient(ref item) => { let start_point = item.gradient.start_point.to_pointf(); let end_point = item.gradient.end_point.to_pointf(); @@ -435,15 +460,19 @@ impl WebRenderDisplayItemConverter for DisplayItem { } else { ExtendMode::Clamp }; - let gradient = builder.create_gradient(start_point, - end_point, - item.gradient.stops.clone(), - extend_mode); - builder.push_gradient(&self.prim_info(), - gradient, - item.tile.to_sizef(), - item.tile_spacing.to_sizef()); - } + let gradient = builder.create_gradient( + start_point, + end_point, + item.gradient.stops.clone(), + extend_mode, + ); + builder.push_gradient( + &self.prim_info(), + gradient, + item.tile.to_sizef(), + item.tile_spacing.to_sizef(), + ); + }, DisplayItem::RadialGradient(ref item) => { let center = item.gradient.center.to_pointf(); let radius = item.gradient.radius.to_sizef(); @@ -452,58 +481,68 @@ impl WebRenderDisplayItemConverter for DisplayItem { } else { ExtendMode::Clamp }; - let gradient = builder.create_radial_gradient(center, - radius, - item.gradient.stops.clone(), - extend_mode); - builder.push_radial_gradient(&self.prim_info(), - gradient, - item.tile.to_sizef(), - item.tile_spacing.to_sizef()); - } + let gradient = builder.create_radial_gradient( + center, + radius, + item.gradient.stops.clone(), + extend_mode, + ); + builder.push_radial_gradient( + &self.prim_info(), + gradient, + item.tile.to_sizef(), + item.tile_spacing.to_sizef(), + ); + }, DisplayItem::Line(ref item) => { - builder.push_line(&self.prim_info(), - // TODO(gw): Use a better estimate for wavy line thickness. - (0.33 * item.base.bounds.size.height.to_f32_px()).ceil(), - webrender_api::LineOrientation::Horizontal, - &item.color, - item.style); - } + builder.push_line( + &self.prim_info(), + // TODO(gw): Use a better estimate for wavy line thickness. + (0.33 * item.base.bounds.size.height.to_f32_px()).ceil(), + webrender_api::LineOrientation::Horizontal, + &item.color, + item.style, + ); + }, DisplayItem::BoxShadow(ref item) => { let box_bounds = item.box_bounds.to_rectf(); - builder.push_box_shadow(&self.prim_info(), - box_bounds, - item.offset.to_vectorf(), - item.color, - item.blur_radius.to_f32_px(), - item.spread_radius.to_f32_px(), - item.border_radius.to_border_radius(), - item.clip_mode.to_clip_mode()); - } + builder.push_box_shadow( + &self.prim_info(), + box_bounds, + item.offset.to_vectorf(), + item.color, + item.blur_radius.to_f32_px(), + item.spread_radius.to_f32_px(), + item.border_radius.to_border_radius(), + item.clip_mode.to_clip_mode(), + ); + }, DisplayItem::PushTextShadow(ref item) => { - builder.push_shadow(&self.prim_info(), - webrender_api::Shadow { - blur_radius: item.blur_radius.to_f32_px(), - offset: item.offset.to_vectorf(), - color: item.color, - }); - } + builder.push_shadow( + &self.prim_info(), + webrender_api::Shadow { + blur_radius: item.blur_radius.to_f32_px(), + offset: item.offset.to_vectorf(), + color: item.color, + }, + ); + }, DisplayItem::PopAllTextShadows(_) => { builder.pop_all_shadows(); - } + }, DisplayItem::Iframe(ref item) => { builder.push_iframe(&self.prim_info(), item.iframe.to_webrender()); - } + }, DisplayItem::PushStackingContext(ref item) => { let stacking_context = &item.stacking_context; debug_assert!(stacking_context.context_type == StackingContextType::Real); - let transform = stacking_context.transform.map(|transform| { - LayoutTransform::from_untyped(&transform).into() - }); - let perspective = stacking_context.perspective.map(|perspective| { - LayoutTransform::from_untyped(&perspective) - }); + let transform = stacking_context + .transform + .map(|transform| LayoutTransform::from_untyped(&transform).into()); + let perspective = stacking_context + .perspective + .map(|perspective| LayoutTransform::from_untyped(&perspective)); builder.push_stacking_context( &webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds.to_rectf()), @@ -512,9 +551,9 @@ impl WebRenderDisplayItemConverter for DisplayItem { stacking_context.transform_style, perspective, stacking_context.mix_blend_mode, - stacking_context.filters.to_filter_ops() + stacking_context.filters.to_filter_ops(), ); - } + }, DisplayItem::PopStackingContext(_) => builder.pop_stacking_context(), DisplayItem::DefineClipScrollNode(ref item) => { let node = &clip_scroll_nodes[item.node_index.0]; @@ -522,26 +561,23 @@ impl WebRenderDisplayItemConverter for DisplayItem { let item_rect = node.clip.main.to_rectf(); let webrender_id = match node.node_type { - ClipScrollNodeType::Clip => { - builder.define_clip_with_parent( - node.id, - parent_id, - item_rect, - node.clip.get_complex_clips(), - None - ) - } - ClipScrollNodeType::ScrollFrame(scroll_sensitivity) => { - builder.define_scroll_frame_with_parent( + ClipScrollNodeType::Clip => builder.define_clip_with_parent( + node.id, + parent_id, + item_rect, + node.clip.get_complex_clips(), + None, + ), + ClipScrollNodeType::ScrollFrame(scroll_sensitivity) => builder + .define_scroll_frame_with_parent( node.id, parent_id, node.content_rect.to_rectf(), node.clip.main.to_rectf(), node.clip.get_complex_clips(), None, - scroll_sensitivity - ) - } + scroll_sensitivity, + ), ClipScrollNodeType::StickyFrame(ref sticky_data) => { // TODO: Add define_sticky_frame_with_parent to WebRender. builder.push_clip_id(parent_id); @@ -555,12 +591,12 @@ impl WebRenderDisplayItemConverter for DisplayItem { ); builder.pop_clip_id(); id - } + }, }; debug_assert!(node.id.is_none() || node.id == Some(webrender_id)); clip_ids[item.node_index.0] = Some(webrender_id); - } + }, } } } @@ -571,12 +607,15 @@ trait ToWebRenderClip { impl ToWebRenderClip for ClippingRegion { fn get_complex_clips(&self) -> Vec { - self.complex.iter().map(|complex_clipping_region| { - ComplexClipRegion::new( - complex_clipping_region.rect.to_rectf(), - complex_clipping_region.radii.to_border_radius(), - ClipMode::Clip, - ) - }).collect() + self.complex + .iter() + .map(|complex_clipping_region| { + ComplexClipRegion::new( + complex_clipping_region.rect.to_rectf(), + complex_clipping_region.radii.to_border_radius(), + ClipMode::Clip, + ) + }) + .collect() } } diff --git a/rustfmt.toml b/rustfmt.toml index e2c132c09dd6..63156a8ec7b5 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,7 +1,2 @@ -ideal_width = 80 match_block_trailing_comma = true -max_width = 120 -newline_style = "Unix" -normalize_comments = false -struct_lit_multiline_style = "ForceMulti" -where_trailing_comma = true +binop_separator = "Back"