Implement radial gradients for borders.

The property border-image-outset is not yet implemented.
Note: Also support repeating-linear-gradients for borders.
This commit is contained in:
Pyfisch 2017-04-30 22:36:45 +02:00
parent a956e3fd52
commit b230be8aaf
3 changed files with 50 additions and 3 deletions

View file

@ -976,12 +976,23 @@ pub struct GradientBorder {
pub outset: SideOffsets2D<f32>, pub outset: SideOffsets2D<f32>,
} }
/// A border that is made of radial gradient
#[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
pub struct RadialGradientBorder {
/// The gradient info that this border uses, border-image-source.
pub gradient: RadialGradient,
/// Outsets for the border, as per border-image-outset.
pub outset: SideOffsets2D<f32>,
}
/// Specifies the type of border /// Specifies the type of border
#[derive(Clone, HeapSizeOf, Deserialize, Serialize)] #[derive(Clone, HeapSizeOf, Deserialize, Serialize)]
pub enum BorderDetails { pub enum BorderDetails {
Normal(NormalBorder), Normal(NormalBorder),
Image(ImageBorder), Image(ImageBorder),
Gradient(GradientBorder), Gradient(GradientBorder),
RadialGradient(RadialGradientBorder),
} }
/// Paints a border. /// Paints a border.

View file

@ -1334,8 +1334,24 @@ impl FragmentDisplayListBuilding for Fragment {
}), }),
})); }));
} }
GradientKind::Radial(_, _) => { GradientKind::Radial(ref shape, ref center) => {
// TODO(#16638): Handle border-image with radial gradient. let grad = self.convert_radial_gradient(&bounds,
&gradient.items[..],
shape,
center,
gradient.repeating,
style);
state.add_display_item(DisplayItem::Border(box BorderDisplayItem {
base: base,
border_widths: border.to_physical(style.writing_mode),
details: BorderDetails::RadialGradient(
display_list::RadialGradientBorder {
gradient: grad,
// TODO(gw): Support border-image-outset
outset: SideOffsets2D::zero(),
}),
}));
} }
} }
} }

View file

@ -352,12 +352,32 @@ impl WebRenderDisplayItemConverter for DisplayItem {
} }
} }
BorderDetails::Gradient(ref gradient) => { BorderDetails::Gradient(ref gradient) => {
let extend_mode = if gradient.gradient.repeating {
ExtendMode::Repeat
} else {
ExtendMode::Clamp
};
webrender_traits::BorderDetails::Gradient(webrender_traits::GradientBorder { webrender_traits::BorderDetails::Gradient(webrender_traits::GradientBorder {
gradient: builder.create_gradient( gradient: builder.create_gradient(
gradient.gradient.start_point.to_pointf(), gradient.gradient.start_point.to_pointf(),
gradient.gradient.end_point.to_pointf(), gradient.gradient.end_point.to_pointf(),
gradient.gradient.stops.clone(), gradient.gradient.stops.clone(),
ExtendMode::Clamp), extend_mode),
outset: gradient.outset,
})
}
BorderDetails::RadialGradient(ref gradient) => {
let extend_mode = if gradient.gradient.repeating {
ExtendMode::Repeat
} else {
ExtendMode::Clamp
};
webrender_traits::BorderDetails::RadialGradient(webrender_traits::RadialGradientBorder {
gradient: builder.create_radial_gradient(
gradient.gradient.center.to_pointf(),
gradient.gradient.radius.to_sizef(),
gradient.gradient.stops.clone(),
extend_mode),
outset: gradient.outset, outset: gradient.outset,
}) })
} }