mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
servo: Merge #14359 - Reuse box-shadow code for drop-shadow filter (from shinglyu:dropshadow-refactor); r=Manishearth
<!-- Please describe your changes on the following line: --> Followup for #14218. Extracted the `Shadow` struct and methods into `values::*`, and make `box-shadow` and `drop-shadow` share the new `Shadow` type. The `ToCss` trait is not reused because they behave different in the two properties. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #14219 (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: cd1d5f1cf359051eb76aa81ec3de48b84b0dab81
This commit is contained in:
parent
84e275726b
commit
e0ddee40ec
@ -1809,7 +1809,7 @@ fn static_assert() {
|
|||||||
Sepia(factor) => fill_filter(NS_STYLE_FILTER_SEPIA,
|
Sepia(factor) => fill_filter(NS_STYLE_FILTER_SEPIA,
|
||||||
CoordDataValue::Factor(factor),
|
CoordDataValue::Factor(factor),
|
||||||
gecko_filter),
|
gecko_filter),
|
||||||
DropShadow(offset_x, offset_y, blur_radius, ref color) => {
|
DropShadow(shadow) => {
|
||||||
gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW;
|
gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW;
|
||||||
|
|
||||||
fn init_shadow(filter: &mut nsStyleFilter) -> &mut nsCSSShadowArray {
|
fn init_shadow(filter: &mut nsStyleFilter) -> &mut nsCSSShadowArray {
|
||||||
@ -1823,13 +1823,13 @@ fn static_assert() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut gecko_shadow = init_shadow(gecko_filter);
|
let mut gecko_shadow = init_shadow(gecko_filter);
|
||||||
gecko_shadow.mArray[0].mXOffset = offset_x.0;
|
gecko_shadow.mArray[0].mXOffset = shadow.offset_x.0;
|
||||||
gecko_shadow.mArray[0].mYOffset = offset_y.0;
|
gecko_shadow.mArray[0].mYOffset = shadow.offset_y.0;
|
||||||
gecko_shadow.mArray[0].mRadius = blur_radius.0;
|
gecko_shadow.mArray[0].mRadius = shadow.blur_radius.0;
|
||||||
// mSpread is not supported in the spec, so we leave it as 0
|
// mSpread is not supported in the spec, so we leave it as 0
|
||||||
gecko_shadow.mArray[0].mInset = false; // Not supported in spec level 1
|
gecko_shadow.mArray[0].mInset = false; // Not supported in spec level 1
|
||||||
|
|
||||||
gecko_shadow.mArray[0].mColor = match *color {
|
gecko_shadow.mArray[0].mColor = match shadow.color {
|
||||||
Color::RGBA(rgba) => {
|
Color::RGBA(rgba) => {
|
||||||
gecko_shadow.mArray[0].mHasColor = true;
|
gecko_shadow.mArray[0].mHasColor = true;
|
||||||
convert_rgba_to_nscolor(&rgba)
|
convert_rgba_to_nscolor(&rgba)
|
||||||
|
@ -18,25 +18,7 @@ ${helpers.predefined_type("opacity",
|
|||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
pub type SpecifiedValue = specified::Shadow;
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub struct SpecifiedValue {
|
|
||||||
pub offset_x: specified::Length,
|
|
||||||
pub offset_y: specified::Length,
|
|
||||||
pub blur_radius: specified::Length,
|
|
||||||
pub spread_radius: specified::Length,
|
|
||||||
pub color: Option<specified::CSSColor>,
|
|
||||||
pub inset: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedValue {
|
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
|
||||||
self.offset_x.has_viewport_percentage() ||
|
|
||||||
self.offset_y.has_viewport_percentage() ||
|
|
||||||
self.blur_radius.has_viewport_percentage() ||
|
|
||||||
self.spread_radius.has_viewport_percentage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for SpecifiedValue {
|
impl ToCss for SpecifiedValue {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
@ -63,17 +45,9 @@ ${helpers.predefined_type("opacity",
|
|||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use values::computed;
|
use values::computed;
|
||||||
|
use values::computed::Shadow;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Copy, Debug)]
|
pub type T = Shadow;
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub struct T {
|
|
||||||
pub offset_x: Au,
|
|
||||||
pub offset_y: Au,
|
|
||||||
pub blur_radius: Au,
|
|
||||||
pub spread_radius: Au,
|
|
||||||
pub color: computed::CSSColor,
|
|
||||||
pub inset: bool,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for computed_value::T {
|
impl ToCss for computed_value::T {
|
||||||
@ -94,95 +68,8 @@ ${helpers.predefined_type("opacity",
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<specified::Shadow, ()> {
|
||||||
type ComputedValue = computed_value::T;
|
specified::Shadow::parse(context, input, false)
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
|
||||||
computed_value::T {
|
|
||||||
offset_x: self.offset_x.to_computed_value(context),
|
|
||||||
offset_y: self.offset_y.to_computed_value(context),
|
|
||||||
blur_radius: self.blur_radius.to_computed_value(context),
|
|
||||||
spread_radius: self.spread_radius.to_computed_value(context),
|
|
||||||
color: self.color
|
|
||||||
.as_ref()
|
|
||||||
.map(|color| color.parsed)
|
|
||||||
.unwrap_or(cssparser::Color::CurrentColor),
|
|
||||||
inset: self.inset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
|
||||||
SpecifiedValue {
|
|
||||||
offset_x: ToComputedValue::from_computed_value(&computed.offset_x),
|
|
||||||
offset_y: ToComputedValue::from_computed_value(&computed.offset_y),
|
|
||||||
blur_radius: ToComputedValue::from_computed_value(&computed.blur_radius),
|
|
||||||
spread_radius: ToComputedValue::from_computed_value(&computed.spread_radius),
|
|
||||||
color: Some(ToComputedValue::from_computed_value(&computed.color)),
|
|
||||||
inset: computed.inset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
|
||||||
use app_units::Au;
|
|
||||||
let mut lengths = [specified::Length::Absolute(Au(0)); 4];
|
|
||||||
let mut lengths_parsed = false;
|
|
||||||
let mut color = None;
|
|
||||||
let mut inset = false;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if !inset {
|
|
||||||
if input.try(|input| input.expect_ident_matching("inset")).is_ok() {
|
|
||||||
inset = true;
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !lengths_parsed {
|
|
||||||
if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) {
|
|
||||||
lengths[0] = value;
|
|
||||||
let mut length_parsed_count = 1;
|
|
||||||
while length_parsed_count < 4 {
|
|
||||||
if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) {
|
|
||||||
lengths[length_parsed_count] = value
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
length_parsed_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The first two lengths must be specified.
|
|
||||||
if length_parsed_count < 2 {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
lengths_parsed = true;
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if color.is_none() {
|
|
||||||
if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) {
|
|
||||||
color = Some(value);
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lengths must be specified.
|
|
||||||
if !lengths_parsed {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(SpecifiedValue {
|
|
||||||
offset_x: lengths[0],
|
|
||||||
offset_y: lengths[1],
|
|
||||||
blur_radius: lengths[2],
|
|
||||||
spread_radius: lengths[3],
|
|
||||||
color: color,
|
|
||||||
inset: inset,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</%helpers:vector_longhand>
|
</%helpers:vector_longhand>
|
||||||
|
|
||||||
@ -406,7 +293,7 @@ ${helpers.predefined_type("opacity",
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{self, ToCss};
|
use style_traits::{self, ToCss};
|
||||||
use values::{CSSFloat, HasViewportPercentage};
|
use values::{CSSFloat, HasViewportPercentage};
|
||||||
use values::specified::{Angle, CSSColor, Length};
|
use values::specified::{Angle, CSSColor, Length, Shadow};
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedValue {
|
impl HasViewportPercentage for SpecifiedValue {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
@ -442,14 +329,14 @@ ${helpers.predefined_type("opacity",
|
|||||||
Saturate(CSSFloat),
|
Saturate(CSSFloat),
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
DropShadow(Length, Length, Length, Option<CSSColor>),
|
DropShadow(Shadow),
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
use values::computed::CSSColor;
|
use values::computed::{CSSColor, Shadow};
|
||||||
use values::specified::{Angle};
|
use values::specified::{Angle};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
@ -465,7 +352,7 @@ ${helpers.predefined_type("opacity",
|
|||||||
Saturate(CSSFloat),
|
Saturate(CSSFloat),
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
DropShadow(Au, Au, Au, CSSColor),
|
DropShadow(Shadow),
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,15 +452,15 @@ ${helpers.predefined_type("opacity",
|
|||||||
computed_value::Filter::Saturate(value) => try!(write!(dest, "saturate({})", value)),
|
computed_value::Filter::Saturate(value) => try!(write!(dest, "saturate({})", value)),
|
||||||
computed_value::Filter::Sepia(value) => try!(write!(dest, "sepia({})", value)),
|
computed_value::Filter::Sepia(value) => try!(write!(dest, "sepia({})", value)),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
computed_value::Filter::DropShadow(offset_x, offset_y, blur_radius, ref color) => {
|
computed_value::Filter::DropShadow(shadow) => {
|
||||||
try!(dest.write_str("drop-shadow("));
|
try!(dest.write_str("drop-shadow("));
|
||||||
try!(offset_x.to_css(dest));
|
try!(shadow.offset_x.to_css(dest));
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(offset_y.to_css(dest));
|
try!(shadow.offset_y.to_css(dest));
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(blur_radius.to_css(dest));
|
try!(shadow.blur_radius.to_css(dest));
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(color.to_css(dest));
|
try!(shadow.color.to_css(dest));
|
||||||
try!(dest.write_str(")"));
|
try!(dest.write_str(")"));
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
@ -603,14 +490,14 @@ ${helpers.predefined_type("opacity",
|
|||||||
SpecifiedFilter::Saturate(value) => try!(write!(dest, "saturate({})", value)),
|
SpecifiedFilter::Saturate(value) => try!(write!(dest, "saturate({})", value)),
|
||||||
SpecifiedFilter::Sepia(value) => try!(write!(dest, "sepia({})", value)),
|
SpecifiedFilter::Sepia(value) => try!(write!(dest, "sepia({})", value)),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, ref color) => {
|
SpecifiedFilter::DropShadow(ref shadow) => {
|
||||||
try!(dest.write_str("drop-shadow("));
|
try!(dest.write_str("drop-shadow("));
|
||||||
try!(offset_x.to_css(dest));
|
try!(shadow.offset_x.to_css(dest));
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(offset_y.to_css(dest));
|
try!(shadow.offset_y.to_css(dest));
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(blur_radius.to_css(dest));
|
try!(shadow.blur_radius.to_css(dest));
|
||||||
if let &Some(ref color) = color {
|
if let Some(ref color) = shadow.color {
|
||||||
try!(dest.write_str(", "));
|
try!(dest.write_str(", "));
|
||||||
try!(color.to_css(dest));
|
try!(color.to_css(dest));
|
||||||
}
|
}
|
||||||
@ -646,7 +533,8 @@ ${helpers.predefined_type("opacity",
|
|||||||
"saturate" => parse_factor(input).map(SpecifiedFilter::Saturate),
|
"saturate" => parse_factor(input).map(SpecifiedFilter::Saturate),
|
||||||
"sepia" => parse_factor(input).map(SpecifiedFilter::Sepia),
|
"sepia" => parse_factor(input).map(SpecifiedFilter::Sepia),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
"drop-shadow" => parse_drop_shadow(context, input),
|
"drop-shadow" => specified::Shadow::parse(context, input, true)
|
||||||
|
.map(SpecifiedFilter::DropShadow),
|
||||||
% endif
|
% endif
|
||||||
_ => Err(())
|
_ => Err(())
|
||||||
}
|
}
|
||||||
@ -668,17 +556,6 @@ ${helpers.predefined_type("opacity",
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
% if product == "gecko":
|
|
||||||
fn parse_drop_shadow(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedFilter, ()> {
|
|
||||||
let offset_x = try!(specified::Length::parse(context, input));
|
|
||||||
let offset_y = try!(specified::Length::parse(context, input));
|
|
||||||
let blur_radius = input.try(|i| specified::Length::parse(context, i))
|
|
||||||
.unwrap_or(specified::Length::from_px(0.0));
|
|
||||||
let color = input.try(|i| specified::CSSColor::parse(context, i)).ok();
|
|
||||||
Ok(SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, color))
|
|
||||||
}
|
|
||||||
% endif
|
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
impl ToComputedValue for SpecifiedValue {
|
||||||
type ComputedValue = computed_value::T;
|
type ComputedValue = computed_value::T;
|
||||||
|
|
||||||
@ -696,16 +573,9 @@ ${helpers.predefined_type("opacity",
|
|||||||
SpecifiedFilter::Saturate(factor) => computed_value::Filter::Saturate(factor),
|
SpecifiedFilter::Saturate(factor) => computed_value::Filter::Saturate(factor),
|
||||||
SpecifiedFilter::Sepia(factor) => computed_value::Filter::Sepia(factor),
|
SpecifiedFilter::Sepia(factor) => computed_value::Filter::Sepia(factor),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, ref color) => {
|
SpecifiedFilter::DropShadow(ref shadow) => {
|
||||||
computed_value::Filter::DropShadow(
|
computed_value::Filter::DropShadow(shadow.to_computed_value(context))
|
||||||
offset_x.to_computed_value(context),
|
},
|
||||||
offset_y.to_computed_value(context),
|
|
||||||
blur_radius.to_computed_value(context),
|
|
||||||
color.as_ref()
|
|
||||||
.map(|color| color.parsed)
|
|
||||||
.unwrap_or(cssparser::Color::CurrentColor),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
}).collect() }
|
}).collect() }
|
||||||
@ -725,12 +595,9 @@ ${helpers.predefined_type("opacity",
|
|||||||
computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor),
|
computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor),
|
||||||
computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor),
|
computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor),
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
computed_value::Filter::DropShadow(offset_x, offset_y, blur_radius, color) => {
|
computed_value::Filter::DropShadow(shadow) => {
|
||||||
SpecifiedFilter::DropShadow(
|
SpecifiedFilter::DropShadow(
|
||||||
ToComputedValue::from_computed_value(&offset_x),
|
ToComputedValue::from_computed_value(&shadow),
|
||||||
ToComputedValue::from_computed_value(&offset_y),
|
|
||||||
ToComputedValue::from_computed_value(&blur_radius),
|
|
||||||
Some(ToComputedValue::from_computed_value(&color)),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
@ -167,5 +167,16 @@ impl ToCss for BorderRadiusSize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct Shadow {
|
||||||
|
pub offset_x: Au,
|
||||||
|
pub offset_y: Au,
|
||||||
|
pub blur_radius: Au,
|
||||||
|
pub spread_radius: Au,
|
||||||
|
pub color: CSSColor,
|
||||||
|
pub inset: bool,
|
||||||
|
}
|
||||||
|
|
||||||
pub type Number = CSSFloat;
|
pub type Number = CSSFloat;
|
||||||
pub type Opacity = CSSFloat;
|
pub type Opacity = CSSFloat;
|
||||||
|
@ -14,6 +14,7 @@ use std::ops::Mul;
|
|||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use super::{CSSFloat, HasViewportPercentage, NoViewportPercentage, Either, None_};
|
use super::{CSSFloat, HasViewportPercentage, NoViewportPercentage, Either, None_};
|
||||||
use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
|
||||||
|
use super::computed::Shadow as ComputedShadow;
|
||||||
|
|
||||||
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
|
||||||
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};
|
||||||
@ -517,3 +518,117 @@ impl ToCss for Opacity {
|
|||||||
|
|
||||||
pub type UrlOrNone = Either<SpecifiedUrl, None_>;
|
pub type UrlOrNone = Either<SpecifiedUrl, None_>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
pub struct Shadow {
|
||||||
|
pub offset_x: Length,
|
||||||
|
pub offset_y: Length,
|
||||||
|
pub blur_radius: Length,
|
||||||
|
pub spread_radius: Length,
|
||||||
|
pub color: Option<CSSColor>,
|
||||||
|
pub inset: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasViewportPercentage for Shadow {
|
||||||
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
|
self.offset_x.has_viewport_percentage() ||
|
||||||
|
self.offset_y.has_viewport_percentage() ||
|
||||||
|
self.blur_radius.has_viewport_percentage() ||
|
||||||
|
self.spread_radius.has_viewport_percentage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for Shadow {
|
||||||
|
type ComputedValue = ComputedShadow;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
|
ComputedShadow {
|
||||||
|
offset_x: self.offset_x.to_computed_value(context),
|
||||||
|
offset_y: self.offset_y.to_computed_value(context),
|
||||||
|
blur_radius: self.blur_radius.to_computed_value(context),
|
||||||
|
spread_radius: self.spread_radius.to_computed_value(context),
|
||||||
|
color: self.color
|
||||||
|
.as_ref()
|
||||||
|
.map(|color| color.parsed)
|
||||||
|
.unwrap_or(cssparser::Color::CurrentColor),
|
||||||
|
inset: self.inset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &ComputedShadow) -> Self {
|
||||||
|
Shadow {
|
||||||
|
offset_x: ToComputedValue::from_computed_value(&computed.offset_x),
|
||||||
|
offset_y: ToComputedValue::from_computed_value(&computed.offset_y),
|
||||||
|
blur_radius: ToComputedValue::from_computed_value(&computed.blur_radius),
|
||||||
|
spread_radius: ToComputedValue::from_computed_value(&computed.spread_radius),
|
||||||
|
color: Some(ToComputedValue::from_computed_value(&computed.color)),
|
||||||
|
inset: computed.inset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Shadow {
|
||||||
|
// disable_spread_and_inset is for filter: drop-shadow(...)
|
||||||
|
pub fn parse(context: &ParserContext, input: &mut Parser, disable_spread_and_inset: bool) -> Result<Shadow, ()> {
|
||||||
|
use app_units::Au;
|
||||||
|
let length_count = if disable_spread_and_inset { 3 } else { 4 };
|
||||||
|
let mut lengths = [Length::Absolute(Au(0)); 4];
|
||||||
|
let mut lengths_parsed = false;
|
||||||
|
let mut color = None;
|
||||||
|
let mut inset = false;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if !inset && !disable_spread_and_inset {
|
||||||
|
if input.try(|input| input.expect_ident_matching("inset")).is_ok() {
|
||||||
|
inset = true;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !lengths_parsed {
|
||||||
|
if let Ok(value) = input.try(|i| Length::parse(context, i)) {
|
||||||
|
lengths[0] = value;
|
||||||
|
let mut length_parsed_count = 1;
|
||||||
|
while length_parsed_count < length_count {
|
||||||
|
if let Ok(value) = input.try(|i| Length::parse(context, i)) {
|
||||||
|
lengths[length_parsed_count] = value
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
length_parsed_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first two lengths must be specified.
|
||||||
|
if length_parsed_count < 2 {
|
||||||
|
return Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
lengths_parsed = true;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if color.is_none() {
|
||||||
|
if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) {
|
||||||
|
color = Some(value);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lengths must be specified.
|
||||||
|
if !lengths_parsed {
|
||||||
|
return Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Shadow {
|
||||||
|
offset_x: lengths[0],
|
||||||
|
offset_y: lengths[1],
|
||||||
|
blur_radius: lengths[2],
|
||||||
|
spread_radius: if disable_spread_and_inset { Length::Absolute(Au(0)) } else { lengths[3] },
|
||||||
|
color: color,
|
||||||
|
inset: inset,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user