From 5eb1472a3389005645d0d2e6346890c4ea93b9f1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 24 Oct 2019 15:04:14 +0200 Subject: [PATCH] 2020: paint borders --- components/layout_2020/display_list.rs | 110 +++++++++++++----- components/style/properties/helpers.mako.rs | 3 +- .../style/properties/longhands/border.mako.rs | 15 ++- .../properties/shorthands/border.mako.rs | 7 +- components/style/values/specified/border.rs | 7 -- 5 files changed, 95 insertions(+), 47 deletions(-) diff --git a/components/layout_2020/display_list.rs b/components/layout_2020/display_list.rs index cd3d3b103db..315c3bbc766 100644 --- a/components/layout_2020/display_list.rs +++ b/components/layout_2020/display_list.rs @@ -6,24 +6,22 @@ use crate::fragments::{BoxFragment, Fragment}; use crate::geom::physical::{Rect, Vec2}; use crate::style_ext::ComputedValuesExt; use app_units::Au; -use style::values::computed::Length; -use webrender_api::CommonItemProperties; +use euclid::{self, SideOffsets2D}; +use style::values::computed::{BorderStyle, Length}; +use webrender_api::{self as wr, units, CommonItemProperties}; pub struct DisplayListBuilder { - pipeline_id: webrender_api::PipelineId, - pub wr: webrender_api::DisplayListBuilder, + pipeline_id: wr::PipelineId, + pub wr: wr::DisplayListBuilder, pub is_contentful: bool, } impl DisplayListBuilder { - pub fn new( - pipeline_id: webrender_api::PipelineId, - viewport_size: webrender_api::units::LayoutSize, - ) -> Self { + pub fn new(pipeline_id: wr::PipelineId, viewport_size: wr::units::LayoutSize) -> Self { Self { pipeline_id, 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, containing_block: &Rect, ) { - let background_color = self - .style - .resolve_color(self.style.clone_background_color()); - if background_color.alpha > 0 { - let clip_rect = self - .border_rect() - .to_physical(self.style.writing_mode(), containing_block) - .translate(&containing_block.top_left) - .into(); - let common = CommonItemProperties { - clip_rect, - clip_id: webrender_api::ClipId::root(builder.pipeline_id), - spatial_id: webrender_api::SpatialId::root_scroll_node(builder.pipeline_id), - hit_info: None, - // TODO(gw): Make use of the WR backface visibility functionality. - is_backface_visible: true, - }; - builder.wr.push_rect(&common, rgba(background_color)) - } + let border_rect = self + .border_rect() + .to_physical(self.style.writing_mode(), containing_block) + .translate(&containing_block.top_left) + .into(); + let common = CommonItemProperties { + clip_rect: border_rect, + clip_id: wr::ClipId::root(builder.pipeline_id), + spatial_id: wr::SpatialId::root_scroll_node(builder.pipeline_id), + hit_info: None, + // TODO(gw): Make use of the WR backface visibility functionality. + is_backface_visible: true, + }; + + self.background_display_items(builder, &common); + self.border_display_items(builder, &common, border_rect); let content_rect = self .content_rect .to_physical(self.style.writing_mode(), containing_block) @@ -94,10 +89,65 @@ impl BoxFragment { 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 { - webrender_api::ColorF::new( +fn rgba(rgba: cssparser::RGBA) -> wr::ColorF { + wr::ColorF::new( rgba.red_f32(), rgba.green_f32(), rgba.blue_f32(), diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 5d9e6f54e8f..4d3895440d5 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -880,7 +880,8 @@ { // Define all of the expected variables that correspond to the shorthand % 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 // Attempt to assign the incoming declarations to the expected variables diff --git a/components/style/properties/longhands/border.mako.rs b/components/style/properties/longhands/border.mako.rs index a77fe4cb5b3..4d68c8bfc93 100644 --- a/components/style/properties/longhands/border.mako.rs +++ b/components/style/properties/longhands/border.mako.rs @@ -107,7 +107,8 @@ ${helpers.single_keyword( ${helpers.predefined_type( "border-image-source", "ImageLayer", - engines="gecko servo-2013", + engines="gecko servo-2013 servo-2020", + servo_2020_pref="layout.2020.unimplemented", initial_value="computed::ImageLayer::none()", initial_specified_value="specified::ImageLayer::none()", spec="https://drafts.csswg.org/css-backgrounds/#the-background-image", @@ -120,7 +121,8 @@ ${helpers.predefined_type( ${helpers.predefined_type( "border-image-outset", "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_specified_value="generics::rect::Rect::all(specified::NonNegativeLengthOrNumber::zero())", spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset", @@ -132,7 +134,8 @@ ${helpers.predefined_type( "border-image-repeat", "BorderImageRepeat", "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()", animation_value_type="discrete", spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat", @@ -141,7 +144,8 @@ ${helpers.predefined_type( ${helpers.predefined_type( "border-image-width", "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_specified_value="specified::BorderImageWidth::all(specified::BorderImageSideWidth::one())", spec="https://drafts.csswg.org/css-backgrounds/#border-image-width", @@ -152,7 +156,8 @@ ${helpers.predefined_type( ${helpers.predefined_type( "border-image-slice", "BorderImageSlice", - engines="gecko servo-2013", + engines="gecko servo-2013 servo-2020", + servo_2020_pref="layout.2020.unimplemented", initial_value="computed::BorderImageSlice::hundred_percent()", initial_specified_value="specified::BorderImageSlice::hundred_percent()", spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice", diff --git a/components/style/properties/shorthands/border.mako.rs b/components/style/properties/shorthands/border.mako.rs index 4f1c381c732..c1bf200fe45 100644 --- a/components/style/properties/shorthands/border.mako.rs +++ b/components/style/properties/shorthands/border.mako.rs @@ -111,7 +111,6 @@ pub fn parse_border<'i, 't>( <%helpers:shorthand name="border-${side}" engines="gecko servo-2013 servo-2020" - servo_2020_pref="layout.2020.unimplemented" sub_properties="${' '.join( 'border-%s-%s' % (side, prop) for prop in ['color', 'style', 'width'] @@ -146,7 +145,7 @@ pub fn parse_border<'i, 't>( % endfor <%helpers:shorthand name="border" - engines="gecko servo-2013" + engines="gecko servo-2013 servo-2020" sub_properties="${' '.join('border-%s-%s' % (side, prop) for side in PHYSICAL_SIDES 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) %> <%helpers:shorthand - engines="gecko servo-2013" + engines="gecko servo-2013 servo-2020" name="border-${axis}-${prop}" sub_properties="${' '.join( 'border-%s-%s-%s' % (axis, side, prop) @@ -430,7 +429,7 @@ pub fn parse_border<'i, 't>( %> <%helpers:shorthand name="border-${axis}" - engines="gecko servo-2013" + engines="gecko servo-2013 servo-2020" sub_properties="${' '.join( 'border-%s-%s-width' % (axis, side) for side in ['start', 'end'] diff --git a/components/style/values/specified/border.rs b/components/style/values/specified/border.rs index 375700809d1..1b1ed74d568 100644 --- a/components/style/values/specified/border.rs +++ b/components/style/values/specified/border.rs @@ -47,20 +47,13 @@ use style_traits::{CssWriter, ParseError, ToCss}; pub enum BorderStyle { Hidden, None, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Inset, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Groove, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Outset, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Ridge, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Dotted, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Dashed, Solid, - #[cfg(any(feature = "gecko", feature = "servo-layout-2013"))] Double, }