mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Add context-{fill,stroke}-opacity support to {fill,stroke}-opacity.
This commit is contained in:
parent
7827ca6bb5
commit
ef4352d2a5
8 changed files with 149 additions and 7 deletions
|
@ -634,6 +634,67 @@ def set_gecko_property(ffi_name, expr):
|
|||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_svg_opacity(ident, gecko_ffi_name, need_clone=False)">
|
||||
<% source_prefix = ident.split("_")[0].upper() + "_OPACITY_SOURCE" %>
|
||||
|
||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||
use gecko_bindings::structs::nsStyleSVG_${source_prefix}_MASK as MASK;
|
||||
use gecko_bindings::structs::nsStyleSVG_${source_prefix}_SHIFT as SHIFT;
|
||||
use gecko_bindings::structs::nsStyleSVGOpacitySource::*;
|
||||
use values::generics::svg::SVGOpacity;
|
||||
self.gecko.mContextFlags &= !MASK;
|
||||
match v {
|
||||
SVGOpacity::Opacity(opacity) => {
|
||||
self.gecko.mContextFlags |=
|
||||
(eStyleSVGOpacitySource_Normal as u8) << SHIFT;
|
||||
self.gecko.${gecko_ffi_name} = opacity;
|
||||
}
|
||||
SVGOpacity::ContextFillOpacity => {
|
||||
self.gecko.mContextFlags |=
|
||||
(eStyleSVGOpacitySource_ContextFillOpacity as u8) << SHIFT;
|
||||
self.gecko.${gecko_ffi_name} = 1.;
|
||||
}
|
||||
SVGOpacity::ContextStrokeOpacity => {
|
||||
self.gecko.mContextFlags |=
|
||||
(eStyleSVGOpacitySource_ContextStrokeOpacity as u8) << SHIFT;
|
||||
self.gecko.${gecko_ffi_name} = 1.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
use gecko_bindings::structs::nsStyleSVG_${source_prefix}_MASK as MASK;
|
||||
self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
|
||||
self.gecko.mContextFlags =
|
||||
(self.gecko.mContextFlags & !MASK) |
|
||||
(other.gecko.mContextFlags & MASK);
|
||||
}
|
||||
|
||||
pub fn reset_${ident}(&mut self, other: &Self) {
|
||||
self.copy_${ident}_from(other)
|
||||
}
|
||||
|
||||
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
|
||||
use gecko_bindings::structs::nsStyleSVG_${source_prefix}_MASK as MASK;
|
||||
use gecko_bindings::structs::nsStyleSVG_${source_prefix}_SHIFT as SHIFT;
|
||||
use gecko_bindings::structs::nsStyleSVGOpacitySource::*;
|
||||
use values::generics::svg::SVGOpacity;
|
||||
|
||||
let source = (self.gecko.mContextFlags & MASK) >> SHIFT;
|
||||
if source == eStyleSVGOpacitySource_Normal as u8 {
|
||||
return SVGOpacity::Opacity(self.gecko.${gecko_ffi_name});
|
||||
} else {
|
||||
debug_assert_eq!(self.gecko.${gecko_ffi_name}, 1.0);
|
||||
if source == eStyleSVGOpacitySource_ContextFillOpacity as u8 {
|
||||
SVGOpacity::ContextFillOpacity
|
||||
} else {
|
||||
debug_assert_eq!(source, eStyleSVGOpacitySource_ContextStrokeOpacity as u8);
|
||||
SVGOpacity::ContextStrokeOpacity
|
||||
}
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
|
||||
<%def name="impl_svg_paint(ident, gecko_ffi_name, need_clone=False)">
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set_${ident}(&mut self, mut v: longhands::${ident}::computed_value::T) {
|
||||
|
@ -1024,6 +1085,7 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
"Color": impl_color,
|
||||
"RGBAColor": impl_rgba_color,
|
||||
"SVGLength": impl_svg_length,
|
||||
"SVGOpacity": impl_svg_opacity,
|
||||
"SVGPaint": impl_svg_paint,
|
||||
"UrlOrNone": impl_css_url,
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToC
|
|||
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
|
||||
use values::generics::effects::Filter;
|
||||
use values::generics::position as generic_position;
|
||||
use values::generics::svg::{SVGLength, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
||||
use values::generics::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
||||
|
||||
/// A trait used to implement various procedures used during animation.
|
||||
pub trait Animatable: Sized {
|
||||
|
@ -3116,6 +3116,45 @@ impl<LengthType> ToAnimatedZero for SVGStrokeDashArray<LengthType>
|
|||
}
|
||||
}
|
||||
|
||||
impl<OpacityType> Animatable for SVGOpacity<OpacityType>
|
||||
where OpacityType: Animatable + Clone
|
||||
{
|
||||
#[inline]
|
||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||
match (self, other) {
|
||||
(&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => {
|
||||
this.add_weighted(other, self_portion, other_portion).map(SVGOpacity::Opacity)
|
||||
}
|
||||
_ => {
|
||||
Ok(if self_portion > other_portion { self.clone() } else { other.clone() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||
match (self, other) {
|
||||
(&SVGOpacity::Opacity(ref this), &SVGOpacity::Opacity(ref other)) => {
|
||||
this.compute_distance(other)
|
||||
}
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<OpacityType> ToAnimatedZero for SVGOpacity<OpacityType>
|
||||
where OpacityType: ToAnimatedZero + Clone
|
||||
{
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
match self {
|
||||
&SVGOpacity::Opacity(ref opacity) =>
|
||||
opacity.to_animated_zero().map(SVGOpacity::Opacity),
|
||||
other => Ok(other.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<%
|
||||
FILTER_FUNCTIONS = [ 'Blur', 'Brightness', 'Contrast', 'Grayscale',
|
||||
'HueRotate', 'Invert', 'Opacity', 'Saturate',
|
||||
|
|
|
@ -39,7 +39,7 @@ ${helpers.predefined_type(
|
|||
boxed=True,
|
||||
spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint")}
|
||||
|
||||
${helpers.predefined_type("fill-opacity", "Opacity", "1.0",
|
||||
${helpers.predefined_type("fill-opacity", "SVGOpacity", "Default::default()",
|
||||
products="gecko", animation_value_type="ComputedValue",
|
||||
spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}
|
||||
|
||||
|
@ -85,7 +85,7 @@ ${helpers.predefined_type("stroke-miterlimit", "Number", "4.0",
|
|||
animation_value_type="ComputedValue",
|
||||
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeMiterlimitProperty")}
|
||||
|
||||
${helpers.predefined_type("stroke-opacity", "Opacity", "1.0",
|
||||
${helpers.predefined_type("stroke-opacity", "SVGOpacity", "Default::default()",
|
||||
products="gecko", animation_value_type="ComputedValue",
|
||||
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ pub use super::specified::url::SpecifiedUrl;
|
|||
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage};
|
||||
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength, Percentage};
|
||||
pub use self::position::Position;
|
||||
pub use self::svg::{SVGLength, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
||||
pub use self::transform::{TimingFunction, TransformOrigin};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use app_units::Au;
|
||||
use values::{Either, RGBA};
|
||||
use values::computed::LengthOrPercentageOrNumber;
|
||||
use values::computed::{LengthOrPercentageOrNumber, Opacity};
|
||||
use values::generics::svg as generic;
|
||||
|
||||
/// Computed SVG Paint value
|
||||
|
@ -51,3 +51,12 @@ impl Default for SVGStrokeDashArray {
|
|||
generic::SVGStrokeDashArray::Values(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
/// <opacity-value> | context-fill-opacity | context-stroke-opacity
|
||||
pub type SVGOpacity = generic::SVGOpacity<Opacity>;
|
||||
|
||||
impl Default for SVGOpacity {
|
||||
fn default() -> Self {
|
||||
generic::SVGOpacity::Opacity(1.)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,3 +138,16 @@ impl<LengthType> ToCss for SVGStrokeDashArray<LengthType> where LengthType: ToCs
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An SVG opacity value accepts `context-{fill,stroke}-opacity` in
|
||||
/// addition to opacity value.
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, HasViewportPercentage, ToComputedValue, ToCss)]
|
||||
pub enum SVGOpacity<OpacityType> {
|
||||
/// `<opacity-value>`
|
||||
Opacity(OpacityType),
|
||||
/// `context-fill-opacity`
|
||||
ContextFillOpacity,
|
||||
/// `context-stroke-opacity`
|
||||
ContextStrokeOpacity,
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength};
|
|||
pub use self::length::{NoCalcLength, Percentage, ViewportPercentageLength};
|
||||
pub use self::rect::LengthOrNumberRect;
|
||||
pub use self::position::{Position, PositionComponent};
|
||||
pub use self::svg::{SVGLength, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
||||
pub use self::transform::{TimingFunction, TransformOrigin};
|
||||
pub use super::generics::grid::GridLine;
|
||||
|
|
|
@ -8,7 +8,7 @@ use cssparser::Parser;
|
|||
use parser::{Parse, ParserContext};
|
||||
use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseError};
|
||||
use values::generics::svg as generic;
|
||||
use values::specified::LengthOrPercentageOrNumber;
|
||||
use values::specified::{LengthOrPercentageOrNumber, Opacity};
|
||||
use values::specified::color::RGBAColor;
|
||||
|
||||
/// Specified SVG Paint value
|
||||
|
@ -87,3 +87,22 @@ impl Parse for SVGStrokeDashArray {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <opacity-value> | context-fill-opacity | context-stroke-opacity
|
||||
pub type SVGOpacity = generic::SVGOpacity<Opacity>;
|
||||
|
||||
impl Parse for SVGOpacity {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
if let Ok(opacity) = input.try(|i| Opacity::parse(context, i)) {
|
||||
Ok(generic::SVGOpacity::Opacity(opacity))
|
||||
} else if is_context_value_enabled() {
|
||||
try_match_ident_ignore_ascii_case! { input.expect_ident()?,
|
||||
"context-fill-opacity" => Ok(generic::SVGOpacity::ContextFillOpacity),
|
||||
"context-stroke-opacity" => Ok(generic::SVGOpacity::ContextStrokeOpacity),
|
||||
}
|
||||
} else {
|
||||
Err(StyleParseError::UnspecifiedError.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue