diff --git a/webrender/src/border.rs b/webrender/src/border.rs index b35bd69243..fec6f3c02d 100644 --- a/webrender/src/border.rs +++ b/webrender/src/border.rs @@ -10,7 +10,7 @@ use ellipse::Ellipse; use display_list_flattener::DisplayListFlattener; use gpu_types::{BorderInstance, BorderSegment, BrushFlags}; use prim_store::{BrushKind, BrushPrimitive, BrushSegment}; -use prim_store::{BorderSource, EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain}; +use prim_store::{EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain}; use util::{lerp, RectHelpers}; // Using 2048 as the maximum radius in device space before which we @@ -116,6 +116,20 @@ pub struct BorderCacheKey { pub scale: Au, } +impl BorderCacheKey { + pub fn new(border: &NormalBorder, widths: &BorderWidths) -> Self { + BorderCacheKey { + left: border.left.into(), + top: border.top.into(), + right: border.right.into(), + bottom: border.bottom.into(), + widths: (*widths).into(), + radius: border.radius.into(), + scale: Au::from_f32_px(0.0), + } + } +} + pub fn ensure_no_corner_overlap( radius: &mut BorderRadius, rect: &LayoutRect, @@ -173,23 +187,7 @@ impl<'a> DisplayListFlattener<'a> { ensure_no_corner_overlap(&mut border.radius, &info.rect); let prim = BrushPrimitive::new( - BrushKind::Border { - source: BorderSource::Border { - border, - widths: *widths, - cache_key: BorderCacheKey { - left: border.left.into(), - top: border.top.into(), - right: border.right.into(), - bottom: border.bottom.into(), - widths: (*widths).into(), - radius: border.radius.into(), - scale: Au::from_f32_px(0.0), - }, - task_info: None, - handle: None, - }, - }, + BrushKind::new_border(border, *widths), None, ); diff --git a/webrender/src/prim_store.rs b/webrender/src/prim_store.rs index c5826e081e..701b954526 100644 --- a/webrender/src/prim_store.rs +++ b/webrender/src/prim_store.rs @@ -420,6 +420,41 @@ impl BrushKind { opacity_binding: OpacityBinding::new(), } } + + // Construct a brush that is a border with `border` style and `widths` + // dimensions. + pub fn new_border(border: NormalBorder, widths: BorderWidths) -> BrushKind { + let cache_key = BorderCacheKey::new(&border, &widths); + BrushKind::Border { + source: BorderSource::Border { + border, + widths, + cache_key, + task_info: None, + handle: None, + } + } + } + + // Construct a brush that is an image wisth `stretch_size` dimensions and + // `color`. + pub fn new_image( + request: ImageRequest, + stretch_size: LayoutSize, + color: ColorF + ) -> BrushKind { + BrushKind::Image { + request, + alpha_type: AlphaType::PremultipliedAlpha, + stretch_size, + tile_spacing: LayoutSize::new(0., 0.), + color, + source: ImageSource::Default, + sub_rect: None, + opacity_binding: OpacityBinding::new(), + visible_tiles: Vec::new(), + } + } } bitflags! { @@ -1242,11 +1277,35 @@ impl PrimitiveContainer { None, )) } + BrushKind::Border { ref source } => { + let source = match *source { + BorderSource::Image(request) => { + BrushKind::Border { + source: BorderSource::Image(request) + } + }, + BorderSource::Border { border, widths, .. } => { + let border = border.with_color(shadow.color); + BrushKind::new_border(border, widths) + + } + }; + PrimitiveContainer::Brush(BrushPrimitive::new( + source, + None, + )) + } + BrushKind::Image { request, stretch_size, .. } => { + PrimitiveContainer::Brush(BrushPrimitive::new( + BrushKind::new_image(request.clone(), + stretch_size.clone(), + shadow.color), + None, + )) + } BrushKind::Clear | BrushKind::Picture { .. } | - BrushKind::Image { .. } | BrushKind::YuvImage { .. } | - BrushKind::Border { .. } | BrushKind::RadialGradient { .. } | BrushKind::LinearGradient { .. } => { panic!("bug: other brush kinds not expected here yet"); diff --git a/webrender_api/src/display_item.rs b/webrender_api/src/display_item.rs index 9759be2dfc..040e6f64ee 100644 --- a/webrender_api/src/display_item.rs +++ b/webrender_api/src/display_item.rs @@ -263,6 +263,18 @@ pub struct NormalBorder { pub radius: BorderRadius, } +impl NormalBorder { + // Construct a border based upon self with color + pub fn with_color(&self, color: ColorF) -> Self { + let mut b = *self; + b.left.color = color; + b.right.color = color; + b.top.color = color; + b.bottom.color = color; + b + } +} + #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] pub enum RepeatMode { diff --git a/wrench/reftests/text/reftest.list b/wrench/reftests/text/reftest.list index 54b2f411aa..a730275107 100644 --- a/wrench/reftests/text/reftest.list +++ b/wrench/reftests/text/reftest.list @@ -63,3 +63,5 @@ fuzzy(1,71) platform(linux) == raster-space.yaml raster-space.png == bg-color.yaml bg-color-ref.yaml != large-glyphs.yaml blank.yaml == snap-text-offset.yaml snap-text-offset-ref.yaml +== shadow-border.yaml shadow-solid-ref.yaml +== shadow-image.yaml shadow-solid-ref.yaml diff --git a/wrench/reftests/text/shadow-border.yaml b/wrench/reftests/text/shadow-border.yaml new file mode 100644 index 0000000000..b05fb88cb5 --- /dev/null +++ b/wrench/reftests/text/shadow-border.yaml @@ -0,0 +1,19 @@ +--- +root: + items: + - + type: "shadow" + blur-radius: 25 + bounds: [0, 0, 90, 90] + offset: [0, 0] + color: [0, 0, 0, 0.8] + - + type: border + bounds: [ 30, 30, 30, 30 ] + width: [ 15, 15, 15, 15 ] + border-type: normal + style: solid + color: blue + radius: 0 + - + type: "pop-all-shadows" diff --git a/wrench/reftests/text/shadow-image.yaml b/wrench/reftests/text/shadow-image.yaml new file mode 100644 index 0000000000..4d472aadc4 --- /dev/null +++ b/wrench/reftests/text/shadow-image.yaml @@ -0,0 +1,14 @@ +--- +root: + items: + - + type: "shadow" + blur-radius: 25 + bounds: [0, 0, 90, 90] + offset: [0, 0] + color: [0, 0, 0, 0.8] + - + bounds: [ 30, 30, 30, 30 ] + image: solid-color(0, 0, 255, 255, 30, 30) + - + type: "pop-all-shadows" diff --git a/wrench/reftests/text/shadow-solid-ref.yaml b/wrench/reftests/text/shadow-solid-ref.yaml new file mode 100644 index 0000000000..264b1e1096 --- /dev/null +++ b/wrench/reftests/text/shadow-solid-ref.yaml @@ -0,0 +1,16 @@ +--- +root: + items: + - + type: "shadow" + blur-radius: 25 + bounds: [0, 0, 90, 90] + offset: [0, 0] + color: [0, 0, 0, 0.8] + - + bounds: [30, 30, 30, 30] + type: rect + style: solid + color: blue + - + type: "pop-all-shadows"