mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Auto merge of #20752 - pyfisch:backgrounds42, r=emilio
Fix crash in DL building Fix one crash and some style changes. This HTML crashed servo before. Key parts are `background-clip: content-box` and `direction: rtl` ```html <!DOCTYPE html> <html> <style> #span1 { background-clip: content-box; } #span2 { direction: rtl; } </style> <span id="span1">Filler Text <span id="span2">txeT relliF</span></span> </html> ``` Should I add this as a test? And where do I put this "does-it-crash?" test? I find always passing rectangles by value a lot easier as it avoids many references and dereferences and I assume that the compiler will always use the faster one either way. If you don't like the change feel free to only merge the first commit. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20752) <!-- Reviewable:end -->
This commit is contained in:
commit
ea214e9bc3
7 changed files with 220 additions and 191 deletions
|
@ -711,7 +711,7 @@ fn handle_overlapping_radii(size: LayoutSize, radii: BorderRadius) -> BorderRadi
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_border_radius(
|
pub fn build_border_radius(
|
||||||
abs_bounds: &Rect<Au>,
|
abs_bounds: Rect<Au>,
|
||||||
border_style: &style_structs::Border,
|
border_style: &style_structs::Border,
|
||||||
) -> BorderRadius {
|
) -> BorderRadius {
|
||||||
// TODO(cgaebel): Support border radii even in the case of multiple border widths.
|
// TODO(cgaebel): Support border radii even in the case of multiple border widths.
|
||||||
|
@ -811,10 +811,7 @@ pub fn build_image_border_details(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_border_image_outset_side(
|
fn calculate_border_image_outset_side(outset: LengthOrNumber, border_width: Au) -> Au {
|
||||||
outset: LengthOrNumber,
|
|
||||||
border_width: Au,
|
|
||||||
) -> Au {
|
|
||||||
match outset {
|
match outset {
|
||||||
Either::First(length) => length.into(),
|
Either::First(length) => length.into(),
|
||||||
Either::Second(factor) => border_width.scale_by(factor),
|
Either::Second(factor) => border_width.scale_by(factor),
|
||||||
|
|
|
@ -17,8 +17,9 @@ use context::LayoutContext;
|
||||||
use display_list::ToLayout;
|
use display_list::ToLayout;
|
||||||
use display_list::background::{build_border_radius, build_image_border_details};
|
use display_list::background::{build_border_radius, build_image_border_details};
|
||||||
use display_list::background::{calculate_border_image_outset, calculate_inner_border_radii};
|
use display_list::background::{calculate_border_image_outset, calculate_inner_border_radii};
|
||||||
use display_list::background::{compute_background_placement, convert_linear_gradient};
|
use display_list::background::{compute_background_clip, compute_background_placement};
|
||||||
use display_list::background::{convert_radial_gradient, get_cyclic, simple_normal_border};
|
use display_list::background::{convert_linear_gradient, convert_radial_gradient, get_cyclic};
|
||||||
|
use display_list::background::simple_normal_border;
|
||||||
use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
|
use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
|
||||||
use display_list::items::{BoxShadowDisplayItem, ClipScrollNode};
|
use display_list::items::{BoxShadowDisplayItem, ClipScrollNode};
|
||||||
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
|
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
|
||||||
|
@ -52,7 +53,6 @@ use std::default::Default;
|
||||||
use std::f32;
|
use std::f32;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
|
||||||
use style::computed_values::border_style::T as BorderStyle;
|
use style::computed_values::border_style::T as BorderStyle;
|
||||||
use style::computed_values::overflow_x::T as StyleOverflow;
|
use style::computed_values::overflow_x::T as StyleOverflow;
|
||||||
use style::computed_values::pointer_events::T as PointerEvents;
|
use style::computed_values::pointer_events::T as PointerEvents;
|
||||||
|
@ -385,8 +385,8 @@ impl<'a> DisplayListBuildState<'a> {
|
||||||
|
|
||||||
fn create_base_display_item(
|
fn create_base_display_item(
|
||||||
&self,
|
&self,
|
||||||
bounds: &Rect<Au>,
|
bounds: Rect<Au>,
|
||||||
clip_rect: &Rect<Au>,
|
clip_rect: Rect<Au>,
|
||||||
node: OpaqueNode,
|
node: OpaqueNode,
|
||||||
cursor: Option<CursorKind>,
|
cursor: Option<CursorKind>,
|
||||||
section: DisplayListSection,
|
section: DisplayListSection,
|
||||||
|
@ -572,7 +572,7 @@ pub trait FragmentDisplayListBuilding {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
absolute_bounds: &Rect<Au>,
|
absolute_bounds: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Same as build_display_list_for_background_if_applicable, but lets you
|
/// Same as build_display_list_for_background_if_applicable, but lets you
|
||||||
|
@ -584,7 +584,7 @@ pub trait FragmentDisplayListBuilding {
|
||||||
background: &style_structs::Background,
|
background: &style_structs::Background,
|
||||||
background_color: RGBA,
|
background_color: RGBA,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
absolute_bounds: &Rect<Au>,
|
absolute_bounds: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adds the display items necessary to paint a webrender image of this fragment to the
|
/// Adds the display items necessary to paint a webrender image of this fragment to the
|
||||||
|
@ -630,9 +630,9 @@ pub trait FragmentDisplayListBuilding {
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
inline_node_info: Option<InlineNodeBorderInfo>,
|
inline_node_info: Option<InlineNodeBorderInfo>,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
bounds: &Rect<Au>,
|
bounds: Rect<Au>,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adds the display items necessary to paint the outline of this fragment to the display list
|
/// Adds the display items necessary to paint the outline of this fragment to the display list
|
||||||
|
@ -641,8 +641,8 @@ pub trait FragmentDisplayListBuilding {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
bounds: &Rect<Au>,
|
bounds: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adds the display items necessary to paint the box shadow of this fragment to the display
|
/// Adds the display items necessary to paint the box shadow of this fragment to the display
|
||||||
|
@ -652,8 +652,8 @@ pub trait FragmentDisplayListBuilding {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
absolute_bounds: &Rect<Au>,
|
absolute_bounds: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adds display items necessary to draw debug boxes around a scanned text fragment.
|
/// Adds display items necessary to draw debug boxes around a scanned text fragment.
|
||||||
|
@ -661,18 +661,18 @@ pub trait FragmentDisplayListBuilding {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
stacking_relative_content_box: &Rect<Au>,
|
stacking_relative_content_box: Rect<Au>,
|
||||||
text_fragment: &ScannedTextFragmentInfo,
|
text_fragment: &ScannedTextFragmentInfo,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adds display items necessary to draw debug boxes around this fragment.
|
/// Adds display items necessary to draw debug boxes around this fragment.
|
||||||
fn build_debug_borders_around_fragment(
|
fn build_debug_borders_around_fragment(
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adds the display items for this fragment to the given display list.
|
/// Adds the display items for this fragment to the given display list.
|
||||||
|
@ -689,7 +689,7 @@ pub trait FragmentDisplayListBuilding {
|
||||||
stacking_relative_border_box: Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// build_display_list, but don't update the restyle damage
|
/// build_display_list, but don't update the restyle damage
|
||||||
|
@ -701,7 +701,7 @@ pub trait FragmentDisplayListBuilding {
|
||||||
stacking_relative_border_box: Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Builds the display items necessary to paint the selection and/or caret for this fragment,
|
/// Builds the display items necessary to paint the selection and/or caret for this fragment,
|
||||||
|
@ -709,9 +709,9 @@ pub trait FragmentDisplayListBuilding {
|
||||||
fn build_display_items_for_selection_if_necessary(
|
fn build_display_items_for_selection_if_necessary(
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Creates the text display item for one text fragment. This can be called multiple times for
|
/// Creates the text display item for one text fragment. This can be called multiple times for
|
||||||
|
@ -722,9 +722,9 @@ pub trait FragmentDisplayListBuilding {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
text_fragment: &ScannedTextFragmentInfo,
|
text_fragment: &ScannedTextFragmentInfo,
|
||||||
stacking_relative_content_box: &Rect<Au>,
|
stacking_relative_content_box: Rect<Au>,
|
||||||
text_shadows: &[SimpleShadow],
|
text_shadows: &[SimpleShadow],
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Creates the display item for a text decoration: underline, overline, or line-through.
|
/// Creates the display item for a text decoration: underline, overline, or line-through.
|
||||||
|
@ -733,15 +733,15 @@ pub trait FragmentDisplayListBuilding {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
color: &RGBA,
|
color: &RGBA,
|
||||||
stacking_relative_box: &LogicalRect<Au>,
|
stacking_relative_box: &LogicalRect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A helper method that `build_display_list` calls to create per-fragment-type display items.
|
/// A helper method that `build_display_list` calls to create per-fragment-type display items.
|
||||||
fn build_fragment_type_specific_display_items(
|
fn build_fragment_type_specific_display_items(
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Creates a stacking context for associated fragment.
|
/// Creates a stacking context for associated fragment.
|
||||||
|
@ -762,10 +762,10 @@ pub trait FragmentDisplayListBuilding {
|
||||||
/// Get the border radius for the rectangle inside of a rounded border. This is useful
|
/// 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.
|
/// for building the clip for the content inside the border.
|
||||||
fn build_border_radius_for_inner_rect(
|
fn build_border_radius_for_inner_rect(
|
||||||
outer_rect: &Rect<Au>,
|
outer_rect: Rect<Au>,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
) -> BorderRadius {
|
) -> BorderRadius {
|
||||||
let radii = build_border_radius(&outer_rect, style.get_border());
|
let radii = build_border_radius(outer_rect, style.get_border());
|
||||||
if radii.is_zero() {
|
if radii.is_zero() {
|
||||||
return radii;
|
return radii;
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
absolute_bounds: &Rect<Au>,
|
absolute_bounds: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
let background = style.get_background();
|
let background = style.get_background();
|
||||||
let background_color = style.resolve_color(background.background_color);
|
let background_color = style.resolve_color(background.background_color);
|
||||||
|
@ -833,40 +833,26 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
background: &style_structs::Background,
|
background: &style_structs::Background,
|
||||||
background_color: RGBA,
|
background_color: RGBA,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
absolute_bounds: &Rect<Au>,
|
absolute_bounds: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// FIXME: This causes a lot of background colors to be displayed when they are clearly not
|
// 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
|
// 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
|
// inefficient. What we really want is something like "nearest ancestor element that
|
||||||
// doesn't have a fragment".
|
// doesn't have a fragment".
|
||||||
|
|
||||||
// 'background-clip' determines the area within which the background is painted.
|
|
||||||
// http://dev.w3.org/csswg/css-backgrounds-3/#the-background-clip
|
|
||||||
let mut bounds = *absolute_bounds;
|
|
||||||
|
|
||||||
// Quote from CSS Backgrounds and Borders Module Level 3:
|
// Quote from CSS Backgrounds and Borders Module Level 3:
|
||||||
//
|
//
|
||||||
// > The background color is clipped according to the background-clip value associated
|
// > The background color is clipped according to the background-clip value associated
|
||||||
// > with the bottom-most background image layer.
|
// > with the bottom-most background image layer.
|
||||||
let last_background_image_index = background.background_image.0.len() - 1;
|
let last_background_image_index = background.background_image.0.len() - 1;
|
||||||
let color_clip = get_cyclic(&background.background_clip.0, last_background_image_index);
|
let color_clip = *get_cyclic(&background.background_clip.0, last_background_image_index);
|
||||||
|
let (bounds, border_radii) = compute_background_clip(
|
||||||
// Adjust the clipping region as necessary to account for `border-radius`.
|
color_clip,
|
||||||
let mut border_radii = build_border_radius(absolute_bounds, style.get_border());
|
absolute_bounds,
|
||||||
|
style.logical_border_width().to_physical(style.writing_mode),
|
||||||
match color_clip {
|
self.border_padding.to_physical(self.style.writing_mode),
|
||||||
BackgroundClip::BorderBox => {},
|
build_border_radius(absolute_bounds, style.get_border()),
|
||||||
BackgroundClip::PaddingBox => {
|
);
|
||||||
let border = style.logical_border_width().to_physical(style.writing_mode);
|
|
||||||
bounds = bounds.inner_rect(border);
|
|
||||||
border_radii = calculate_inner_border_radii(border_radii, border);
|
|
||||||
},
|
|
||||||
BackgroundClip::ContentBox => {
|
|
||||||
let border_padding = self.border_padding.to_physical(style.writing_mode);
|
|
||||||
bounds = bounds.inner_rect(border_padding);
|
|
||||||
border_radii = calculate_inner_border_radii(border_radii, border_padding);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
state.clipping_and_scrolling_scope(|state| {
|
state.clipping_and_scrolling_scope(|state| {
|
||||||
if !border_radii.is_zero() {
|
if !border_radii.is_zero() {
|
||||||
|
@ -875,8 +861,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&bounds,
|
bounds,
|
||||||
&bounds,
|
bounds,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
display_list_section,
|
display_list_section,
|
||||||
|
@ -898,7 +884,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
self.build_display_list_for_background_gradient(
|
self.build_display_list_for_background_gradient(
|
||||||
state,
|
state,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
*absolute_bounds,
|
absolute_bounds,
|
||||||
gradient,
|
gradient,
|
||||||
style,
|
style,
|
||||||
i,
|
i,
|
||||||
|
@ -916,7 +902,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state,
|
state,
|
||||||
style,
|
style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
*absolute_bounds,
|
absolute_bounds,
|
||||||
webrender_image,
|
webrender_image,
|
||||||
i,
|
i,
|
||||||
);
|
);
|
||||||
|
@ -948,7 +934,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state,
|
state,
|
||||||
style,
|
style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
*absolute_bounds,
|
absolute_bounds,
|
||||||
webrender_image,
|
webrender_image,
|
||||||
i,
|
i,
|
||||||
);
|
);
|
||||||
|
@ -988,8 +974,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
absolute_bounds,
|
absolute_bounds,
|
||||||
Some(image),
|
Some(image),
|
||||||
style.logical_border_width().to_physical(style.writing_mode),
|
style.logical_border_width().to_physical(style.writing_mode),
|
||||||
self.border_padding.to_physical(style.writing_mode),
|
self.border_padding.to_physical(self.style.writing_mode),
|
||||||
build_border_radius(&absolute_bounds, style.get_border()),
|
build_border_radius(absolute_bounds, style.get_border()),
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1002,8 +988,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Create the image display item.
|
// Create the image display item.
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&placement.bounds,
|
placement.bounds,
|
||||||
&placement.clip_rect,
|
placement.clip_rect,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
display_list_section,
|
display_list_section,
|
||||||
|
@ -1095,8 +1081,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
absolute_bounds,
|
absolute_bounds,
|
||||||
None,
|
None,
|
||||||
style.logical_border_width().to_physical(style.writing_mode),
|
style.logical_border_width().to_physical(style.writing_mode),
|
||||||
self.border_padding.to_physical(style.writing_mode),
|
self.border_padding.to_physical(self.style.writing_mode),
|
||||||
build_border_radius(&absolute_bounds, style.get_border()),
|
build_border_radius(absolute_bounds, style.get_border()),
|
||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1108,8 +1094,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&placement.bounds,
|
placement.bounds,
|
||||||
&placement.clip_rect,
|
placement.clip_rect,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
display_list_section,
|
display_list_section,
|
||||||
|
@ -1155,13 +1141,13 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
absolute_bounds: &Rect<Au>,
|
absolute_bounds: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// NB: According to CSS-BACKGROUNDS, box shadows render in *reverse* order (front to back).
|
// 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() {
|
for box_shadow in style.get_effects().box_shadow.0.iter().rev() {
|
||||||
let bounds = shadow_bounds(
|
let bounds = shadow_bounds(
|
||||||
&absolute_bounds.translate(&Vector2D::new(
|
absolute_bounds.translate(&Vector2D::new(
|
||||||
Au::from(box_shadow.base.horizontal),
|
Au::from(box_shadow.base.horizontal),
|
||||||
Au::from(box_shadow.base.vertical),
|
Au::from(box_shadow.base.vertical),
|
||||||
)),
|
)),
|
||||||
|
@ -1170,7 +1156,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
);
|
);
|
||||||
|
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&bounds,
|
bounds,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
|
@ -1207,9 +1193,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
inline_info: Option<InlineNodeBorderInfo>,
|
inline_info: Option<InlineNodeBorderInfo>,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
bounds: &Rect<Au>,
|
mut bounds: Rect<Au>,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
let mut border = style.logical_border_width();
|
let mut border = style.logical_border_width();
|
||||||
|
|
||||||
|
@ -1252,26 +1238,23 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this border collapses, then we draw outside the boundaries we were given.
|
// If this border collapses, then we draw outside the boundaries we were given.
|
||||||
let mut bounds = *bounds;
|
|
||||||
if let BorderPaintingMode::Collapse(collapsed_borders) = border_painting_mode {
|
if let BorderPaintingMode::Collapse(collapsed_borders) = border_painting_mode {
|
||||||
collapsed_borders.adjust_border_bounds_for_painting(&mut bounds, style.writing_mode)
|
collapsed_borders.adjust_border_bounds_for_painting(&mut bounds, style.writing_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the border to the display list.
|
// Append the border to the display list.
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&bounds,
|
bounds,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
display_list_section,
|
display_list_section,
|
||||||
);
|
);
|
||||||
|
|
||||||
let border_radius = build_border_radius(&bounds, border_style_struct);
|
let border_radius = build_border_radius(bounds, border_style_struct);
|
||||||
let border_widths = border.to_physical(style.writing_mode);
|
let border_widths = border.to_physical(style.writing_mode);
|
||||||
let outset = calculate_border_image_outset(
|
let outset =
|
||||||
border_style_struct.border_image_outset,
|
calculate_border_image_outset(border_style_struct.border_image_outset, border_widths);
|
||||||
border_widths
|
|
||||||
);
|
|
||||||
let outset_layout = SideOffsets2D::new(
|
let outset_layout = SideOffsets2D::new(
|
||||||
outset.top.to_f32_px(),
|
outset.top.to_f32_px(),
|
||||||
outset.right.to_f32_px(),
|
outset.right.to_f32_px(),
|
||||||
|
@ -1300,10 +1283,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
},
|
},
|
||||||
radius: border_radius,
|
radius: border_radius,
|
||||||
})),
|
})),
|
||||||
Either::Second(Image::Gradient(ref gradient)) => {
|
Either::Second(Image::Gradient(ref gradient)) => Some(match gradient.kind {
|
||||||
Some(match gradient.kind {
|
GradientKind::Linear(angle_or_corner) => BorderDetails::Gradient(GradientBorder {
|
||||||
GradientKind::Linear(angle_or_corner) => {
|
|
||||||
BorderDetails::Gradient(GradientBorder {
|
|
||||||
gradient: convert_linear_gradient(
|
gradient: convert_linear_gradient(
|
||||||
bounds.size,
|
bounds.size,
|
||||||
&gradient.items[..],
|
&gradient.items[..],
|
||||||
|
@ -1311,8 +1292,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
gradient.repeating,
|
gradient.repeating,
|
||||||
),
|
),
|
||||||
outset: outset_layout,
|
outset: outset_layout,
|
||||||
})
|
}),
|
||||||
},
|
|
||||||
GradientKind::Radial(shape, center, _angle) => {
|
GradientKind::Radial(shape, center, _angle) => {
|
||||||
BorderDetails::RadialGradient(RadialGradientBorder {
|
BorderDetails::RadialGradient(RadialGradientBorder {
|
||||||
gradient: convert_radial_gradient(
|
gradient: convert_radial_gradient(
|
||||||
|
@ -1325,11 +1305,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
outset: outset_layout,
|
outset: outset_layout,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
},
|
|
||||||
Either::Second(Image::PaintWorklet(ref paint_worklet)) => {
|
Either::Second(Image::PaintWorklet(ref paint_worklet)) => {
|
||||||
self.get_webrender_image_for_paint_worklet(state, style, paint_worklet, size)
|
self.get_webrender_image_for_paint_worklet(state, style, paint_worklet, size)
|
||||||
.and_then(|image| build_image_border_details(image, border_style_struct, outset_layout))
|
.and_then(|image| {
|
||||||
|
build_image_border_details(image, border_style_struct, outset_layout)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
Either::Second(Image::Rect(..)) => {
|
Either::Second(Image::Rect(..)) => {
|
||||||
// TODO: Handle border-image with `-moz-image-rect`.
|
// TODO: Handle border-image with `-moz-image-rect`.
|
||||||
|
@ -1348,7 +1329,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
UsePlaceholder::No,
|
UsePlaceholder::No,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|image| build_image_border_details(image, border_style_struct, outset_layout)),
|
.and_then(|image| {
|
||||||
|
build_image_border_details(image, border_style_struct, outset_layout)
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
if let Some(details) = details {
|
if let Some(details) = details {
|
||||||
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
|
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
|
||||||
|
@ -1363,8 +1346,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
bounds: &Rect<Au>,
|
mut bounds: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
use style::values::specified::outline::OutlineStyle;
|
use style::values::specified::outline::OutlineStyle;
|
||||||
|
|
||||||
|
@ -1381,7 +1364,6 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Outlines are not accounted for in the dimensions of the border box, so adjust the
|
// Outlines are not accounted for in the dimensions of the border box, so adjust the
|
||||||
// absolute bounds.
|
// absolute bounds.
|
||||||
let mut bounds = *bounds;
|
|
||||||
let offset = width + Au::from(style.get_outline().outline_offset);
|
let offset = width + Au::from(style.get_outline().outline_offset);
|
||||||
bounds = bounds.inflate(offset, offset);
|
bounds = bounds.inflate(offset, offset);
|
||||||
|
|
||||||
|
@ -1390,7 +1372,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
.resolve_color(style.get_outline().outline_color)
|
.resolve_color(style.get_outline().outline_color)
|
||||||
.to_layout();
|
.to_layout();
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&bounds,
|
bounds,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
|
@ -1407,10 +1389,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
stacking_relative_content_box: &Rect<Au>,
|
stacking_relative_content_box: Rect<Au>,
|
||||||
text_fragment: &ScannedTextFragmentInfo,
|
text_fragment: &ScannedTextFragmentInfo,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// FIXME(pcwalton, #2795): Get the real container size.
|
// FIXME(pcwalton, #2795): Get the real container size.
|
||||||
let container_size = Size2D::zero();
|
let container_size = Size2D::zero();
|
||||||
|
@ -1435,7 +1417,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// Draw a rectangle representing the baselines.
|
// Draw a rectangle representing the baselines.
|
||||||
let mut baseline = LogicalRect::from_physical(
|
let mut baseline = LogicalRect::from_physical(
|
||||||
self.style.writing_mode,
|
self.style.writing_mode,
|
||||||
*stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
container_size,
|
container_size,
|
||||||
);
|
);
|
||||||
baseline.start.b = baseline.start.b + text_fragment.run.ascent();
|
baseline.start.b = baseline.start.b + text_fragment.run.ascent();
|
||||||
|
@ -1443,7 +1425,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let baseline = baseline.to_physical(self.style.writing_mode, container_size);
|
let baseline = baseline.to_physical(self.style.writing_mode, container_size);
|
||||||
|
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&baseline,
|
baseline,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
style.get_cursor(CursorKind::Default),
|
style.get_cursor(CursorKind::Default),
|
||||||
|
@ -1459,8 +1441,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
fn build_debug_borders_around_fragment(
|
fn build_debug_borders_around_fragment(
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// This prints a debug border around the border of this fragment.
|
// This prints a debug border around the border of this fragment.
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
|
@ -1483,9 +1465,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
fn build_display_items_for_selection_if_necessary(
|
fn build_display_items_for_selection_if_necessary(
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
let scanned_text_fragment_info = match self.specific {
|
let scanned_text_fragment_info = match self.specific {
|
||||||
SpecificFragmentInfo::ScannedText(ref scanned_text_fragment_info) => {
|
SpecificFragmentInfo::ScannedText(ref scanned_text_fragment_info) => {
|
||||||
|
@ -1545,7 +1527,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
};
|
};
|
||||||
|
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&insertion_point_bounds,
|
insertion_point_bounds,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
self.style.get_cursor(cursor),
|
self.style.get_cursor(cursor),
|
||||||
|
@ -1563,7 +1545,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
stacking_relative_border_box: Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
|
||||||
self.build_display_list_no_damage(
|
self.build_display_list_no_damage(
|
||||||
|
@ -1581,7 +1563,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
stacking_relative_border_box: Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
border_painting_mode: BorderPaintingMode,
|
border_painting_mode: BorderPaintingMode,
|
||||||
display_list_section: DisplayListSection,
|
display_list_section: DisplayListSection,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
if self.style().get_inheritedbox().visibility != Visibility::Visible {
|
if self.style().get_inheritedbox().visibility != Visibility::Visible {
|
||||||
return;
|
return;
|
||||||
|
@ -1603,14 +1585,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state,
|
state,
|
||||||
&*node.style,
|
&*node.style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.build_display_list_for_box_shadow_if_applicable(
|
self.build_display_list_for_box_shadow_if_applicable(
|
||||||
state,
|
state,
|
||||||
&*node.style,
|
&*node.style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1624,7 +1606,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT),
|
.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT),
|
||||||
}),
|
}),
|
||||||
border_painting_mode,
|
border_painting_mode,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1634,7 +1616,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
self.build_display_list_for_outline_if_applicable(
|
self.build_display_list_for_outline_if_applicable(
|
||||||
state,
|
state,
|
||||||
&*node.style,
|
&*node.style,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1645,14 +1627,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state,
|
state,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.build_display_list_for_box_shadow_if_applicable(
|
self.build_display_list_for_box_shadow_if_applicable(
|
||||||
state,
|
state,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1661,7 +1643,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
&*self.style,
|
&*self.style,
|
||||||
/* inline_node_info = */ None,
|
/* inline_node_info = */ None,
|
||||||
border_painting_mode,
|
border_painting_mode,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1669,7 +1651,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
self.build_display_list_for_outline_if_applicable(
|
self.build_display_list_for_outline_if_applicable(
|
||||||
state,
|
state,
|
||||||
&*self.style,
|
&*self.style,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1680,7 +1662,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// insertion point, so we do this even if `empty_rect` is true.
|
// insertion point, so we do this even if `empty_rect` is true.
|
||||||
self.build_display_items_for_selection_if_necessary(
|
self.build_display_items_for_selection_if_necessary(
|
||||||
state,
|
state,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
display_list_section,
|
display_list_section,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1696,21 +1678,21 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state.clipping_and_scrolling_scope(|state| {
|
state.clipping_and_scrolling_scope(|state| {
|
||||||
self.build_fragment_type_specific_display_items(
|
self.build_fragment_type_specific_display_items(
|
||||||
state,
|
state,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if opts::get().show_debug_fragment_borders {
|
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(
|
fn build_fragment_type_specific_display_items(
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// Compute the context box position relative to the parent stacking context.
|
// Compute the context box position relative to the parent stacking context.
|
||||||
let stacking_relative_content_box =
|
let stacking_relative_content_box =
|
||||||
|
@ -1719,7 +1701,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let create_base_display_item = |state: &mut DisplayListBuildState| {
|
let create_base_display_item = |state: &mut DisplayListBuildState| {
|
||||||
// Adjust the clipping region as necessary to account for `border-radius`.
|
// Adjust the clipping region as necessary to account for `border-radius`.
|
||||||
let radii =
|
let radii =
|
||||||
build_border_radius_for_inner_rect(&stacking_relative_border_box, &self.style);
|
build_border_radius_for_inner_rect(stacking_relative_border_box, &self.style);
|
||||||
|
|
||||||
if !radii.is_zero() {
|
if !radii.is_zero() {
|
||||||
let clip_id =
|
let clip_id =
|
||||||
|
@ -1728,8 +1710,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.create_base_display_item(
|
state.create_base_display_item(
|
||||||
&stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
self.node,
|
self.node,
|
||||||
self.style.get_cursor(CursorKind::Default),
|
self.style.get_cursor(CursorKind::Default),
|
||||||
DisplayListSection::Content,
|
DisplayListSection::Content,
|
||||||
|
@ -1745,7 +1727,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
self.build_display_list_for_text_fragment(
|
self.build_display_list_for_text_fragment(
|
||||||
state,
|
state,
|
||||||
&text_fragment,
|
&text_fragment,
|
||||||
&stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
&self.style.get_inheritedtext().text_shadow.0,
|
&self.style.get_inheritedtext().text_shadow.0,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1755,7 +1737,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state,
|
state,
|
||||||
self.style(),
|
self.style(),
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
&stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
&text_fragment,
|
&text_fragment,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1766,7 +1748,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
self.build_display_list_for_text_fragment(
|
self.build_display_list_for_text_fragment(
|
||||||
state,
|
state,
|
||||||
&text_fragment,
|
&text_fragment,
|
||||||
&stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
&self.style.get_inheritedtext().text_shadow.0,
|
&self.style.get_inheritedtext().text_shadow.0,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1776,7 +1758,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state,
|
state,
|
||||||
self.style(),
|
self.style(),
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
&stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
&text_fragment,
|
&text_fragment,
|
||||||
clip,
|
clip,
|
||||||
);
|
);
|
||||||
|
@ -1854,8 +1836,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let ipc_renderer = ipc_renderer.lock().unwrap();
|
let ipc_renderer = ipc_renderer.lock().unwrap();
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
ipc_renderer
|
ipc_renderer
|
||||||
.send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender),
|
.send(CanvasMsg::FromLayout(
|
||||||
canvas_fragment_info.canvas_id.clone()))
|
FromLayoutMsg::SendData(sender),
|
||||||
|
canvas_fragment_info.canvas_id.clone(),
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
receiver.recv().unwrap().image_key
|
receiver.recv().unwrap().image_key
|
||||||
},
|
},
|
||||||
|
@ -1939,9 +1923,9 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
&self,
|
&self,
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
text_fragment: &ScannedTextFragmentInfo,
|
text_fragment: &ScannedTextFragmentInfo,
|
||||||
stacking_relative_content_box: &Rect<Au>,
|
stacking_relative_content_box: Rect<Au>,
|
||||||
text_shadows: &[SimpleShadow],
|
text_shadows: &[SimpleShadow],
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// NB: The order for painting text components (CSS Text Decoration Module Level 3) is:
|
// NB: The order for painting text components (CSS Text Decoration Module Level 3) is:
|
||||||
// shadows, underline, overline, text, text-emphasis, and then line-through.
|
// shadows, underline, overline, text, text-emphasis, and then line-through.
|
||||||
|
@ -1975,7 +1959,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
// Base item for all text/shadows
|
// Base item for all text/shadows
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
self.style().get_cursor(cursor),
|
self.style().get_cursor(cursor),
|
||||||
|
@ -2007,7 +1991,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
|
|
||||||
let logical_stacking_relative_content_box = LogicalRect::from_physical(
|
let logical_stacking_relative_content_box = LogicalRect::from_physical(
|
||||||
self.style.writing_mode,
|
self.style.writing_mode,
|
||||||
*stacking_relative_content_box,
|
stacking_relative_content_box,
|
||||||
container_size,
|
container_size,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2091,14 +2075,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
state: &mut DisplayListBuildState,
|
state: &mut DisplayListBuildState,
|
||||||
color: &RGBA,
|
color: &RGBA,
|
||||||
stacking_relative_box: &LogicalRect<Au>,
|
stacking_relative_box: &LogicalRect<Au>,
|
||||||
clip: &Rect<Au>,
|
clip: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// FIXME(pcwalton, #2795): Get the real container size.
|
// FIXME(pcwalton, #2795): Get the real container size.
|
||||||
let container_size = Size2D::zero();
|
let container_size = Size2D::zero();
|
||||||
let stacking_relative_box =
|
let stacking_relative_box =
|
||||||
stacking_relative_box.to_physical(self.style.writing_mode, container_size);
|
stacking_relative_box.to_physical(self.style.writing_mode, container_size);
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&stacking_relative_box,
|
stacking_relative_box,
|
||||||
clip,
|
clip,
|
||||||
self.node,
|
self.node,
|
||||||
self.style.get_cursor(CursorKind::Default),
|
self.style.get_cursor(CursorKind::Default),
|
||||||
|
@ -2156,18 +2140,18 @@ pub trait BlockFlowDisplayListBuilding {
|
||||||
fn setup_clip_scroll_node_for_position(
|
fn setup_clip_scroll_node_for_position(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
border_box: &Rect<Au>,
|
border_box: Rect<Au>,
|
||||||
);
|
);
|
||||||
fn setup_clip_scroll_node_for_overflow(
|
fn setup_clip_scroll_node_for_overflow(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
border_box: &Rect<Au>,
|
border_box: Rect<Au>,
|
||||||
);
|
);
|
||||||
fn setup_clip_scroll_node_for_css_clip(
|
fn setup_clip_scroll_node_for_css_clip(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
preserved_state: &mut SavedStackingContextCollectionState,
|
preserved_state: &mut SavedStackingContextCollectionState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
);
|
);
|
||||||
fn create_pseudo_stacking_context_for_block(
|
fn create_pseudo_stacking_context_for_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -2262,10 +2246,9 @@ impl SavedStackingContextCollectionState {
|
||||||
fn push_clip(
|
fn push_clip(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
clip: &Rect<Au>,
|
mut clip: Rect<Au>,
|
||||||
positioning: StylePosition,
|
positioning: StylePosition,
|
||||||
) {
|
) {
|
||||||
let mut clip = *clip;
|
|
||||||
if positioning != StylePosition::Fixed {
|
if positioning != StylePosition::Fixed {
|
||||||
if let Some(old_clip) = state.clip_stack.last() {
|
if let Some(old_clip) = state.clip_stack.last() {
|
||||||
clip = old_clip.intersection(&clip).unwrap_or_else(Rect::zero);
|
clip = old_clip.intersection(&clip).unwrap_or_else(Rect::zero);
|
||||||
|
@ -2302,10 +2285,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
.unwrap_or(LayoutTransform::identity());
|
.unwrap_or(LayoutTransform::identity());
|
||||||
let transform = transform.pre_mul(&perspective).inverse();
|
let transform = transform.pre_mul(&perspective).inverse();
|
||||||
|
|
||||||
let origin = &border_box.origin;
|
let origin = border_box.origin;
|
||||||
let transform_clip = |clip: &Rect<Au>| {
|
let transform_clip = |clip: Rect<Au>| {
|
||||||
if *clip == Rect::max_rect() {
|
if clip == Rect::max_rect() {
|
||||||
return *clip;
|
return clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
match transform {
|
match transform {
|
||||||
|
@ -2339,14 +2322,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(clip) = state.clip_stack.last().cloned() {
|
if let Some(clip) = state.clip_stack.last().cloned() {
|
||||||
state.clip_stack.push(transform_clip(&clip));
|
state.clip_stack.push(transform_clip(clip));
|
||||||
preserved_state.clips_pushed += 1;
|
preserved_state.clips_pushed += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(clip) = state.containing_block_clip_stack.last().cloned() {
|
if let Some(clip) = state.containing_block_clip_stack.last().cloned() {
|
||||||
state
|
state.containing_block_clip_stack.push(transform_clip(clip));
|
||||||
.containing_block_clip_stack
|
|
||||||
.push(transform_clip(&clip));
|
|
||||||
preserved_state.containing_block_clips_pushed += 1;
|
preserved_state.containing_block_clips_pushed += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2423,7 +2404,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
state.containing_block_clipping_and_scrolling
|
state.containing_block_clipping_and_scrolling
|
||||||
},
|
},
|
||||||
StylePosition::Fixed => {
|
StylePosition::Fixed => {
|
||||||
preserved_state.push_clip(state, &Rect::max_rect(), StylePosition::Fixed);
|
preserved_state.push_clip(state, Rect::max_rect(), StylePosition::Fixed);
|
||||||
state.current_clipping_and_scrolling
|
state.current_clipping_and_scrolling
|
||||||
},
|
},
|
||||||
_ => state.current_clipping_and_scrolling,
|
_ => state.current_clipping_and_scrolling,
|
||||||
|
@ -2441,12 +2422,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE) {
|
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_position(state, stacking_relative_border_box);
|
||||||
self.setup_clip_scroll_node_for_overflow(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(
|
self.setup_clip_scroll_node_for_css_clip(
|
||||||
state,
|
state,
|
||||||
preserved_state,
|
preserved_state,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.base.clip = state
|
self.base.clip = state
|
||||||
|
@ -2464,7 +2445,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
self.stacking_relative_border_box(CoordinateSystem::Own)
|
self.stacking_relative_border_box(CoordinateSystem::Own)
|
||||||
};
|
};
|
||||||
state.parent_stacking_relative_content_box =
|
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() {
|
match self.positioning() {
|
||||||
|
@ -2480,7 +2461,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
fn setup_clip_scroll_node_for_position(
|
fn setup_clip_scroll_node_for_position(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
border_box: &Rect<Au>,
|
border_box: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
if self.positioning() != StylePosition::Sticky {
|
if self.positioning() != StylePosition::Sticky {
|
||||||
return;
|
return;
|
||||||
|
@ -2558,13 +2539,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
fn setup_clip_scroll_node_for_overflow(
|
fn setup_clip_scroll_node_for_overflow(
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
border_box: &Rect<Au>,
|
border_box: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
if !self.overflow_style_may_require_clip_scroll_node() {
|
if !self.overflow_style_may_require_clip_scroll_node() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let content_box = self.fragment.stacking_relative_content_box(&border_box);
|
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.width > content_box.size.width ||
|
||||||
self.base.overflow.scroll.size.height > content_box.size.height ||
|
self.base.overflow.scroll.size.height > content_box.size.height ||
|
||||||
|
@ -2591,7 +2572,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
let clip_rect = border_box.inner_rect(border_widths);
|
let clip_rect = border_box.inner_rect(border_widths);
|
||||||
|
|
||||||
let mut clip = ClippingRegion::from_rect(clip_rect.to_layout());
|
let mut clip = ClippingRegion::from_rect(clip_rect.to_layout());
|
||||||
let radii = build_border_radius_for_inner_rect(&border_box, &self.fragment.style);
|
let radii = build_border_radius_for_inner_rect(border_box, &self.fragment.style);
|
||||||
if !radii.is_zero() {
|
if !radii.is_zero() {
|
||||||
clip.intersect_with_rounded_rect(clip_rect.to_layout(), radii)
|
clip.intersect_with_rounded_rect(clip_rect.to_layout(), radii)
|
||||||
}
|
}
|
||||||
|
@ -2619,7 +2600,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
&mut self,
|
&mut self,
|
||||||
state: &mut StackingContextCollectionState,
|
state: &mut StackingContextCollectionState,
|
||||||
preserved_state: &mut SavedStackingContextCollectionState,
|
preserved_state: &mut SavedStackingContextCollectionState,
|
||||||
stacking_relative_border_box: &Rect<Au>,
|
stacking_relative_border_box: Rect<Au>,
|
||||||
) {
|
) {
|
||||||
// Account for `clip` per CSS 2.1 § 11.1.2.
|
// Account for `clip` per CSS 2.1 § 11.1.2.
|
||||||
let style_clip_rect = match self.fragment.style().get_effects().clip {
|
let style_clip_rect = match self.fragment.style().get_effects().clip {
|
||||||
|
@ -2651,7 +2632,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
|
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
|
||||||
|
|
||||||
let clip_rect = Rect::new(clip_origin, clip_size);
|
let clip_rect = Rect::new(clip_origin, clip_size);
|
||||||
preserved_state.push_clip(state, &clip_rect, self.positioning());
|
preserved_state.push_clip(state, clip_rect, self.positioning());
|
||||||
|
|
||||||
let new_index = state.add_clip_scroll_node(ClipScrollNode {
|
let new_index = state.add_clip_scroll_node(ClipScrollNode {
|
||||||
parent_index: self.clipping_and_scrolling().scrolling,
|
parent_index: self.clipping_and_scrolling().scrolling,
|
||||||
|
@ -2738,7 +2719,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
border_painting_mode,
|
border_painting_mode,
|
||||||
background_border_section,
|
background_border_section,
|
||||||
&self.base.clip,
|
self.base.clip,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.base
|
self.base
|
||||||
|
@ -2775,7 +2756,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||||
background,
|
background,
|
||||||
background_color,
|
background_color,
|
||||||
background_border_section,
|
background_border_section,
|
||||||
&stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2878,7 +2859,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
BorderPaintingMode::Separate,
|
BorderPaintingMode::Separate,
|
||||||
DisplayListSection::Content,
|
DisplayListSection::Content,
|
||||||
&self.base.clip,
|
self.base.clip,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2935,7 +2916,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
BorderPaintingMode::Separate,
|
BorderPaintingMode::Separate,
|
||||||
DisplayListSection::Content,
|
DisplayListSection::Content,
|
||||||
&self.block_flow.base.clip,
|
self.block_flow.base.clip,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2984,8 +2965,8 @@ impl BaseFlowDisplayListBuilding for BaseFlow {
|
||||||
let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()];
|
let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()];
|
||||||
color.a = 1.0;
|
color.a = 1.0;
|
||||||
let base = state.create_base_display_item(
|
let base = state.create_base_display_item(
|
||||||
&stacking_context_relative_bounds.inflate(Au::from_px(2), Au::from_px(2)),
|
stacking_context_relative_bounds.inflate(Au::from_px(2), Au::from_px(2)),
|
||||||
&self.clip,
|
self.clip,
|
||||||
node,
|
node,
|
||||||
None,
|
None,
|
||||||
DisplayListSection::Content,
|
DisplayListSection::Content,
|
||||||
|
@ -3016,7 +2997,13 @@ impl ComputedValuesCursorUtility for ComputedValues {
|
||||||
&self.get_inheritedui().cursor,
|
&self.get_inheritedui().cursor,
|
||||||
) {
|
) {
|
||||||
(PointerEvents::None, _) => None,
|
(PointerEvents::None, _) => None,
|
||||||
(PointerEvents::Auto, &Cursor { keyword: CursorKind::Auto, .. }) => Some(default_cursor),
|
(
|
||||||
|
PointerEvents::Auto,
|
||||||
|
&Cursor {
|
||||||
|
keyword: CursorKind::Auto,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
) => Some(default_cursor),
|
||||||
(PointerEvents::Auto, &Cursor { keyword, .. }) => Some(keyword),
|
(PointerEvents::Auto, &Cursor { keyword, .. }) => Some(keyword),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3024,7 +3011,7 @@ impl ComputedValuesCursorUtility for ComputedValues {
|
||||||
|
|
||||||
/// Adjusts `content_rect` as necessary for the given spread, and blur so that the resulting
|
/// Adjusts `content_rect` as necessary for the given spread, and blur so that the resulting
|
||||||
/// bounding rect contains all of a shadow's ink.
|
/// bounding rect contains all of a shadow's ink.
|
||||||
fn shadow_bounds(content_rect: &Rect<Au>, blur: Au, spread: Au) -> Rect<Au> {
|
fn shadow_bounds(content_rect: Rect<Au>, blur: Au, spread: Au) -> Rect<Au> {
|
||||||
let inflation = spread + blur * BLUR_INFLATION_FACTOR;
|
let inflation = spread + blur * BLUR_INFLATION_FACTOR;
|
||||||
content_rect.inflate(inflation, inflation)
|
content_rect.inflate(inflation, inflation)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2465,7 +2465,7 @@ impl Fragment {
|
||||||
|
|
||||||
/// Given the stacking-context-relative border box, returns the stacking-context-relative
|
/// Given the stacking-context-relative border box, returns the stacking-context-relative
|
||||||
/// content box.
|
/// content box.
|
||||||
pub fn stacking_relative_content_box(&self, stacking_relative_border_box: &Rect<Au>)
|
pub fn stacking_relative_content_box(&self, stacking_relative_border_box: Rect<Au>)
|
||||||
-> Rect<Au> {
|
-> Rect<Au> {
|
||||||
let border_padding = self.border_padding.to_physical(self.style.writing_mode);
|
let border_padding = self.border_padding.to_physical(self.style.writing_mode);
|
||||||
Rect::new(Point2D::new(stacking_relative_border_box.origin.x + border_padding.left,
|
Rect::new(Point2D::new(stacking_relative_border_box.origin.x + border_padding.left,
|
||||||
|
|
|
@ -1617,7 +1617,7 @@ impl Flow for InlineFlow {
|
||||||
.relative_containing_block_mode,
|
.relative_containing_block_mode,
|
||||||
CoordinateSystem::Parent);
|
CoordinateSystem::Parent);
|
||||||
let stacking_relative_content_box =
|
let stacking_relative_content_box =
|
||||||
fragment.stacking_relative_content_box(&stacking_relative_border_box);
|
fragment.stacking_relative_content_box(stacking_relative_border_box);
|
||||||
|
|
||||||
let is_positioned = fragment.is_positioned();
|
let is_positioned = fragment.is_positioned();
|
||||||
match fragment.specific {
|
match fragment.specific {
|
||||||
|
|
|
@ -307,6 +307,18 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/background_border_padding_crash.html": [
|
||||||
|
[
|
||||||
|
"/_mozilla/css/background_border_padding_crash.html",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/_mozilla/css/background_border_padding_crash-ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/background_clip_a.html": [
|
"css/background_clip_a.html": [
|
||||||
[
|
[
|
||||||
"/_mozilla/css/background_clip_a.html",
|
"/_mozilla/css/background_clip_a.html",
|
||||||
|
@ -7459,6 +7471,11 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/background_border_padding_crash-ref.html": [
|
||||||
|
[
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/background_clip_ref.html": [
|
"css/background_clip_ref.html": [
|
||||||
[
|
[
|
||||||
{}
|
{}
|
||||||
|
@ -60187,6 +60204,14 @@
|
||||||
"a85620b9a57b3cb46b7629b7a8fead6417d2dd28",
|
"a85620b9a57b3cb46b7629b7a8fead6417d2dd28",
|
||||||
"reftest"
|
"reftest"
|
||||||
],
|
],
|
||||||
|
"css/background_border_padding_crash-ref.html": [
|
||||||
|
"eae17c2be5646f7fa1dc26e5a28a89c527da00e6",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
|
"css/background_border_padding_crash.html": [
|
||||||
|
"600d0c014aabfe13f09dec11757d5d7740a5ba74",
|
||||||
|
"reftest"
|
||||||
|
],
|
||||||
"css/background_clip_a.html": [
|
"css/background_clip_a.html": [
|
||||||
"e2d43d67ea0485e171fc1280498ac68a483e881a",
|
"e2d43d67ea0485e171fc1280498ac68a483e881a",
|
||||||
"reftest"
|
"reftest"
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<title>Assure that different writing modes do not crash background building in Servo</title>
|
||||||
|
<span>Filler Text txeT relliF</span>
|
||||||
|
</html>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<title>Assure that different writing modes do not crash background building in Servo</title>
|
||||||
|
<link rel=match href=background_border_padding_crash-ref.html>
|
||||||
|
<style>
|
||||||
|
#span1 {
|
||||||
|
background-clip: content-box;
|
||||||
|
}
|
||||||
|
#span2
|
||||||
|
{
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<span id="span1">Filler Text <span id="span2">txeT relliF</span></span>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue