style: Add method to parse CSS filters without context for workers

This patch adds the ability to parse most CSS filters without a context.
OffscreenCanvas can use this on worker threads to provide support for
filter operations.

Differential Revision: https://phabricator.services.mozilla.com/D179994
This commit is contained in:
Andrew Osmond 2023-06-09 13:38:40 +00:00 committed by Martin Robinson
parent a10df24ffb
commit 42d9ec1106
2 changed files with 93 additions and 0 deletions

View file

@ -7,6 +7,12 @@
use crate::parser::{Parse, ParserContext};
use crate::values::computed::effects::BoxShadow as ComputedBoxShadow;
use crate::values::computed::effects::SimpleShadow as ComputedSimpleShadow;
#[cfg(feature = "gecko")]
use crate::values::computed::url::ComputedUrl;
use crate::values::computed::Angle as ComputedAngle;
use crate::values::computed::CSSPixelLength as ComputedCSSPixelLength;
use crate::values::computed::Filter as ComputedFilter;
use crate::values::computed::NonNegativeLength as ComputedNonNegativeLength;
use crate::values::computed::NonNegativeNumber as ComputedNonNegativeNumber;
use crate::values::computed::ZeroToOneNumber as ComputedZeroToOneNumber;
use crate::values::computed::{Context, ToComputedValue};
@ -75,6 +81,7 @@ fn clamp_to_one(number: NumberOrPercentage) -> NumberOrPercentage {
macro_rules! factor_impl_common {
($ty:ty, $computed_ty:ty) => {
impl $ty {
#[inline]
fn one() -> Self {
Self(NumberOrPercentage::Number(Number::new(1.)))
}
@ -217,6 +224,90 @@ impl ToComputedValue for BoxShadow {
}
}
// We need this for converting the specified Filter into computed Filter without Context (for
// some FFIs in glue.rs). This can fail because in some circumstances, we still need Context to
// determine the computed value.
impl Filter {
/// Generate the ComputedFilter without Context.
pub fn to_computed_value_without_context(&self) -> Result<ComputedFilter, ()> {
match *self {
Filter::Blur(ref length) => Ok(ComputedFilter::Blur(ComputedNonNegativeLength::new(
length.0.to_computed_pixel_length_without_context()?,
))),
Filter::Brightness(ref factor) => Ok(ComputedFilter::Brightness(
ComputedNonNegativeNumber::from(factor.0.to_number().get()),
)),
Filter::Contrast(ref factor) => Ok(ComputedFilter::Contrast(
ComputedNonNegativeNumber::from(factor.0.to_number().get()),
)),
Filter::Grayscale(ref factor) => Ok(ComputedFilter::Grayscale(
ComputedZeroToOneNumber::from(factor.0.to_number().get()),
)),
Filter::HueRotate(ref angle) => Ok(ComputedFilter::HueRotate(
ComputedAngle::from_degrees(angle.degrees()),
)),
Filter::Invert(ref factor) => Ok(ComputedFilter::Invert(
ComputedZeroToOneNumber::from(factor.0.to_number().get()),
)),
Filter::Opacity(ref factor) => Ok(ComputedFilter::Opacity(
ComputedZeroToOneNumber::from(factor.0.to_number().get()),
)),
Filter::Saturate(ref factor) => Ok(ComputedFilter::Saturate(
ComputedNonNegativeNumber::from(factor.0.to_number().get()),
)),
Filter::Sepia(ref factor) => Ok(ComputedFilter::Sepia(ComputedZeroToOneNumber::from(
factor.0.to_number().get(),
))),
Filter::DropShadow(ref shadow) => {
if cfg!(feature = "gecko") {
let color = match shadow
.color
.as_ref()
.unwrap_or(&Color::currentcolor())
.to_computed_color(None)
{
Some(c) => c,
None => return Err(()),
};
let horizontal = ComputedCSSPixelLength::new(
shadow
.horizontal
.to_computed_pixel_length_without_context()?,
);
let vertical = ComputedCSSPixelLength::new(
shadow.vertical.to_computed_pixel_length_without_context()?,
);
let blur = ComputedNonNegativeLength::new(
shadow
.blur
.as_ref()
.unwrap_or(&NonNegativeLength::zero())
.0
.to_computed_pixel_length_without_context()?,
);
Ok(ComputedFilter::DropShadow(ComputedSimpleShadow {
color,
horizontal,
vertical,
blur,
}))
} else {
Err(())
}
},
Filter::Url(ref url) => {
if cfg!(feature = "gecko") {
Ok(ComputedFilter::Url(ComputedUrl(url.clone())))
} else {
Err(())
}
},
}
}
}
impl Parse for Filter {
#[inline]
fn parse<'i, 't>(

View file

@ -235,6 +235,7 @@ impl Parse for Number {
impl Number {
/// Returns a new number with the value `val`.
#[inline]
fn new_with_clamping_mode(
value: CSSFloat,
calc_clamping_mode: Option<AllowedNumericType>,
@ -251,6 +252,7 @@ impl Number {
}
/// Returns a new number with the value `val`.
#[inline]
pub fn new(val: CSSFloat) -> Self {
Self::new_with_clamping_mode(val, None)
}