mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Add bindings for box shadows, and remove nsCSSShadowArray and friends.
Differential Revision: https://phabricator.services.mozilla.com/D30547
This commit is contained in:
parent
a109fbb7c8
commit
5f6c8d9060
11 changed files with 46 additions and 220 deletions
|
@ -6,8 +6,6 @@
|
||||||
|
|
||||||
mod ns_com_ptr;
|
mod ns_com_ptr;
|
||||||
mod ns_compatibility;
|
mod ns_compatibility;
|
||||||
mod ns_css_shadow_array;
|
|
||||||
mod ns_css_shadow_item;
|
|
||||||
pub mod ns_css_value;
|
pub mod ns_css_value;
|
||||||
mod ns_style_auto_array;
|
mod ns_style_auto_array;
|
||||||
pub mod ns_style_coord;
|
pub mod ns_style_coord;
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
//! Rust helpers for Gecko's `nsCSSShadowArray`.
|
|
||||||
|
|
||||||
use crate::gecko_bindings::bindings::Gecko_AddRefCSSShadowArrayArbitraryThread;
|
|
||||||
use crate::gecko_bindings::bindings::Gecko_NewCSSShadowArray;
|
|
||||||
use crate::gecko_bindings::bindings::Gecko_ReleaseCSSShadowArrayArbitraryThread;
|
|
||||||
use crate::gecko_bindings::structs::{nsCSSShadowArray, nsCSSShadowItem, RefPtr};
|
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
use std::{ptr, slice};
|
|
||||||
|
|
||||||
impl RefPtr<nsCSSShadowArray> {
|
|
||||||
/// Replaces the current `nsCSSShadowArray` with a new one of len `len`.
|
|
||||||
pub fn replace_with_new(&mut self, len: u32) {
|
|
||||||
unsafe {
|
|
||||||
if !self.mRawPtr.is_null() {
|
|
||||||
Gecko_ReleaseCSSShadowArrayArbitraryThread(self.mRawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.mRawPtr = if len == 0 {
|
|
||||||
ptr::null_mut()
|
|
||||||
} else {
|
|
||||||
Gecko_NewCSSShadowArray(len)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the value to other `nsCSSShadowArray`, bumping and decreasing
|
|
||||||
/// refcounts as needed.
|
|
||||||
///
|
|
||||||
/// TODO(emilio): Seems like this could move to `refptr.rs`, and be more
|
|
||||||
/// generic.
|
|
||||||
pub fn copy_from(&mut self, other: &Self) {
|
|
||||||
unsafe {
|
|
||||||
if !self.mRawPtr.is_null() {
|
|
||||||
Gecko_ReleaseCSSShadowArrayArbitraryThread(self.mRawPtr);
|
|
||||||
}
|
|
||||||
if !other.mRawPtr.is_null() {
|
|
||||||
Gecko_AddRefCSSShadowArrayArbitraryThread(other.mRawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.mRawPtr = other.mRawPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for RefPtr<nsCSSShadowArray> {
|
|
||||||
type Target = [nsCSSShadowItem];
|
|
||||||
fn deref(&self) -> &[nsCSSShadowItem] {
|
|
||||||
if self.mRawPtr.is_null() {
|
|
||||||
&[]
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
slice::from_raw_parts(
|
|
||||||
(*self.mRawPtr).mArray.as_ptr(),
|
|
||||||
(*self.mRawPtr).mLength as usize,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DerefMut for RefPtr<nsCSSShadowArray> {
|
|
||||||
fn deref_mut(&mut self) -> &mut [nsCSSShadowItem] {
|
|
||||||
if self.mRawPtr.is_null() {
|
|
||||||
&mut []
|
|
||||||
} else {
|
|
||||||
unsafe {
|
|
||||||
slice::from_raw_parts_mut(
|
|
||||||
(*self.mRawPtr).mArray.as_mut_ptr(),
|
|
||||||
(*self.mRawPtr).mLength as usize,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
//! Rust helpers for Gecko's `nsCSSShadowItem`.
|
|
||||||
|
|
||||||
use crate::gecko_bindings::structs::nsCSSShadowItem;
|
|
||||||
use crate::values::computed::effects::{BoxShadow, SimpleShadow};
|
|
||||||
use app_units::Au;
|
|
||||||
|
|
||||||
impl nsCSSShadowItem {
|
|
||||||
/// Sets this item from the given box shadow.
|
|
||||||
#[inline]
|
|
||||||
pub fn set_from_box_shadow(&mut self, shadow: BoxShadow) {
|
|
||||||
self.set_from_simple_shadow(shadow.base);
|
|
||||||
self.mSpread = shadow.spread.to_i32_au();
|
|
||||||
self.mInset = shadow.inset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns this item as a box shadow.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_box_shadow(&self) -> BoxShadow {
|
|
||||||
BoxShadow {
|
|
||||||
base: self.extract_simple_shadow(),
|
|
||||||
spread: Au(self.mSpread).into(),
|
|
||||||
inset: self.mInset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets this item from the given simple shadow.
|
|
||||||
#[inline]
|
|
||||||
pub fn set_from_simple_shadow(&mut self, shadow: SimpleShadow) {
|
|
||||||
self.mXOffset = shadow.horizontal.to_i32_au();
|
|
||||||
self.mYOffset = shadow.vertical.to_i32_au();
|
|
||||||
self.mRadius = shadow.blur.0.to_i32_au();
|
|
||||||
self.mSpread = 0;
|
|
||||||
self.mInset = false;
|
|
||||||
self.mColor = shadow.color.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a simple shadow from this item.
|
|
||||||
#[inline]
|
|
||||||
fn extract_simple_shadow(&self) -> SimpleShadow {
|
|
||||||
SimpleShadow {
|
|
||||||
color: self.mColor.into(),
|
|
||||||
horizontal: Au(self.mXOffset).into(),
|
|
||||||
vertical: Au(self.mYOffset).into(),
|
|
||||||
blur: Au(self.mRadius).into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns this item as a simple shadow.
|
|
||||||
#[inline]
|
|
||||||
pub fn to_simple_shadow(&self) -> SimpleShadow {
|
|
||||||
debug_assert_eq!(self.mSpread, 0);
|
|
||||||
debug_assert_eq!(self.mInset, false);
|
|
||||||
self.extract_simple_shadow()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -174,6 +174,7 @@ class Longhand(object):
|
||||||
logical=False, logical_group=None, alias=None, extra_prefixes=None, boxed=False,
|
logical=False, logical_group=None, alias=None, extra_prefixes=None, boxed=False,
|
||||||
flags=None, allowed_in_page_rule=False, allow_quirks=False,
|
flags=None, allowed_in_page_rule=False, allow_quirks=False,
|
||||||
ignored_when_colors_disabled=False,
|
ignored_when_colors_disabled=False,
|
||||||
|
simple_vector_bindings=False,
|
||||||
vector=False, servo_restyle_damage="repaint"):
|
vector=False, servo_restyle_damage="repaint"):
|
||||||
self.name = name
|
self.name = name
|
||||||
if not spec:
|
if not spec:
|
||||||
|
@ -210,6 +211,7 @@ class Longhand(object):
|
||||||
self.allow_quirks = allow_quirks
|
self.allow_quirks = allow_quirks
|
||||||
self.ignored_when_colors_disabled = ignored_when_colors_disabled
|
self.ignored_when_colors_disabled = ignored_when_colors_disabled
|
||||||
self.is_vector = vector
|
self.is_vector = vector
|
||||||
|
self.simple_vector_bindings = simple_vector_bindings
|
||||||
|
|
||||||
# https://drafts.csswg.org/css-animations/#keyframes
|
# https://drafts.csswg.org/css-animations/#keyframes
|
||||||
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
|
||||||
|
|
|
@ -28,7 +28,6 @@ use crate::gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
|
||||||
use crate::gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
|
use crate::gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
|
||||||
use crate::gecko_bindings::bindings::Gecko_SetCursorArrayLength;
|
use crate::gecko_bindings::bindings::Gecko_SetCursorArrayLength;
|
||||||
use crate::gecko_bindings::bindings::Gecko_SetCursorImageValue;
|
use crate::gecko_bindings::bindings::Gecko_SetCursorImageValue;
|
||||||
use crate::gecko_bindings::bindings::Gecko_NewCSSShadowArray;
|
|
||||||
use crate::gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
|
use crate::gecko_bindings::bindings::Gecko_nsStyleFont_SetLang;
|
||||||
use crate::gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
|
use crate::gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
|
||||||
use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone;
|
||||||
|
@ -56,7 +55,7 @@ use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
|
||||||
use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty};
|
use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty};
|
||||||
use crate::values::computed::BorderStyle;
|
use crate::values::computed::BorderStyle;
|
||||||
use crate::values::computed::font::FontSize;
|
use crate::values::computed::font::FontSize;
|
||||||
use crate::values::computed::effects::{BoxShadow, Filter, SimpleShadow};
|
use crate::values::computed::effects::Filter;
|
||||||
use crate::values::generics::column::ColumnCount;
|
use crate::values::generics::column::ColumnCount;
|
||||||
use crate::values::generics::transform::TransformStyle;
|
use crate::values::generics::transform::TransformStyle;
|
||||||
use crate::values::generics::url::UrlOrNone;
|
use crate::values::generics::url::UrlOrNone;
|
||||||
|
@ -3455,31 +3454,7 @@ fn static_assert() {
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Effects"
|
<%self:impl_trait style_struct_name="Effects"
|
||||||
skip_longhands="box-shadow clip filter">
|
skip_longhands="clip filter">
|
||||||
pub fn set_box_shadow<I>(&mut self, v: I)
|
|
||||||
where I: IntoIterator<Item = BoxShadow>,
|
|
||||||
I::IntoIter: ExactSizeIterator
|
|
||||||
{
|
|
||||||
let v = v.into_iter();
|
|
||||||
self.gecko.mBoxShadow.replace_with_new(v.len() as u32);
|
|
||||||
for (servo, gecko_shadow) in v.zip(self.gecko.mBoxShadow.iter_mut()) {
|
|
||||||
gecko_shadow.set_from_box_shadow(servo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_box_shadow_from(&mut self, other: &Self) {
|
|
||||||
self.gecko.mBoxShadow.copy_from(&other.gecko.mBoxShadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_box_shadow(&mut self, other: &Self) {
|
|
||||||
self.copy_box_shadow_from(other)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clone_box_shadow(&self) -> longhands::box_shadow::computed_value::T {
|
|
||||||
let buf = self.gecko.mBoxShadow.iter().map(|v| v.to_box_shadow()).collect();
|
|
||||||
longhands::box_shadow::computed_value::List(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_clip(&mut self, v: longhands::clip::computed_value::T) {
|
pub fn set_clip(&mut self, v: longhands::clip::computed_value::T) {
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_AUTO;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_RECT;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_RECT;
|
||||||
|
@ -3603,7 +3578,6 @@ fn static_assert() {
|
||||||
I::IntoIter: ExactSizeIterator,
|
I::IntoIter: ExactSizeIterator,
|
||||||
{
|
{
|
||||||
use crate::values::generics::effects::Filter::*;
|
use crate::values::generics::effects::Filter::*;
|
||||||
use crate::gecko_bindings::structs::nsCSSShadowArray;
|
|
||||||
use crate::gecko_bindings::structs::nsStyleFilter;
|
use crate::gecko_bindings::structs::nsStyleFilter;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
use crate::gecko_bindings::structs::NS_STYLE_FILTER_BLUR;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS;
|
use crate::gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS;
|
||||||
|
@ -3644,19 +3618,10 @@ fn static_assert() {
|
||||||
|
|
||||||
DropShadow(shadow) => {
|
DropShadow(shadow) => {
|
||||||
gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW;
|
gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW;
|
||||||
|
unsafe {
|
||||||
fn init_shadow(filter: &mut nsStyleFilter) -> &mut nsCSSShadowArray {
|
let ref mut union = gecko_filter.__bindgen_anon_1;
|
||||||
unsafe {
|
ptr::write(union.mDropShadow.as_mut(), shadow);
|
||||||
let ref mut union = filter.__bindgen_anon_1;
|
|
||||||
let shadow_array: &mut *mut nsCSSShadowArray = union.mDropShadow.as_mut();
|
|
||||||
*shadow_array = Gecko_NewCSSShadowArray(1);
|
|
||||||
|
|
||||||
&mut **shadow_array
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let gecko_shadow = init_shadow(gecko_filter);
|
|
||||||
gecko_shadow.mArray[0].set_from_simple_shadow(shadow);
|
|
||||||
},
|
},
|
||||||
Url(ref url) => {
|
Url(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -3715,7 +3680,7 @@ fn static_assert() {
|
||||||
},
|
},
|
||||||
NS_STYLE_FILTER_DROP_SHADOW => {
|
NS_STYLE_FILTER_DROP_SHADOW => {
|
||||||
Filter::DropShadow(unsafe {
|
Filter::DropShadow(unsafe {
|
||||||
(**filter.__bindgen_anon_1.mDropShadow.as_ref()).mArray[0].to_simple_shadow()
|
(*filter.__bindgen_anon_1.mDropShadow.as_ref()).clone()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
NS_STYLE_FILTER_URL => {
|
NS_STYLE_FILTER_URL => {
|
||||||
|
@ -3761,7 +3726,7 @@ fn static_assert() {
|
||||||
|
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="InheritedText"
|
<%self:impl_trait style_struct_name="InheritedText"
|
||||||
skip_longhands="text-align text-emphasis-style text-shadow
|
skip_longhands="text-align text-emphasis-style
|
||||||
-webkit-text-stroke-width text-emphasis-position">
|
-webkit-text-stroke-width text-emphasis-position">
|
||||||
|
|
||||||
<% text_align_keyword = Keyword("text-align",
|
<% text_align_keyword = Keyword("text-align",
|
||||||
|
@ -3769,32 +3734,6 @@ fn static_assert() {
|
||||||
gecko_strip_moz_prefix=False) %>
|
gecko_strip_moz_prefix=False) %>
|
||||||
${impl_keyword('text_align', 'mTextAlign', text_align_keyword)}
|
${impl_keyword('text_align', 'mTextAlign', text_align_keyword)}
|
||||||
|
|
||||||
pub fn set_text_shadow<I>(&mut self, v: I)
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = SimpleShadow>,
|
|
||||||
I::IntoIter: ExactSizeIterator
|
|
||||||
{
|
|
||||||
let v = v.into_iter();
|
|
||||||
self.gecko.mTextShadow.replace_with_new(v.len() as u32);
|
|
||||||
for (servo, gecko_shadow) in v.zip(self.gecko.mTextShadow.iter_mut()) {
|
|
||||||
gecko_shadow.set_from_simple_shadow(servo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_text_shadow_from(&mut self, other: &Self) {
|
|
||||||
self.gecko.mTextShadow.copy_from(&other.gecko.mTextShadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_text_shadow(&mut self, other: &Self) {
|
|
||||||
self.copy_text_shadow_from(other)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(emilio): Remove by sharing representation.
|
|
||||||
pub fn clone_text_shadow(&self) -> longhands::text_shadow::computed_value::T {
|
|
||||||
let iter = self.gecko.mTextShadow.iter().map(|v| v.to_simple_shadow());
|
|
||||||
longhands::text_shadow::computed_value::List(crate::ArcSlice::from_iter(iter))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_text_emphasis_style_if_string(&mut self) {
|
fn clear_text_emphasis_style_if_string(&mut self) {
|
||||||
if self.gecko.mTextEmphasisStyle == structs::NS_STYLE_TEXT_EMPHASIS_STYLE_STRING as u8 {
|
if self.gecko.mTextEmphasisStyle == structs::NS_STYLE_TEXT_EMPHASIS_STYLE_STRING as u8 {
|
||||||
self.gecko.mTextEmphasisStyleString.truncate();
|
self.gecko.mTextEmphasisStyleString.truncate();
|
||||||
|
|
|
@ -90,12 +90,16 @@
|
||||||
// * computed_value::List is just a convenient alias that you can use for the
|
// * computed_value::List is just a convenient alias that you can use for the
|
||||||
// computed value list, since this is in the computed_value module.
|
// computed value list, since this is in the computed_value module.
|
||||||
//
|
//
|
||||||
|
// If simple_vector_bindings is true, then we don't use the complex iterator
|
||||||
|
// machinery and set_foo_from, and just compute the value like any other
|
||||||
|
// longhand.
|
||||||
<%def name="vector_longhand(name, animation_value_type=None,
|
<%def name="vector_longhand(name, animation_value_type=None,
|
||||||
vector_animation_type=None, allow_empty=False,
|
vector_animation_type=None, allow_empty=False,
|
||||||
|
simple_vector_bindings=False,
|
||||||
separator='Comma',
|
separator='Comma',
|
||||||
**kwargs)">
|
**kwargs)">
|
||||||
<%call expr="longhand(name, animation_value_type=animation_value_type, vector=True,
|
<%call expr="longhand(name, animation_value_type=animation_value_type, vector=True,
|
||||||
**kwargs)">
|
simple_vector_bindings=simple_vector_bindings, **kwargs)">
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -237,6 +241,20 @@
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
% if simple_vector_bindings:
|
||||||
|
impl From<ComputedList> for UnderlyingList<single_value::T> {
|
||||||
|
#[inline]
|
||||||
|
fn from(l: ComputedList) -> Self {
|
||||||
|
l.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<UnderlyingList<single_value::T>> for ComputedList {
|
||||||
|
#[inline]
|
||||||
|
fn from(l: UnderlyingList<single_value::T>) -> Self {
|
||||||
|
List(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
|
||||||
% if vector_animation_type:
|
% if vector_animation_type:
|
||||||
% if not animation_value_type:
|
% if not animation_value_type:
|
||||||
|
@ -345,6 +363,7 @@
|
||||||
|
|
||||||
pub use self::single_value::SpecifiedValue as SingleSpecifiedValue;
|
pub use self::single_value::SpecifiedValue as SingleSpecifiedValue;
|
||||||
|
|
||||||
|
% if not simple_vector_bindings:
|
||||||
impl SpecifiedValue {
|
impl SpecifiedValue {
|
||||||
fn compute_iter<'a, 'cx, 'cx_a>(
|
fn compute_iter<'a, 'cx, 'cx_a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
|
@ -353,6 +372,7 @@
|
||||||
computed_value::Iter::new(context, &self.0)
|
computed_value::Iter::new(context, &self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
% endif
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
impl ToComputedValue for SpecifiedValue {
|
||||||
type ComputedValue = computed_value::T;
|
type ComputedValue = computed_value::T;
|
||||||
|
@ -473,7 +493,7 @@
|
||||||
.set_writing_mode_dependency(context.builder.writing_mode);
|
.set_writing_mode_dependency(context.builder.writing_mode);
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% if property.is_vector:
|
% if property.is_vector and not property.simple_vector_bindings:
|
||||||
// In the case of a vector property we want to pass down an
|
// In the case of a vector property we want to pass down an
|
||||||
// iterator so that this can be computed without allocation.
|
// iterator so that this can be computed without allocation.
|
||||||
//
|
//
|
||||||
|
|
|
@ -23,6 +23,7 @@ ${helpers.predefined_type(
|
||||||
"BoxShadow",
|
"BoxShadow",
|
||||||
None,
|
None,
|
||||||
vector=True,
|
vector=True,
|
||||||
|
simple_vector_bindings=True,
|
||||||
animation_value_type="AnimatedBoxShadowList",
|
animation_value_type="AnimatedBoxShadowList",
|
||||||
vector_animation_type="with_zero",
|
vector_animation_type="with_zero",
|
||||||
extra_prefixes="webkit",
|
extra_prefixes="webkit",
|
||||||
|
|
|
@ -218,6 +218,7 @@ ${helpers.predefined_type(
|
||||||
vector_animation_type="with_zero",
|
vector_animation_type="with_zero",
|
||||||
animation_value_type="AnimatedTextShadowList",
|
animation_value_type="AnimatedTextShadowList",
|
||||||
ignored_when_colors_disabled=True,
|
ignored_when_colors_disabled=True,
|
||||||
|
simple_vector_bindings=True,
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||||
spec="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property",
|
spec="https://drafts.csswg.org/css-text-decor-3/#text-shadow-property",
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -3444,7 +3444,7 @@ impl<'a> StyleBuilder<'a> {
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% if not property.is_vector:
|
% if not property.is_vector or property.simple_vector_bindings:
|
||||||
/// Set the `${property.ident}` to the computed value `value`.
|
/// Set the `${property.ident}` to the computed value `value`.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set_${property.ident}(
|
pub fn set_${property.ident}(
|
||||||
|
|
|
@ -9,22 +9,18 @@ use crate::values::computed::length::Length;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::values::computed::url::ComputedUrl;
|
use crate::values::computed::url::ComputedUrl;
|
||||||
use crate::values::computed::{Angle, Number};
|
use crate::values::computed::{Angle, Number};
|
||||||
use crate::values::generics::effects::BoxShadow as GenericBoxShadow;
|
|
||||||
use crate::values::generics::effects::Filter as GenericFilter;
|
use crate::values::generics::effects::Filter as GenericFilter;
|
||||||
use crate::values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
use crate::values::generics::effects::SimpleShadow as GenericSimpleShadow;
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
use crate::values::Impossible;
|
use crate::values::Impossible;
|
||||||
|
|
||||||
/// An animated value for a single `box-shadow`.
|
/// An animated value for the `drop-shadow()` filter.
|
||||||
pub type BoxShadow = GenericBoxShadow<Color, Length, Length, Length>;
|
type AnimatedSimpleShadow = GenericSimpleShadow<Color, Length, Length>;
|
||||||
|
|
||||||
/// An animated value for a single `filter`.
|
/// An animated value for a single `filter`.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow, ComputedUrl>;
|
pub type Filter = GenericFilter<Angle, Number, Length, AnimatedSimpleShadow, ComputedUrl>;
|
||||||
|
|
||||||
/// An animated value for a single `filter`.
|
/// An animated value for a single `filter`.
|
||||||
#[cfg(not(feature = "gecko"))]
|
#[cfg(not(feature = "gecko"))]
|
||||||
pub type Filter = GenericFilter<Angle, Number, Length, Impossible, Impossible>;
|
pub type Filter = GenericFilter<Angle, Number, Length, Impossible, Impossible>;
|
||||||
|
|
||||||
/// An animated value for the `drop-shadow()` filter.
|
|
||||||
pub type SimpleShadow = GenericSimpleShadow<Color, Length, Length>;
|
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
|
#[repr(C)]
|
||||||
|
pub struct GenericBoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
|
||||||
/// The base shadow.
|
/// The base shadow.
|
||||||
pub base: SimpleShadow<Color, SizeLength, BlurShapeLength>,
|
pub base: GenericSimpleShadow<Color, SizeLength, BlurShapeLength>,
|
||||||
/// The spread radius.
|
/// The spread radius.
|
||||||
pub spread: ShapeLength,
|
pub spread: ShapeLength,
|
||||||
/// Whether this is an inset box shadow.
|
/// Whether this is an inset box shadow.
|
||||||
|
@ -30,6 +31,8 @@ pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
|
||||||
pub inset: bool,
|
pub inset: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::GenericBoxShadow as BoxShadow;
|
||||||
|
|
||||||
/// A generic value for a single `filter`.
|
/// A generic value for a single `filter`.
|
||||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||||
#[animation(no_bound(Url))]
|
#[animation(no_bound(Url))]
|
||||||
|
@ -100,7 +103,8 @@ pub enum Filter<Angle, Factor, Length, DropShadow, Url> {
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
pub struct SimpleShadow<Color, SizeLength, ShapeLength> {
|
#[repr(C)]
|
||||||
|
pub struct GenericSimpleShadow<Color, SizeLength, ShapeLength> {
|
||||||
/// Color.
|
/// Color.
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
/// Horizontal radius.
|
/// Horizontal radius.
|
||||||
|
@ -110,3 +114,5 @@ pub struct SimpleShadow<Color, SizeLength, ShapeLength> {
|
||||||
/// Blur radius.
|
/// Blur radius.
|
||||||
pub blur: ShapeLength,
|
pub blur: ShapeLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use self::GenericSimpleShadow as SimpleShadow;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue