mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Bug 1374233 - Part 13: Use NonNegative{*} types for components of Shadow and Filter.
MozReview-Commit-ID: Im4KGy1n9IJ
This commit is contained in:
parent
6dd8b159d7
commit
8651acd94c
13 changed files with 84 additions and 53 deletions
|
@ -1388,7 +1388,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
box_shadow.base.horizontal,
|
||||
box_shadow.base.vertical,
|
||||
)),
|
||||
box_shadow.base.blur,
|
||||
box_shadow.base.blur.0,
|
||||
box_shadow.spread,
|
||||
);
|
||||
|
||||
|
@ -1403,7 +1403,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
box_bounds: *absolute_bounds,
|
||||
color: style.resolve_color(box_shadow.base.color).to_gfx_color(),
|
||||
offset: Vector2D::new(box_shadow.base.horizontal, box_shadow.base.vertical),
|
||||
blur_radius: box_shadow.base.blur,
|
||||
blur_radius: box_shadow.base.blur.0,
|
||||
spread_radius: box_shadow.spread,
|
||||
border_radius: model::specified_border_radius(style.get_border()
|
||||
.border_top_left_radius,
|
||||
|
@ -2049,7 +2049,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
let effects = self.style().get_effects();
|
||||
let mut filters = effects.filter.0.clone();
|
||||
if effects.opacity != 1.0 {
|
||||
filters.push(Filter::Opacity(effects.opacity))
|
||||
filters.push(Filter::Opacity(effects.opacity.into()))
|
||||
}
|
||||
|
||||
let context_type = match mode {
|
||||
|
@ -2124,7 +2124,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
for shadow in text_shadows.iter().rev() {
|
||||
state.add_display_item(DisplayItem::PushTextShadow(box PushTextShadowDisplayItem {
|
||||
base: base.clone(),
|
||||
blur_radius: shadow.blur,
|
||||
blur_radius: shadow.blur.0,
|
||||
offset: Vector2D::new(shadow.horizontal, shadow.vertical),
|
||||
color: self.style().resolve_color(shadow.color).to_gfx_color(),
|
||||
}));
|
||||
|
|
|
@ -2570,7 +2570,7 @@ impl Fragment {
|
|||
// Box shadows cause us to draw outside our border box.
|
||||
for box_shadow in &self.style().get_effects().box_shadow.0 {
|
||||
let offset = Vector2D::new(box_shadow.base.horizontal, box_shadow.base.vertical);
|
||||
let inflation = box_shadow.spread + box_shadow.base.blur * BLUR_INFLATION_FACTOR;
|
||||
let inflation = box_shadow.spread + box_shadow.base.blur.0 * BLUR_INFLATION_FACTOR;
|
||||
overflow.paint = overflow.paint.union(&border_box.translate(&offset)
|
||||
.inflate(inflation, inflation))
|
||||
}
|
||||
|
|
|
@ -190,15 +190,15 @@ impl ToFilterOps for Vec<Filter> {
|
|||
let mut result = Vec::with_capacity(self.len());
|
||||
for filter in self.iter() {
|
||||
match *filter {
|
||||
GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius.to_f32_px())),
|
||||
GenericFilter::Brightness(amount) => result.push(webrender_api::FilterOp::Brightness(amount)),
|
||||
GenericFilter::Contrast(amount) => result.push(webrender_api::FilterOp::Contrast(amount)),
|
||||
GenericFilter::Grayscale(amount) => result.push(webrender_api::FilterOp::Grayscale(amount)),
|
||||
GenericFilter::Blur(radius) => result.push(webrender_api::FilterOp::Blur(radius.0.to_f32_px())),
|
||||
GenericFilter::Brightness(amount) => result.push(webrender_api::FilterOp::Brightness(amount.0)),
|
||||
GenericFilter::Contrast(amount) => result.push(webrender_api::FilterOp::Contrast(amount.0)),
|
||||
GenericFilter::Grayscale(amount) => result.push(webrender_api::FilterOp::Grayscale(amount.0)),
|
||||
GenericFilter::HueRotate(angle) => result.push(webrender_api::FilterOp::HueRotate(angle.radians())),
|
||||
GenericFilter::Invert(amount) => result.push(webrender_api::FilterOp::Invert(amount)),
|
||||
GenericFilter::Opacity(amount) => result.push(webrender_api::FilterOp::Opacity(amount.into())),
|
||||
GenericFilter::Saturate(amount) => result.push(webrender_api::FilterOp::Saturate(amount)),
|
||||
GenericFilter::Sepia(amount) => result.push(webrender_api::FilterOp::Sepia(amount)),
|
||||
GenericFilter::Invert(amount) => result.push(webrender_api::FilterOp::Invert(amount.0)),
|
||||
GenericFilter::Opacity(amount) => result.push(webrender_api::FilterOp::Opacity(amount.0.into())),
|
||||
GenericFilter::Saturate(amount) => result.push(webrender_api::FilterOp::Saturate(amount.0)),
|
||||
GenericFilter::Sepia(amount) => result.push(webrender_api::FilterOp::Sepia(amount.0)),
|
||||
GenericFilter::DropShadow(ref shadow) => match *shadow {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ use nsstring::{nsACString, nsCString};
|
|||
use std::cmp::max;
|
||||
use values::{Auto, Either, ExtremumLength, None_, Normal};
|
||||
use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto};
|
||||
use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage, NonNegativeAu};
|
||||
use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage};
|
||||
use values::computed::{MaxLength, MozLength, Percentage};
|
||||
use values::computed::NonNegativeLengthOrPercentage;
|
||||
use values::computed::{NonNegativeAu, NonNegativeLengthOrPercentage, NonNegativeNumber};
|
||||
use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
|
||||
use values::generics::{CounterStyleOrNone, NonNegative};
|
||||
use values::generics::basic_shape::ShapeRadius;
|
||||
|
@ -155,6 +155,16 @@ impl GeckoStyleCoordConvertible for NonNegativeAu {
|
|||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for NonNegativeNumber {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
self.0.to_gecko_style_coord(coord);
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
Number::from_gecko_style_coord(coord).map(NonNegative::<Number>)
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
let value = match *self {
|
||||
|
|
|
@ -27,7 +27,7 @@ impl nsCSSShadowItem {
|
|||
color: Color::rgba(convert_nscolor_to_rgba(self.mColor)),
|
||||
horizontal: Au(self.mXOffset),
|
||||
vertical: Au(self.mYOffset),
|
||||
blur: Au(self.mRadius),
|
||||
blur: Au(self.mRadius).into(),
|
||||
},
|
||||
spread: Au(self.mSpread),
|
||||
inset: self.mInset,
|
||||
|
@ -39,7 +39,7 @@ impl nsCSSShadowItem {
|
|||
pub fn set_from_simple_shadow(&mut self, shadow: SimpleShadow) {
|
||||
self.mXOffset = shadow.horizontal.0;
|
||||
self.mYOffset = shadow.vertical.0;
|
||||
self.mRadius = shadow.blur.0;
|
||||
self.mRadius = shadow.blur.value();
|
||||
self.mSpread = 0;
|
||||
self.mInset = false;
|
||||
if shadow.color.is_currentcolor() {
|
||||
|
@ -62,7 +62,7 @@ impl nsCSSShadowItem {
|
|||
color: Color::rgba(convert_nscolor_to_rgba(self.mColor)),
|
||||
horizontal: Au(self.mXOffset),
|
||||
vertical: Au(self.mYOffset),
|
||||
blur: Au(self.mRadius),
|
||||
blur: Au(self.mRadius).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4420,11 +4420,11 @@ fn static_assert() {
|
|||
match servo {
|
||||
% for func in FILTER_FUNCTIONS:
|
||||
${func}(factor) => fill_filter(NS_STYLE_FILTER_${func.upper()},
|
||||
CoordDataValue::Factor(factor),
|
||||
CoordDataValue::Factor(factor.0),
|
||||
gecko_filter),
|
||||
% endfor
|
||||
Blur(length) => fill_filter(NS_STYLE_FILTER_BLUR,
|
||||
CoordDataValue::Coord(length.0),
|
||||
CoordDataValue::Coord(length.value()),
|
||||
gecko_filter),
|
||||
|
||||
HueRotate(angle) => fill_filter(NS_STYLE_FILTER_HUE_ROTATE,
|
||||
|
@ -4492,7 +4492,7 @@ fn static_assert() {
|
|||
},
|
||||
% endfor
|
||||
NS_STYLE_FILTER_BLUR => {
|
||||
filters.push(Filter::Blur(Au::from_gecko_style_coord(
|
||||
filters.push(Filter::Blur(NonNegativeAu::from_gecko_style_coord(
|
||||
&filter.mFilterParameter).unwrap()));
|
||||
},
|
||||
NS_STYLE_FILTER_HUE_ROTATE => {
|
||||
|
|
|
@ -3192,7 +3192,7 @@ fn add_weighted_filter_function_impl(from: &AnimatedFilter,
|
|||
&to_value,
|
||||
self_portion,
|
||||
other_portion,
|
||||
&0.0,
|
||||
&NonNegative::<CSSFloat>(0.0),
|
||||
)?))
|
||||
},
|
||||
% endfor
|
||||
|
@ -3203,7 +3203,7 @@ fn add_weighted_filter_function_impl(from: &AnimatedFilter,
|
|||
&to_value,
|
||||
self_portion,
|
||||
other_portion,
|
||||
&1.0,
|
||||
&NonNegative::<CSSFloat>(1.0),
|
||||
)?))
|
||||
},
|
||||
% endfor
|
||||
|
|
|
@ -12,8 +12,8 @@ use std::cmp;
|
|||
#[cfg(not(feature = "gecko"))]
|
||||
use values::Impossible;
|
||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||
use values::computed::{Angle, Number};
|
||||
use values::computed::length::Length;
|
||||
use values::computed::{Angle, NonNegativeNumber};
|
||||
use values::computed::length::{Length, NonNegativeLength};
|
||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
use values::generics::effects::Filter as GenericFilter;
|
||||
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||
|
@ -32,7 +32,7 @@ pub type TextShadowList = ShadowList<SimpleShadow>;
|
|||
pub struct ShadowList<Shadow>(Vec<Shadow>);
|
||||
|
||||
/// An animated value for a single `box-shadow`.
|
||||
pub type BoxShadow = GenericBoxShadow<IntermediateColor, Length, Length>;
|
||||
pub type BoxShadow = GenericBoxShadow<IntermediateColor, Length, NonNegativeLength, Length>;
|
||||
|
||||
/// An animated value for the `filter` property.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -41,14 +41,14 @@ pub struct FilterList(pub Vec<Filter>);
|
|||
|
||||
/// An animated value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow>;
|
||||
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow>;
|
||||
|
||||
/// An animated value for a single `filter`.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type Filter = GenericFilter<Angle, Number, Length, Impossible>;
|
||||
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible>;
|
||||
|
||||
/// An animated value for the `drop-shadow()` filter.
|
||||
pub type SimpleShadow = GenericSimpleShadow<IntermediateColor, Length, Length>;
|
||||
pub type SimpleShadow = GenericSimpleShadow<IntermediateColor, Length, NonNegativeLength>;
|
||||
|
||||
impl ToAnimatedValue for ComputedBoxShadowList {
|
||||
type AnimatedValue = BoxShadowList;
|
||||
|
|
|
@ -6,23 +6,23 @@
|
|||
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
use values::Impossible;
|
||||
use values::computed::{Angle, Number};
|
||||
use values::computed::{Angle, NonNegativeNumber};
|
||||
use values::computed::color::Color;
|
||||
use values::computed::length::Length;
|
||||
use values::computed::length::{Length, NonNegativeLength};
|
||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
use values::generics::effects::Filter as GenericFilter;
|
||||
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||
|
||||
/// A computed value for a single shadow of the `box-shadow` property.
|
||||
pub type BoxShadow = GenericBoxShadow<Color, Length, Length>;
|
||||
pub type BoxShadow = GenericBoxShadow<Color, Length, NonNegativeLength, Length>;
|
||||
|
||||
/// A computed value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow>;
|
||||
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow>;
|
||||
|
||||
/// A computed value for a single `filter`.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type Filter = GenericFilter<Angle, Number, Length, Impossible>;
|
||||
pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible>;
|
||||
|
||||
/// A computed value for the `drop-shadow()` filter.
|
||||
pub type SimpleShadow = GenericSimpleShadow<Color, Length, Length>;
|
||||
pub type SimpleShadow = GenericSimpleShadow<Color, Length, NonNegativeLength>;
|
||||
|
|
|
@ -12,9 +12,9 @@ use values::specified::url::SpecifiedUrl;
|
|||
/// A generic value for a single `box-shadow`.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue)]
|
||||
pub struct BoxShadow<Color, SizeLength, ShapeLength> {
|
||||
pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
|
||||
/// The base shadow.
|
||||
pub base: SimpleShadow<Color, SizeLength, ShapeLength>,
|
||||
pub base: SimpleShadow<Color, SizeLength, BlurShapeLength>,
|
||||
/// The spread radius.
|
||||
pub spread: ShapeLength,
|
||||
/// Whether this is an inset box shadow.
|
||||
|
@ -77,10 +77,14 @@ pub struct SimpleShadow<Color, SizeLength, ShapeLength> {
|
|||
pub blur: ShapeLength,
|
||||
}
|
||||
|
||||
impl<Color, SizeLength, ShapeLength> ToCss for BoxShadow<Color, SizeLength, ShapeLength>
|
||||
impl<Color, SizeLength, BlurShapeLength, ShapeLength> ToCss for BoxShadow<Color,
|
||||
SizeLength,
|
||||
BlurShapeLength,
|
||||
ShapeLength>
|
||||
where
|
||||
Color: ToCss,
|
||||
SizeLength: ToCss,
|
||||
BlurShapeLength: ToCss,
|
||||
ShapeLength: ToCss,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
|
|
|
@ -9,28 +9,29 @@ use parser::{Parse, ParserContext};
|
|||
use style_traits::{ParseError, StyleParseError};
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
use values::Impossible;
|
||||
use values::computed::{Context, Number as ComputedNumber, ToComputedValue};
|
||||
use values::computed::{Context, NonNegativeNumber as ComputedNonNegativeNumber, ToComputedValue};
|
||||
use values::computed::effects::BoxShadow as ComputedBoxShadow;
|
||||
use values::computed::effects::SimpleShadow as ComputedSimpleShadow;
|
||||
use values::generics::NonNegative;
|
||||
use values::generics::effects::BoxShadow as GenericBoxShadow;
|
||||
use values::generics::effects::Filter as GenericFilter;
|
||||
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||
use values::specified::{Angle, NumberOrPercentage};
|
||||
use values::specified::color::Color;
|
||||
use values::specified::length::Length;
|
||||
use values::specified::length::{Length, NonNegativeLength};
|
||||
#[cfg(feature = "gecko")]
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
/// A specified value for a single shadow of the `box-shadow` property.
|
||||
pub type BoxShadow = GenericBoxShadow<Option<Color>, Length, Option<Length>>;
|
||||
pub type BoxShadow = GenericBoxShadow<Option<Color>, Length, Option<NonNegativeLength>, Option<Length>>;
|
||||
|
||||
/// A specified value for a single `filter`.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub type Filter = GenericFilter<Angle, Factor, Length, SimpleShadow>;
|
||||
pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, SimpleShadow>;
|
||||
|
||||
/// A specified value for a single `filter`.
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
pub type Filter = GenericFilter<Angle, Factor, Length, Impossible>;
|
||||
pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, Impossible>;
|
||||
|
||||
/// A value for the `<factor>` parts in `Filter`.
|
||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
|
||||
|
@ -48,25 +49,25 @@ impl Parse for Factor {
|
|||
}
|
||||
|
||||
impl ToComputedValue for Factor {
|
||||
type ComputedValue = ComputedNumber;
|
||||
type ComputedValue = ComputedNonNegativeNumber;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
use values::computed::NumberOrPercentage;
|
||||
match self.0.to_computed_value(context) {
|
||||
NumberOrPercentage::Number(n) => n,
|
||||
NumberOrPercentage::Percentage(p) => p.0,
|
||||
NumberOrPercentage::Number(n) => n.into(),
|
||||
NumberOrPercentage::Percentage(p) => p.0.into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
Factor(NumberOrPercentage::Number(ToComputedValue::from_computed_value(computed)))
|
||||
Factor(NumberOrPercentage::Number(ToComputedValue::from_computed_value(&computed.0)))
|
||||
}
|
||||
}
|
||||
|
||||
/// A specified value for the `drop-shadow()` filter.
|
||||
pub type SimpleShadow = GenericSimpleShadow<Option<Color>, Length, Option<Length>>;
|
||||
pub type SimpleShadow = GenericSimpleShadow<Option<Color>, Length, Option<NonNegativeLength>>;
|
||||
|
||||
impl Parse for BoxShadow {
|
||||
fn parse<'i, 't>(
|
||||
|
@ -91,7 +92,7 @@ impl Parse for BoxShadow {
|
|||
let (blur, spread) = match i.try::<_, _, ParseError>(|i| Length::parse_non_negative(context, i)) {
|
||||
Ok(blur) => {
|
||||
let spread = i.try(|i| Length::parse(context, i)).ok();
|
||||
(Some(blur), spread)
|
||||
(Some(blur.into()), spread)
|
||||
},
|
||||
Err(_) => (None, None),
|
||||
};
|
||||
|
@ -162,7 +163,7 @@ impl Parse for Filter {
|
|||
let function = input.expect_function()?.clone();
|
||||
input.parse_nested_block(|i| {
|
||||
try_match_ident_ignore_ascii_case! { function,
|
||||
"blur" => Ok(GenericFilter::Blur(Length::parse_non_negative(context, i)?)),
|
||||
"blur" => Ok(GenericFilter::Blur((Length::parse_non_negative(context, i)?).into())),
|
||||
"brightness" => Ok(GenericFilter::Brightness(Factor::parse(context, i)?)),
|
||||
"contrast" => Ok(GenericFilter::Contrast(Factor::parse(context, i)?)),
|
||||
"grayscale" => Ok(GenericFilter::Grayscale(Factor::parse(context, i)?)),
|
||||
|
@ -192,7 +193,7 @@ impl Parse for SimpleShadow {
|
|||
color: color,
|
||||
horizontal: horizontal,
|
||||
vertical: vertical,
|
||||
blur: blur,
|
||||
blur: blur.map(NonNegative::<Length>),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +209,7 @@ impl ToComputedValue for SimpleShadow {
|
|||
horizontal: self.horizontal.to_computed_value(context),
|
||||
vertical: self.vertical.to_computed_value(context),
|
||||
blur:
|
||||
self.blur.as_ref().unwrap_or(&Length::zero()).to_computed_value(context),
|
||||
self.blur.as_ref().unwrap_or(&NonNegativeLength::zero()).to_computed_value(context),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -733,6 +733,20 @@ impl<T: Parse> Parse for Either<NonNegativeLength, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl NonNegativeLength {
|
||||
/// Returns a `zero` length.
|
||||
#[inline]
|
||||
pub fn zero() -> Self {
|
||||
Length::zero().into()
|
||||
}
|
||||
|
||||
/// Get an absolute length from a px value.
|
||||
#[inline]
|
||||
pub fn from_px(px_value: CSSFloat) -> Self {
|
||||
Length::from_px(px_value.max(0.)).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Either a NonNegativeLength or the `normal` keyword.
|
||||
pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>;
|
||||
|
||||
|
|
|
@ -1241,13 +1241,15 @@ mod shorthand_serialization {
|
|||
|
||||
#[test]
|
||||
fn box_shadow_should_serialize_correctly() {
|
||||
use style::values::specified::length::NonNegativeLength;
|
||||
|
||||
let mut properties = Vec::new();
|
||||
let shadow_val = BoxShadow {
|
||||
base: SimpleShadow {
|
||||
color: None,
|
||||
horizontal: Length::from_px(1f32),
|
||||
vertical: Length::from_px(2f32),
|
||||
blur: Some(Length::from_px(3f32)),
|
||||
blur: Some(NonNegativeLength::from_px(3f32)),
|
||||
},
|
||||
spread: Some(Length::from_px(4f32)),
|
||||
inset: false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue