mirror of
https://github.com/servo/servo.git
synced 2025-08-08 06:55:31 +01:00
stylo: Add Gecko bindings for <paint>, use for stroke/fill
MozReview-Commit-ID: 4QKKzJ1DVYP
This commit is contained in:
parent
fabc1b875b
commit
51b03fbc7d
6 changed files with 124 additions and 14 deletions
|
@ -365,6 +365,7 @@ mod bindings {
|
||||||
"nsStylePadding",
|
"nsStylePadding",
|
||||||
"nsStylePosition",
|
"nsStylePosition",
|
||||||
"nsStyleSVG",
|
"nsStyleSVG",
|
||||||
|
"nsStyleSVGPaint",
|
||||||
"nsStyleSVGReset",
|
"nsStyleSVGReset",
|
||||||
"nsStyleTable",
|
"nsStyleTable",
|
||||||
"nsStyleTableBorder",
|
"nsStyleTableBorder",
|
||||||
|
@ -568,6 +569,7 @@ mod bindings {
|
||||||
"nsStylePosition",
|
"nsStylePosition",
|
||||||
"nsStyleQuoteValues",
|
"nsStyleQuoteValues",
|
||||||
"nsStyleSVG",
|
"nsStyleSVG",
|
||||||
|
"nsStyleSVGPaint",
|
||||||
"nsStyleSVGReset",
|
"nsStyleSVGReset",
|
||||||
"nsStyleTable",
|
"nsStyleTable",
|
||||||
"nsStyleTableBorder",
|
"nsStyleTableBorder",
|
||||||
|
|
|
@ -118,6 +118,9 @@ unsafe impl Sync for nsStyleQuoteValues {}
|
||||||
use gecko_bindings::structs::nsStyleSVG;
|
use gecko_bindings::structs::nsStyleSVG;
|
||||||
unsafe impl Send for nsStyleSVG {}
|
unsafe impl Send for nsStyleSVG {}
|
||||||
unsafe impl Sync for nsStyleSVG {}
|
unsafe impl Sync for nsStyleSVG {}
|
||||||
|
use gecko_bindings::structs::nsStyleSVGPaint;
|
||||||
|
unsafe impl Send for nsStyleSVGPaint {}
|
||||||
|
unsafe impl Sync for nsStyleSVGPaint {}
|
||||||
use gecko_bindings::structs::nsStyleSVGReset;
|
use gecko_bindings::structs::nsStyleSVGReset;
|
||||||
unsafe impl Send for nsStyleSVGReset {}
|
unsafe impl Send for nsStyleSVGReset {}
|
||||||
unsafe impl Sync for nsStyleSVGReset {}
|
unsafe impl Sync for nsStyleSVGReset {}
|
||||||
|
@ -719,6 +722,17 @@ extern "C" {
|
||||||
pub fn Gecko_nsStyleFilter_SetURLValue(effects: *mut nsStyleFilter,
|
pub fn Gecko_nsStyleFilter_SetURLValue(effects: *mut nsStyleFilter,
|
||||||
uri: ServoBundledURI);
|
uri: ServoBundledURI);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVGPaint_CopyFrom(dest: *mut nsStyleSVGPaint,
|
||||||
|
src: *const nsStyleSVGPaint);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVGPaint_SetURLValue(paint: *mut nsStyleSVGPaint,
|
||||||
|
uri: ServoBundledURI);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVGPaint_Reset(paint: *mut nsStyleSVGPaint);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_FillAllBackgroundLists(layers: *mut nsStyleImageLayers,
|
pub fn Gecko_FillAllBackgroundLists(layers: *mut nsStyleImageLayers,
|
||||||
max_len: u32);
|
max_len: u32);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use cssparser::Color;
|
||||||
use custom_properties::ComputedValuesMap;
|
use custom_properties::ComputedValuesMap;
|
||||||
use gecko_bindings::bindings;
|
use gecko_bindings::bindings;
|
||||||
% for style_struct in data.style_structs:
|
% for style_struct in data.style_structs:
|
||||||
|
@ -274,6 +275,19 @@ def set_gecko_property(ffi_name, expr):
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
||||||
|
/// Convert a Servo color into an nscolor; with currentColor as 0
|
||||||
|
///
|
||||||
|
/// Call sites will need to be updated after https://bugzilla.mozilla.org/show_bug.cgi?id=760345
|
||||||
|
fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
|
||||||
|
match color {
|
||||||
|
Color::RGBA(rgba) => {
|
||||||
|
convert_rgba_to_nscolor(&rgba)
|
||||||
|
},
|
||||||
|
Color::CurrentColor => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<%def name="impl_color_setter(ident, gecko_ffi_name, complex_color=True)">
|
<%def name="impl_color_setter(ident, gecko_ffi_name, complex_color=True)">
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -281,12 +295,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% if complex_color:
|
% if complex_color:
|
||||||
let result = v.into();
|
let result = v.into();
|
||||||
% else:
|
% else:
|
||||||
use cssparser::Color;
|
let result = color_to_nscolor_zero_currentcolor(v);
|
||||||
let result = match v {
|
|
||||||
Color::RGBA(rgba) => convert_rgba_to_nscolor(&rgba),
|
|
||||||
// FIXME #13547
|
|
||||||
Color::CurrentColor => 0,
|
|
||||||
};
|
|
||||||
% endif
|
% endif
|
||||||
${set_gecko_property(gecko_ffi_name, "result")}
|
${set_gecko_property(gecko_ffi_name, "result")}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +315,6 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% if complex_color:
|
% if complex_color:
|
||||||
${get_gecko_property(gecko_ffi_name)}.into()
|
${get_gecko_property(gecko_ffi_name)}.into()
|
||||||
% else:
|
% else:
|
||||||
use cssparser::Color;
|
|
||||||
Color::RGBA(convert_nscolor_to_rgba(${get_gecko_property(gecko_ffi_name)}))
|
Color::RGBA(convert_nscolor_to_rgba(${get_gecko_property(gecko_ffi_name)}))
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
@ -369,6 +377,54 @@ def set_gecko_property(ffi_name, expr):
|
||||||
% endif
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
<%def name="impl_svg_paint(ident, gecko_ffi_name, need_clone=False, complex_color=True)">
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn set_${ident}(&mut self, mut v: longhands::${ident}::computed_value::T) {
|
||||||
|
use values::computed::SVGPaintKind;
|
||||||
|
use self::structs::nsStyleSVGPaintType;
|
||||||
|
|
||||||
|
let ref mut paint = ${get_gecko_property(gecko_ffi_name)};
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVGPaint_Reset(paint);
|
||||||
|
}
|
||||||
|
let fallback = v.fallback.take();
|
||||||
|
match v.kind {
|
||||||
|
SVGPaintKind::None => return,
|
||||||
|
SVGPaintKind::ContextFill => {
|
||||||
|
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextFill;
|
||||||
|
}
|
||||||
|
SVGPaintKind::ContextStroke => {
|
||||||
|
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke;
|
||||||
|
}
|
||||||
|
SVGPaintKind::PaintServer(url) => {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.for_ffi());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SVGPaintKind::Color(color) => {
|
||||||
|
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color;
|
||||||
|
unsafe {
|
||||||
|
*paint.mPaint.mColor.as_mut() = color_to_nscolor_zero_currentcolor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fallback) = fallback {
|
||||||
|
paint.mFallbackColor = color_to_nscolor_zero_currentcolor(fallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVGPaint_CopyFrom(
|
||||||
|
&mut ${get_gecko_property(gecko_ffi_name)},
|
||||||
|
& ${get_gecko_property(gecko_ffi_name, "other")}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
|
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
|
@ -543,6 +599,7 @@ impl Debug for ${style_struct.gecko_struct_name} {
|
||||||
"Number": impl_simple,
|
"Number": impl_simple,
|
||||||
"Opacity": impl_simple,
|
"Opacity": impl_simple,
|
||||||
"CSSColor": impl_color,
|
"CSSColor": impl_color,
|
||||||
|
"SVGPaint": impl_svg_paint,
|
||||||
}
|
}
|
||||||
|
|
||||||
def longhand_method(longhand):
|
def longhand_method(longhand):
|
||||||
|
@ -2130,7 +2187,6 @@ fn static_assert() {
|
||||||
<%self:impl_trait style_struct_name="Effects"
|
<%self:impl_trait style_struct_name="Effects"
|
||||||
skip_longhands="box-shadow filter">
|
skip_longhands="box-shadow filter">
|
||||||
pub fn set_box_shadow(&mut self, v: longhands::box_shadow::computed_value::T) {
|
pub fn set_box_shadow(&mut self, v: longhands::box_shadow::computed_value::T) {
|
||||||
use cssparser::Color;
|
|
||||||
|
|
||||||
self.gecko.mBoxShadow.replace_with_new(v.0.len() as u32);
|
self.gecko.mBoxShadow.replace_with_new(v.0.len() as u32);
|
||||||
|
|
||||||
|
@ -2161,8 +2217,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_box_shadow(&self) -> longhands::box_shadow::computed_value::T {
|
pub fn clone_box_shadow(&self) -> longhands::box_shadow::computed_value::T {
|
||||||
use cssparser::Color;
|
|
||||||
|
|
||||||
let buf = self.gecko.mBoxShadow.iter().map(|shadow| {
|
let buf = self.gecko.mBoxShadow.iter().map(|shadow| {
|
||||||
longhands::box_shadow::single_value::computed_value::T {
|
longhands::box_shadow::single_value::computed_value::T {
|
||||||
offset_x: Au(shadow.mXOffset),
|
offset_x: Au(shadow.mXOffset),
|
||||||
|
@ -2177,7 +2231,6 @@ 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::nsCSSShadowArray;
|
||||||
use gecko_bindings::structs::nsStyleFilter;
|
use gecko_bindings::structs::nsStyleFilter;
|
||||||
|
@ -2304,7 +2357,6 @@ fn static_assert() {
|
||||||
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
|
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
|
||||||
|
|
||||||
pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) {
|
pub fn set_text_shadow(&mut self, v: longhands::text_shadow::computed_value::T) {
|
||||||
use cssparser::Color;
|
|
||||||
self.gecko.mTextShadow.replace_with_new(v.0.len() as u32);
|
self.gecko.mTextShadow.replace_with_new(v.0.len() as u32);
|
||||||
|
|
||||||
for (servo, gecko_shadow) in v.0.into_iter()
|
for (servo, gecko_shadow) in v.0.into_iter()
|
||||||
|
@ -2332,7 +2384,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_text_shadow(&self) -> longhands::text_shadow::computed_value::T {
|
pub fn clone_text_shadow(&self) -> longhands::text_shadow::computed_value::T {
|
||||||
use cssparser::Color;
|
|
||||||
|
|
||||||
let buf = self.gecko.mTextShadow.iter().map(|shadow| {
|
let buf = self.gecko.mTextShadow.iter().map(|shadow| {
|
||||||
longhands::text_shadow::computed_value::TextShadow {
|
longhands::text_shadow::computed_value::TextShadow {
|
||||||
|
@ -2720,6 +2771,11 @@ clip-path
|
||||||
}
|
}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
|
<%self:impl_trait style_struct_name="InheritedSVG"
|
||||||
|
skip_longhands=""
|
||||||
|
skip_additionals="*">
|
||||||
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Color"
|
<%self:impl_trait style_struct_name="Color"
|
||||||
skip_longhands="*">
|
skip_longhands="*">
|
||||||
pub fn set_color(&mut self, v: longhands::color::computed_value::T) {
|
pub fn set_color(&mut self, v: longhands::color::computed_value::T) {
|
||||||
|
|
|
@ -33,6 +33,14 @@ ${helpers.single_keyword("color-interpolation-filters", "auto sRGB linearRGB",
|
||||||
animatable=False,
|
animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationFiltersProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"fill", "SVGPaint",
|
||||||
|
"::values::computed::SVGPaint::black()",
|
||||||
|
products="gecko",
|
||||||
|
animatable=False,
|
||||||
|
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", "Opacity", "1.0",
|
||||||
products="gecko", animatable=False,
|
products="gecko", animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty")}
|
||||||
|
@ -49,6 +57,14 @@ ${helpers.single_keyword("shape-rendering",
|
||||||
animatable=False,
|
animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"stroke", "SVGPaint",
|
||||||
|
"Default::default()",
|
||||||
|
products="gecko",
|
||||||
|
animatable=False,
|
||||||
|
boxed=True,
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint")}
|
||||||
|
|
||||||
${helpers.single_keyword("stroke-linecap", "butt round square",
|
${helpers.single_keyword("stroke-linecap", "butt round square",
|
||||||
products="gecko", animatable=False,
|
products="gecko", animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinecapProperty")}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use font_metrics::FontMetricsProvider;
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
use super::{CSSFloat, specified};
|
use super::{CSSFloat, RGBA, specified};
|
||||||
|
|
||||||
pub use cssparser::Color as CSSColor;
|
pub use cssparser::Color as CSSColor;
|
||||||
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image};
|
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image};
|
||||||
|
@ -197,6 +197,26 @@ pub struct SVGPaint {
|
||||||
pub fallback: Option<CSSColor>,
|
pub fallback: Option<CSSColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SVGPaint {
|
||||||
|
fn default() -> Self {
|
||||||
|
SVGPaint {
|
||||||
|
kind: SVGPaintKind::None,
|
||||||
|
fallback: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SVGPaint {
|
||||||
|
/// Opaque black color
|
||||||
|
pub fn black() -> Self {
|
||||||
|
let rgba = RGBA::from_floats(0., 0., 0., 1.);
|
||||||
|
SVGPaint {
|
||||||
|
kind: SVGPaintKind::Color(CSSColor::RGBA(rgba)),
|
||||||
|
fallback: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An SVG paint value without the fallback
|
/// An SVG paint value without the fallback
|
||||||
///
|
///
|
||||||
/// Whereas the spec only allows PaintServer
|
/// Whereas the spec only allows PaintServer
|
||||||
|
|
|
@ -670,6 +670,8 @@ impl Shadow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_viewport_percentage!(SVGPaint);
|
||||||
|
|
||||||
/// An SVG paint value
|
/// An SVG paint value
|
||||||
///
|
///
|
||||||
/// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
|
/// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue