mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
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 -->
This commit is contained in:
commit
f747ff95cd
2 changed files with 108 additions and 3 deletions
|
@ -31,6 +31,7 @@ use gecko_bindings::bindings::Gecko_FontFamilyList_AppendNamed;
|
||||||
use gecko_bindings::bindings::Gecko_FontFamilyList_Clear;
|
use gecko_bindings::bindings::Gecko_FontFamilyList_Clear;
|
||||||
use gecko_bindings::bindings::Gecko_SetCursorArrayLength;
|
use gecko_bindings::bindings::Gecko_SetCursorArrayLength;
|
||||||
use gecko_bindings::bindings::Gecko_SetCursorImage;
|
use gecko_bindings::bindings::Gecko_SetCursorImage;
|
||||||
|
use gecko_bindings::bindings::Gecko_NewCSSShadowArray;
|
||||||
use gecko_bindings::bindings::Gecko_SetListStyleImage;
|
use gecko_bindings::bindings::Gecko_SetListStyleImage;
|
||||||
use gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
use gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
||||||
use gecko_bindings::bindings::Gecko_SetListStyleType;
|
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) {
|
pub fn set_filter(&mut self, v: longhands::filter::computed_value::T) {
|
||||||
|
use cssparser::Color;
|
||||||
use properties::longhands::filter::computed_value::Filter::*;
|
use properties::longhands::filter::computed_value::Filter::*;
|
||||||
|
use gecko_bindings::structs::nsCSSShadowArray;
|
||||||
use gecko_bindings::structs::nsStyleFilter;
|
use gecko_bindings::structs::nsStyleFilter;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
use gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS;
|
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_SATURATE;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_SEPIA;
|
use gecko_bindings::structs::NS_STYLE_FILTER_SEPIA;
|
||||||
use gecko_bindings::structs::NS_STYLE_FILTER_HUE_ROTATE;
|
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){
|
fn fill_filter(m_type: u32, value: CoordDataValue, gecko_filter: &mut nsStyleFilter){
|
||||||
gecko_filter.mType = m_type;
|
gecko_filter.mType = m_type;
|
||||||
|
@ -1744,6 +1748,36 @@ 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) => {
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,10 +402,11 @@ ${helpers.predefined_type("opacity",
|
||||||
// FIXME: This prop should be animatable
|
// FIXME: This prop should be animatable
|
||||||
<%helpers:longhand name="filter" animatable="False">
|
<%helpers:longhand name="filter" animatable="False">
|
||||||
//pub use self::computed_value::T as SpecifiedValue;
|
//pub use self::computed_value::T as SpecifiedValue;
|
||||||
|
use cssparser;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::{self, ToCss};
|
||||||
use values::{CSSFloat, HasViewportPercentage};
|
use values::{CSSFloat, HasViewportPercentage};
|
||||||
use values::specified::{Angle, Length};
|
use values::specified::{Angle, CSSColor, Length};
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedValue {
|
impl HasViewportPercentage for SpecifiedValue {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
|
@ -416,7 +417,7 @@ ${helpers.predefined_type("opacity",
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct SpecifiedValue(Vec<SpecifiedFilter>);
|
pub struct SpecifiedValue(pub Vec<SpecifiedFilter>);
|
||||||
|
|
||||||
impl HasViewportPercentage for SpecifiedFilter {
|
impl HasViewportPercentage for SpecifiedFilter {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
|
@ -440,11 +441,15 @@ ${helpers.predefined_type("opacity",
|
||||||
Opacity(CSSFloat),
|
Opacity(CSSFloat),
|
||||||
Saturate(CSSFloat),
|
Saturate(CSSFloat),
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
|
% if product == "gecko":
|
||||||
|
DropShadow(Length, Length, Length, Option<CSSColor>),
|
||||||
|
% 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::specified::{Angle};
|
use values::specified::{Angle};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
@ -459,6 +464,9 @@ ${helpers.predefined_type("opacity",
|
||||||
Opacity(CSSFloat),
|
Opacity(CSSFloat),
|
||||||
Saturate(CSSFloat),
|
Saturate(CSSFloat),
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
|
% if product == "gecko":
|
||||||
|
DropShadow(Au, Au, Au, CSSColor),
|
||||||
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[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::Opacity(value) => try!(write!(dest, "opacity({})", value)),
|
||||||
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":
|
||||||
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -581,6 +602,21 @@ ${helpers.predefined_type("opacity",
|
||||||
SpecifiedFilter::Opacity(value) => try!(write!(dest, "opacity({})", value)),
|
SpecifiedFilter::Opacity(value) => try!(write!(dest, "opacity({})", value)),
|
||||||
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":
|
||||||
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -609,6 +645,9 @@ ${helpers.predefined_type("opacity",
|
||||||
"opacity" => parse_factor(input).map(SpecifiedFilter::Opacity),
|
"opacity" => parse_factor(input).map(SpecifiedFilter::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":
|
||||||
|
"drop-shadow" => parse_drop_shadow(input),
|
||||||
|
% endif
|
||||||
_ => Err(())
|
_ => 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 {
|
impl ToComputedValue for SpecifiedValue {
|
||||||
type ComputedValue = computed_value::T;
|
type ComputedValue = computed_value::T;
|
||||||
|
|
||||||
|
@ -645,6 +694,18 @@ ${helpers.predefined_type("opacity",
|
||||||
SpecifiedFilter::Opacity(factor) => computed_value::Filter::Opacity(factor),
|
SpecifiedFilter::Opacity(factor) => computed_value::Filter::Opacity(factor),
|
||||||
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":
|
||||||
|
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() }
|
}).collect() }
|
||||||
}
|
}
|
||||||
|
@ -662,6 +723,16 @@ ${helpers.predefined_type("opacity",
|
||||||
computed_value::Filter::Opacity(factor) => SpecifiedFilter::Opacity(factor),
|
computed_value::Filter::Opacity(factor) => SpecifiedFilter::Opacity(factor),
|
||||||
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":
|
||||||
|
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())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue