2020: paint borders

This commit is contained in:
Simon Sapin 2019-10-24 15:04:14 +02:00
parent 59f68525c4
commit 5eb1472a33
5 changed files with 95 additions and 47 deletions

View file

@ -6,24 +6,22 @@ use crate::fragments::{BoxFragment, Fragment};
use crate::geom::physical::{Rect, Vec2}; use crate::geom::physical::{Rect, Vec2};
use crate::style_ext::ComputedValuesExt; use crate::style_ext::ComputedValuesExt;
use app_units::Au; use app_units::Au;
use style::values::computed::Length; use euclid::{self, SideOffsets2D};
use webrender_api::CommonItemProperties; use style::values::computed::{BorderStyle, Length};
use webrender_api::{self as wr, units, CommonItemProperties};
pub struct DisplayListBuilder { pub struct DisplayListBuilder {
pipeline_id: webrender_api::PipelineId, pipeline_id: wr::PipelineId,
pub wr: webrender_api::DisplayListBuilder, pub wr: wr::DisplayListBuilder,
pub is_contentful: bool, pub is_contentful: bool,
} }
impl DisplayListBuilder { impl DisplayListBuilder {
pub fn new( pub fn new(pipeline_id: wr::PipelineId, viewport_size: wr::units::LayoutSize) -> Self {
pipeline_id: webrender_api::PipelineId,
viewport_size: webrender_api::units::LayoutSize,
) -> Self {
Self { Self {
pipeline_id, pipeline_id,
is_contentful: false, is_contentful: false,
wr: webrender_api::DisplayListBuilder::new(pipeline_id, viewport_size), wr: wr::DisplayListBuilder::new(pipeline_id, viewport_size),
} }
} }
} }
@ -67,25 +65,22 @@ impl BoxFragment {
is_contentful: &mut IsContentful, is_contentful: &mut IsContentful,
containing_block: &Rect<Length>, containing_block: &Rect<Length>,
) { ) {
let background_color = self let border_rect = self
.style .border_rect()
.resolve_color(self.style.clone_background_color()); .to_physical(self.style.writing_mode(), containing_block)
if background_color.alpha > 0 { .translate(&containing_block.top_left)
let clip_rect = self .into();
.border_rect() let common = CommonItemProperties {
.to_physical(self.style.writing_mode(), containing_block) clip_rect: border_rect,
.translate(&containing_block.top_left) clip_id: wr::ClipId::root(builder.pipeline_id),
.into(); spatial_id: wr::SpatialId::root_scroll_node(builder.pipeline_id),
let common = CommonItemProperties { hit_info: None,
clip_rect, // TODO(gw): Make use of the WR backface visibility functionality.
clip_id: webrender_api::ClipId::root(builder.pipeline_id), is_backface_visible: true,
spatial_id: webrender_api::SpatialId::root_scroll_node(builder.pipeline_id), };
hit_info: None,
// TODO(gw): Make use of the WR backface visibility functionality. self.background_display_items(builder, &common);
is_backface_visible: true, self.border_display_items(builder, &common, border_rect);
};
builder.wr.push_rect(&common, rgba(background_color))
}
let content_rect = self let content_rect = self
.content_rect .content_rect
.to_physical(self.style.writing_mode(), containing_block) .to_physical(self.style.writing_mode(), containing_block)
@ -94,10 +89,65 @@ impl BoxFragment {
child.build_display_list(builder, is_contentful, &content_rect) child.build_display_list(builder, is_contentful, &content_rect)
} }
} }
fn background_display_items(
&self,
builder: &mut DisplayListBuilder,
common: &CommonItemProperties,
) {
let background_color = self
.style
.resolve_color(self.style.clone_background_color());
if background_color.alpha > 0 {
builder.wr.push_rect(common, rgba(background_color))
}
}
fn border_display_items(
&self,
builder: &mut DisplayListBuilder,
common: &CommonItemProperties,
border_rect: units::LayoutRect,
) {
let b = self.style.get_border();
let widths = SideOffsets2D::new(
b.border_top_width.px(),
b.border_right_width.px(),
b.border_bottom_width.px(),
b.border_left_width.px(),
);
if widths == SideOffsets2D::zero() {
return;
}
let side = |style, color| wr::BorderSide {
color: rgba(self.style.resolve_color(color)),
style: match style {
BorderStyle::None => wr::BorderStyle::None,
BorderStyle::Solid => wr::BorderStyle::Solid,
BorderStyle::Double => wr::BorderStyle::Double,
BorderStyle::Dotted => wr::BorderStyle::Dotted,
BorderStyle::Dashed => wr::BorderStyle::Dashed,
BorderStyle::Hidden => wr::BorderStyle::Hidden,
BorderStyle::Groove => wr::BorderStyle::Groove,
BorderStyle::Ridge => wr::BorderStyle::Ridge,
BorderStyle::Inset => wr::BorderStyle::Inset,
BorderStyle::Outset => wr::BorderStyle::Outset,
},
};
let details = wr::BorderDetails::Normal(wr::NormalBorder {
top: side(b.border_top_style, b.border_top_color),
right: side(b.border_right_style, b.border_right_color),
bottom: side(b.border_bottom_style, b.border_bottom_color),
left: side(b.border_left_style, b.border_left_color),
radius: wr::BorderRadius::zero(),
do_aa: true,
});
builder.wr.push_border(common, border_rect, widths, details)
}
} }
fn rgba(rgba: cssparser::RGBA) -> webrender_api::ColorF { fn rgba(rgba: cssparser::RGBA) -> wr::ColorF {
webrender_api::ColorF::new( wr::ColorF::new(
rgba.red_f32(), rgba.red_f32(),
rgba.green_f32(), rgba.green_f32(),
rgba.blue_f32(), rgba.blue_f32(),

View file

@ -880,7 +880,8 @@
{ {
// Define all of the expected variables that correspond to the shorthand // Define all of the expected variables that correspond to the shorthand
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
let mut ${sub_property.ident} = None; let mut ${sub_property.ident} =
None::< &'a longhands::${sub_property.ident}::SpecifiedValue>;
% endfor % endfor
// Attempt to assign the incoming declarations to the expected variables // Attempt to assign the incoming declarations to the expected variables

View file

@ -107,7 +107,8 @@ ${helpers.single_keyword(
${helpers.predefined_type( ${helpers.predefined_type(
"border-image-source", "border-image-source",
"ImageLayer", "ImageLayer",
engines="gecko servo-2013", engines="gecko servo-2013 servo-2020",
servo_2020_pref="layout.2020.unimplemented",
initial_value="computed::ImageLayer::none()", initial_value="computed::ImageLayer::none()",
initial_specified_value="specified::ImageLayer::none()", initial_specified_value="specified::ImageLayer::none()",
spec="https://drafts.csswg.org/css-backgrounds/#the-background-image", spec="https://drafts.csswg.org/css-backgrounds/#the-background-image",
@ -120,7 +121,8 @@ ${helpers.predefined_type(
${helpers.predefined_type( ${helpers.predefined_type(
"border-image-outset", "border-image-outset",
"NonNegativeLengthOrNumberRect", "NonNegativeLengthOrNumberRect",
engines="gecko servo-2013", engines="gecko servo-2013 servo-2020",
servo_2020_pref="layout.2020.unimplemented",
initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())", initial_value="generics::rect::Rect::all(computed::NonNegativeLengthOrNumber::zero())",
initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())", initial_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset", spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset",
@ -132,7 +134,8 @@ ${helpers.predefined_type(
"border-image-repeat", "border-image-repeat",
"BorderImageRepeat", "BorderImageRepeat",
"computed::BorderImageRepeat::stretch()", "computed::BorderImageRepeat::stretch()",
engines="gecko servo-2013", engines="gecko servo-2013 servo-2020",
servo_2020_pref="layout.2020.unimplemented",
initial_specified_value="specified::BorderImageRepeat::stretch()", initial_specified_value="specified::BorderImageRepeat::stretch()",
animation_value_type="discrete", animation_value_type="discrete",
spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat", spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat",
@ -141,7 +144,8 @@ ${helpers.predefined_type(
${helpers.predefined_type( ${helpers.predefined_type(
"border-image-width", "border-image-width",
"BorderImageWidth", "BorderImageWidth",
engines="gecko servo-2013", engines="gecko servo-2013 servo-2020",
servo_2020_pref="layout.2020.unimplemented",
initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())", initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())",
initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())", initial_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-width", spec="https://drafts.csswg.org/css-backgrounds/#border-image-width",
@ -152,7 +156,8 @@ ${helpers.predefined_type(
${helpers.predefined_type( ${helpers.predefined_type(
"border-image-slice", "border-image-slice",
"BorderImageSlice", "BorderImageSlice",
engines="gecko servo-2013", engines="gecko servo-2013 servo-2020",
servo_2020_pref="layout.2020.unimplemented",
initial_value="computed::BorderImageSlice::hundred_percent()", initial_value="computed::BorderImageSlice::hundred_percent()",
initial_specified_value="specified::BorderImageSlice::hundred_percent()", initial_specified_value="specified::BorderImageSlice::hundred_percent()",
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice", spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",

View file

@ -111,7 +111,6 @@ pub fn parse_border<'i, 't>(
<%helpers:shorthand <%helpers:shorthand
name="border-${side}" name="border-${side}"
engines="gecko servo-2013 servo-2020" engines="gecko servo-2013 servo-2020"
servo_2020_pref="layout.2020.unimplemented"
sub_properties="${' '.join( sub_properties="${' '.join(
'border-%s-%s' % (side, prop) 'border-%s-%s' % (side, prop)
for prop in ['color', 'style', 'width'] for prop in ['color', 'style', 'width']
@ -146,7 +145,7 @@ pub fn parse_border<'i, 't>(
% endfor % endfor
<%helpers:shorthand name="border" <%helpers:shorthand name="border"
engines="gecko servo-2013" engines="gecko servo-2013 servo-2020"
sub_properties="${' '.join('border-%s-%s' % (side, prop) sub_properties="${' '.join('border-%s-%s' % (side, prop)
for side in PHYSICAL_SIDES for side in PHYSICAL_SIDES
for prop in ['color', 'style', 'width'])} for prop in ['color', 'style', 'width'])}
@ -384,7 +383,7 @@ pub fn parse_border<'i, 't>(
spec = "https://drafts.csswg.org/css-logical/#propdef-border-%s-%s" % (axis, prop) spec = "https://drafts.csswg.org/css-logical/#propdef-border-%s-%s" % (axis, prop)
%> %>
<%helpers:shorthand <%helpers:shorthand
engines="gecko servo-2013" engines="gecko servo-2013 servo-2020"
name="border-${axis}-${prop}" name="border-${axis}-${prop}"
sub_properties="${' '.join( sub_properties="${' '.join(
'border-%s-%s-%s' % (axis, side, prop) 'border-%s-%s-%s' % (axis, side, prop)
@ -430,7 +429,7 @@ pub fn parse_border<'i, 't>(
%> %>
<%helpers:shorthand <%helpers:shorthand
name="border-${axis}" name="border-${axis}"
engines="gecko servo-2013" engines="gecko servo-2013 servo-2020"
sub_properties="${' '.join( sub_properties="${' '.join(
'border-%s-%s-width' % (axis, side) 'border-%s-%s-width' % (axis, side)
for side in ['start', 'end'] for side in ['start', 'end']

View file

@ -47,20 +47,13 @@ use style_traits::{CssWriter, ParseError, ToCss};
pub enum BorderStyle { pub enum BorderStyle {
Hidden, Hidden,
None, None,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Inset, Inset,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Groove, Groove,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Outset, Outset,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Ridge, Ridge,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Dotted, Dotted,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Dashed, Dashed,
Solid, Solid,
#[cfg(any(feature = "gecko", feature = "servo-layout-2013"))]
Double, Double,
} }