diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-11-22 03:25:43 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-22 03:25:43 -0600 |
commit | f747ff95cdb03cdf66735d3975de4793147ba07f (patch) | |
tree | acad0b9dbec7993985723eaf82262453e53384f1 | |
parent | cd77071d3f43def99f4501d661c3c32448c80ac1 (diff) | |
parent | 43002f2f07c03df314e8b2fca9ed8d89abec3211 (diff) | |
download | servo-f747ff95cdb03cdf66735d3975de4793147ba07f.tar.gz servo-f747ff95cdb03cdf66735d3975de4793147ba07f.zip |
Auto merge of #14218 - shinglyu:dropshadow-review, r=Manishearth
Implement drop-shadow filter for Stylo
<!-- Please describe your changes on the following line: -->
This patch got an r+ on [MozReview](https://reviewboard.mozilla.org/r/90560/#issue-summary)
---
<!-- 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 Bugzilla [#1315157](https://bugzilla.mozilla.org/show_bug.cgi?id=1315157)
<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because unit test not land-able if not enabled for servo. I'll land the test later when we enable it in Servo
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14218)
<!-- Reviewable:end -->
-rw-r--r-- | components/style/properties/gecko.mako.rs | 34 | ||||
-rw-r--r-- | components/style/properties/longhand/effects.mako.rs | 77 |
2 files changed, 108 insertions, 3 deletions
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index b8d02879368..120498e2a82 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -31,6 +31,7 @@ use gecko_bindings::bindings::Gecko_FontFamilyList_AppendNamed; use gecko_bindings::bindings::Gecko_FontFamilyList_Clear; use gecko_bindings::bindings::Gecko_SetCursorArrayLength; use gecko_bindings::bindings::Gecko_SetCursorImage; +use gecko_bindings::bindings::Gecko_NewCSSShadowArray; use gecko_bindings::bindings::Gecko_SetListStyleImage; use gecko_bindings::bindings::Gecko_SetListStyleImageNone; use gecko_bindings::bindings::Gecko_SetListStyleType; @@ -1692,7 +1693,9 @@ fn static_assert() { } pub fn set_filter(&mut self, v: longhands::filter::computed_value::T) { + use cssparser::Color; use properties::longhands::filter::computed_value::Filter::*; + use gecko_bindings::structs::nsCSSShadowArray; use gecko_bindings::structs::nsStyleFilter; use gecko_bindings::structs::NS_STYLE_FILTER_BLUR; use gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS; @@ -1703,6 +1706,7 @@ fn static_assert() { use gecko_bindings::structs::NS_STYLE_FILTER_SATURATE; use gecko_bindings::structs::NS_STYLE_FILTER_SEPIA; use gecko_bindings::structs::NS_STYLE_FILTER_HUE_ROTATE; + use gecko_bindings::structs::NS_STYLE_FILTER_DROP_SHADOW; fn fill_filter(m_type: u32, value: CoordDataValue, gecko_filter: &mut nsStyleFilter){ gecko_filter.mType = m_type; @@ -1744,6 +1748,36 @@ fn static_assert() { Sepia(factor) => fill_filter(NS_STYLE_FILTER_SEPIA, CoordDataValue::Factor(factor), gecko_filter), + DropShadow(offset_x, offset_y, blur_radius, ref color) => { + gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW; + + fn init_shadow(filter: &mut nsStyleFilter) -> &mut nsCSSShadowArray { + unsafe { + let ref mut union = filter.__bindgen_anon_1; + let mut shadow_array: &mut *mut nsCSSShadowArray = union.mDropShadow.as_mut(); + *shadow_array = Gecko_NewCSSShadowArray(1); + + &mut **shadow_array + } + } + + let mut gecko_shadow = init_shadow(gecko_filter); + gecko_shadow.mArray[0].mXOffset = offset_x.0; + gecko_shadow.mArray[0].mYOffset = offset_y.0; + gecko_shadow.mArray[0].mRadius = blur_radius.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].mColor = match *color { + Color::RGBA(rgba) => { + gecko_shadow.mArray[0].mHasColor = true; + convert_rgba_to_nscolor(&rgba) + }, + // TODO handle currentColor + // https://bugzilla.mozilla.org/show_bug.cgi?id=760345 + Color::CurrentColor => 0, + }; + } } } } diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 4619f07a4d4..7e79546f851 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -402,10 +402,11 @@ ${helpers.predefined_type("opacity", // FIXME: This prop should be animatable <%helpers:longhand name="filter" animatable="False"> //pub use self::computed_value::T as SpecifiedValue; + use cssparser; use std::fmt; - use style_traits::ToCss; + use style_traits::{self, ToCss}; use values::{CSSFloat, HasViewportPercentage}; - use values::specified::{Angle, Length}; + use values::specified::{Angle, CSSColor, Length}; impl HasViewportPercentage for SpecifiedValue { fn has_viewport_percentage(&self) -> bool { @@ -416,7 +417,7 @@ ${helpers.predefined_type("opacity", #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct SpecifiedValue(Vec<SpecifiedFilter>); + pub struct SpecifiedValue(pub Vec<SpecifiedFilter>); impl HasViewportPercentage for SpecifiedFilter { fn has_viewport_percentage(&self) -> bool { @@ -440,11 +441,15 @@ ${helpers.predefined_type("opacity", Opacity(CSSFloat), Saturate(CSSFloat), Sepia(CSSFloat), + % if product == "gecko": + DropShadow(Length, Length, Length, Option<CSSColor>), + % endif } pub mod computed_value { use app_units::Au; use values::CSSFloat; + use values::computed::CSSColor; use values::specified::{Angle}; #[derive(Clone, PartialEq, Debug)] @@ -459,6 +464,9 @@ ${helpers.predefined_type("opacity", Opacity(CSSFloat), Saturate(CSSFloat), Sepia(CSSFloat), + % if product == "gecko": + DropShadow(Au, Au, Au, CSSColor), + % endif } #[derive(Clone, PartialEq, Debug)] @@ -556,6 +564,19 @@ ${helpers.predefined_type("opacity", computed_value::Filter::Opacity(value) => try!(write!(dest, "opacity({})", value)), computed_value::Filter::Saturate(value) => try!(write!(dest, "saturate({})", value)), computed_value::Filter::Sepia(value) => try!(write!(dest, "sepia({})", value)), + % if product == "gecko": + computed_value::Filter::DropShadow(offset_x, offset_y, blur_radius, ref color) => { + try!(dest.write_str("drop-shadow(")); + try!(offset_x.to_css(dest)); + try!(dest.write_str(", ")); + try!(offset_y.to_css(dest)); + try!(dest.write_str(", ")); + try!(blur_radius.to_css(dest)); + try!(dest.write_str(", ")); + try!(color.to_css(dest)); + try!(dest.write_str(")")); + } + % endif } Ok(()) } @@ -581,6 +602,21 @@ ${helpers.predefined_type("opacity", SpecifiedFilter::Opacity(value) => try!(write!(dest, "opacity({})", value)), SpecifiedFilter::Saturate(value) => try!(write!(dest, "saturate({})", value)), SpecifiedFilter::Sepia(value) => try!(write!(dest, "sepia({})", value)), + % if product == "gecko": + SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, ref color) => { + try!(dest.write_str("drop-shadow(")); + try!(offset_x.to_css(dest)); + try!(dest.write_str(", ")); + try!(offset_y.to_css(dest)); + try!(dest.write_str(", ")); + try!(blur_radius.to_css(dest)); + if let &Some(ref color) = color { + try!(dest.write_str(", ")); + try!(color.to_css(dest)); + } + try!(dest.write_str(")")); + } + % endif } Ok(()) } @@ -609,6 +645,9 @@ ${helpers.predefined_type("opacity", "opacity" => parse_factor(input).map(SpecifiedFilter::Opacity), "saturate" => parse_factor(input).map(SpecifiedFilter::Saturate), "sepia" => parse_factor(input).map(SpecifiedFilter::Sepia), + % if product == "gecko": + "drop-shadow" => parse_drop_shadow(input), + % endif _ => Err(()) } }))); @@ -629,6 +668,16 @@ ${helpers.predefined_type("opacity", } } + % if product == "gecko": + fn parse_drop_shadow(input: &mut Parser) -> Result<SpecifiedFilter, ()> { + let offset_x = try!(specified::Length::parse(input)); + let offset_y = try!(specified::Length::parse(input)); + let blur_radius = input.try(specified::Length::parse).unwrap_or(specified::Length::from_px(0.0)); + let color = input.try(specified::CSSColor::parse).ok(); + Ok(SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, color)) + } + % endif + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -645,6 +694,18 @@ ${helpers.predefined_type("opacity", SpecifiedFilter::Opacity(factor) => computed_value::Filter::Opacity(factor), SpecifiedFilter::Saturate(factor) => computed_value::Filter::Saturate(factor), SpecifiedFilter::Sepia(factor) => computed_value::Filter::Sepia(factor), + % if product == "gecko": + SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, ref color) => { + computed_value::Filter::DropShadow( + 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 } }).collect() } } @@ -662,6 +723,16 @@ ${helpers.predefined_type("opacity", computed_value::Filter::Opacity(factor) => SpecifiedFilter::Opacity(factor), computed_value::Filter::Saturate(factor) => SpecifiedFilter::Saturate(factor), computed_value::Filter::Sepia(factor) => SpecifiedFilter::Sepia(factor), + % if product == "gecko": + computed_value::Filter::DropShadow(offset_x, offset_y, blur_radius, color) => { + SpecifiedFilter::DropShadow( + ToComputedValue::from_computed_value(&offset_x), + ToComputedValue::from_computed_value(&offset_y), + ToComputedValue::from_computed_value(&blur_radius), + Some(ToComputedValue::from_computed_value(&color)), + ) + } + % endif } }).collect()) } |