mirror of
https://github.com/servo/servo.git
synced 2025-07-04 05:53:39 +01:00
Auto merge of #20739 - pyfisch:border-image-outset, r=mbrubeck
Implement border-image-outset Add an automatic test for border-image-outset with a gradient. Convert two tests from UTF-8 LE with CRLF line endings to UTF-8 with LF endings as the old files could not be viewed with servo. Closes #16638 <!-- 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/20739) <!-- Reviewable:end -->
This commit is contained in:
commit
eda59780e9
8 changed files with 119 additions and 19 deletions
|
@ -19,9 +19,11 @@ use model::{self, MaybeAuto};
|
||||||
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
|
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
|
||||||
use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
use style::computed_values::background_clip::single_value::T as BackgroundClip;
|
||||||
use style::computed_values::background_origin::single_value::T as BackgroundOrigin;
|
use style::computed_values::background_origin::single_value::T as BackgroundOrigin;
|
||||||
|
use style::computed_values::border_image_outset::T as BorderImageOutset;
|
||||||
use style::properties::style_structs::{self, Background};
|
use style::properties::style_structs::{self, Background};
|
||||||
|
use style::values::Either;
|
||||||
use style::values::computed::{Angle, GradientItem};
|
use style::values::computed::{Angle, GradientItem};
|
||||||
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
use style::values::computed::{LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||||
use style::values::computed::{NumberOrPercentage, Percentage, Position};
|
use style::values::computed::{NumberOrPercentage, Percentage, Position};
|
||||||
use style::values::computed::image::{EndingShape, LineDirection};
|
use style::values::computed::image::{EndingShape, LineDirection};
|
||||||
use style::values::generics::background::BackgroundSize;
|
use style::values::generics::background::BackgroundSize;
|
||||||
|
@ -784,6 +786,7 @@ pub fn calculate_inner_border_radii(
|
||||||
pub fn build_image_border_details(
|
pub fn build_image_border_details(
|
||||||
webrender_image: WebRenderImageInfo,
|
webrender_image: WebRenderImageInfo,
|
||||||
border_style_struct: &style_structs::Border,
|
border_style_struct: &style_structs::Border,
|
||||||
|
outset: SideOffsets2D<f32>,
|
||||||
) -> Option<BorderDetails> {
|
) -> Option<BorderDetails> {
|
||||||
let corners = &border_style_struct.border_image_slice.offsets;
|
let corners = &border_style_struct.border_image_slice.offsets;
|
||||||
let border_image_repeat = &border_style_struct.border_image_repeat;
|
let border_image_repeat = &border_style_struct.border_image_repeat;
|
||||||
|
@ -801,8 +804,7 @@ pub fn build_image_border_details(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
fill: border_style_struct.border_image_slice.fill,
|
fill: border_style_struct.border_image_slice.fill,
|
||||||
// TODO(gw): Support border-image-outset
|
outset: outset,
|
||||||
outset: SideOffsets2D::zero(),
|
|
||||||
repeat_horizontal: border_image_repeat.0.to_layout(),
|
repeat_horizontal: border_image_repeat.0.to_layout(),
|
||||||
repeat_vertical: border_image_repeat.1.to_layout(),
|
repeat_vertical: border_image_repeat.1.to_layout(),
|
||||||
}))
|
}))
|
||||||
|
@ -810,3 +812,25 @@ pub fn build_image_border_details(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_border_image_outset_side(
|
||||||
|
outset: LengthOrNumber,
|
||||||
|
border_width: Au,
|
||||||
|
) -> Au {
|
||||||
|
match outset {
|
||||||
|
Either::First(length) => length.into(),
|
||||||
|
Either::Second(factor) => border_width.scale_by(factor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calculate_border_image_outset(
|
||||||
|
outset: BorderImageOutset,
|
||||||
|
border: SideOffsets2D<Au>,
|
||||||
|
) -> SideOffsets2D<Au> {
|
||||||
|
SideOffsets2D::new(
|
||||||
|
calculate_border_image_outset_side(outset.0, border.top),
|
||||||
|
calculate_border_image_outset_side(outset.1, border.right),
|
||||||
|
calculate_border_image_outset_side(outset.2, border.bottom),
|
||||||
|
calculate_border_image_outset_side(outset.3, border.left),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@ use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg};
|
||||||
use context::LayoutContext;
|
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_inner_border_radii, compute_background_placement};
|
use display_list::background::{calculate_border_image_outset, calculate_inner_border_radii};
|
||||||
use display_list::background::{convert_linear_gradient, convert_radial_gradient};
|
use display_list::background::{compute_background_placement, convert_linear_gradient};
|
||||||
use display_list::background::{get_cyclic, simple_normal_border};
|
use display_list::background::{convert_radial_gradient, get_cyclic, 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};
|
||||||
|
@ -1264,6 +1264,18 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
);
|
);
|
||||||
|
|
||||||
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 outset = calculate_border_image_outset(
|
||||||
|
border_style_struct.border_image_outset,
|
||||||
|
border_widths
|
||||||
|
);
|
||||||
|
let outset_layout = SideOffsets2D::new(
|
||||||
|
outset.top.to_f32_px(),
|
||||||
|
outset.right.to_f32_px(),
|
||||||
|
outset.bottom.to_f32_px(),
|
||||||
|
outset.left.to_f32_px(),
|
||||||
|
);
|
||||||
|
let size = bounds.outer_rect(outset).size;
|
||||||
|
|
||||||
let details = match border_style_struct.border_image_source {
|
let details = match border_style_struct.border_image_source {
|
||||||
Either::First(_) => Some(BorderDetails::Normal(NormalBorder {
|
Either::First(_) => Some(BorderDetails::Normal(NormalBorder {
|
||||||
|
@ -1295,8 +1307,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
angle_or_corner,
|
angle_or_corner,
|
||||||
gradient.repeating,
|
gradient.repeating,
|
||||||
),
|
),
|
||||||
// TODO(gw): Support border-image-outset
|
outset: outset_layout,
|
||||||
outset: SideOffsets2D::zero(),
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
GradientKind::Radial(shape, center, _angle) => {
|
GradientKind::Radial(shape, center, _angle) => {
|
||||||
|
@ -1308,17 +1319,14 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
center,
|
center,
|
||||||
gradient.repeating,
|
gradient.repeating,
|
||||||
),
|
),
|
||||||
// TODO(gw): Support border-image-outset
|
outset: outset_layout,
|
||||||
outset: SideOffsets2D::zero(),
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
Either::Second(Image::PaintWorklet(ref paint_worklet)) => {
|
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);
|
|
||||||
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))
|
.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`.
|
||||||
|
@ -1337,12 +1345,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
UsePlaceholder::No,
|
UsePlaceholder::No,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|image| build_image_border_details(image, border_style_struct)),
|
.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 {
|
||||||
base,
|
base,
|
||||||
border_widths: border.to_physical(style.writing_mode).to_layout(),
|
border_widths: border_widths.to_layout(),
|
||||||
details,
|
details,
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
|
@ -103651,6 +103651,18 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/border-image-outset-003.html": [
|
||||||
|
[
|
||||||
|
"/css/css-backgrounds/border-image-outset-003.html",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/css-backgrounds/border-image-outset-003-ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/css-backgrounds/border-image-repeat-round.html": [
|
"css/css-backgrounds/border-image-repeat-round.html": [
|
||||||
[
|
[
|
||||||
"/css/css-backgrounds/border-image-repeat-round.html",
|
"/css/css-backgrounds/border-image-repeat-round.html",
|
||||||
|
@ -238780,6 +238792,11 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/border-image-outset-003-ref.html": [
|
||||||
|
[
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"css/css-backgrounds/border-radius-001-ref.xht": [
|
"css/css-backgrounds/border-radius-001-ref.xht": [
|
||||||
[
|
[
|
||||||
{}
|
{}
|
||||||
|
@ -490958,13 +490975,21 @@
|
||||||
"visual"
|
"visual"
|
||||||
],
|
],
|
||||||
"css/css-backgrounds/border-image-outset-001.htm": [
|
"css/css-backgrounds/border-image-outset-001.htm": [
|
||||||
"91206118ea44913c07090d59a2a702b8ba3fb6ef",
|
"796f739d337c442e64c13ffedc25b38c017ac48d",
|
||||||
"visual"
|
"visual"
|
||||||
],
|
],
|
||||||
"css/css-backgrounds/border-image-outset-002.htm": [
|
"css/css-backgrounds/border-image-outset-002.htm": [
|
||||||
"6101a51156146dec7d46599f7b8dc34934d9ea2f",
|
"9e79efb85575ddc330b69a13265a44bc18723dbd",
|
||||||
"visual"
|
"visual"
|
||||||
],
|
],
|
||||||
|
"css/css-backgrounds/border-image-outset-003-ref.html": [
|
||||||
|
"2679f735e348a77aecd49a1f35794e9fc3a9dd87",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
|
"css/css-backgrounds/border-image-outset-003.html": [
|
||||||
|
"378c9808884010c2e0b0226552b519f3ab4cedce",
|
||||||
|
"reftest"
|
||||||
|
],
|
||||||
"css/css-backgrounds/border-image-repeat-001.htm": [
|
"css/css-backgrounds/border-image-repeat-001.htm": [
|
||||||
"62ebca7169dbd69684405ec03f86d720fc3354b7",
|
"62ebca7169dbd69684405ec03f86d720fc3354b7",
|
||||||
"visual"
|
"visual"
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[background-size-025.html]
|
|
||||||
expected: FAIL
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,23 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Blue Box with Green Frame</title>
|
||||||
|
<style>
|
||||||
|
#a {
|
||||||
|
width: 300px;
|
||||||
|
height: 200px;
|
||||||
|
position: absolute;
|
||||||
|
left: 100px;
|
||||||
|
top: 100px;
|
||||||
|
border-width: 50px;
|
||||||
|
border-style: solid;
|
||||||
|
border-image: linear-gradient(green, green);
|
||||||
|
background-color: blue;
|
||||||
|
background-clip: content-box;
|
||||||
|
border-image-slice: 33%;
|
||||||
|
padding-left: 100px;
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="a"></div>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Background Image Outset</title>
|
||||||
|
<link rel="match" href="border-image-outset-003-ref.html">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#border-image-outset" />
|
||||||
|
<style>
|
||||||
|
#a {
|
||||||
|
width: 300px;
|
||||||
|
height: 200px;
|
||||||
|
position: absolute;
|
||||||
|
left: 200px;
|
||||||
|
top: 150px;
|
||||||
|
border-width: 50px;
|
||||||
|
border-style: solid;
|
||||||
|
border-image: linear-gradient(green, green);
|
||||||
|
background-color: blue;
|
||||||
|
background-clip: content-box;
|
||||||
|
border-image-outset: 50px 10px 50px 100px;
|
||||||
|
border-image-slice: 33%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="a"></div>
|
Loading…
Add table
Add a link
Reference in a new issue