aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/properties/gecko.mako.rs43
-rw-r--r--components/style/properties/longhand/inherited_svg.mako.rs162
2 files changed, 94 insertions, 111 deletions
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index 33fe7cd5af0..c8116a975ec 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -5060,51 +5060,14 @@ clip-path
<%self:impl_trait style_struct_name="InheritedSVG"
skip_longhands="paint-order stroke-dasharray -moz-context-properties">
pub fn set_paint_order(&mut self, v: longhands::paint_order::computed_value::T) {
- use self::longhands::paint_order;
-
- if v.0 == 0 {
- self.gecko.mPaintOrder = structs::NS_STYLE_PAINT_ORDER_NORMAL as u8;
- } else {
- let mut order = 0;
-
- for pos in 0..3 {
- let geckoval = match v.bits_at(pos) {
- paint_order::FILL => structs::NS_STYLE_PAINT_ORDER_FILL as u8,
- paint_order::STROKE => structs::NS_STYLE_PAINT_ORDER_STROKE as u8,
- paint_order::MARKERS => structs::NS_STYLE_PAINT_ORDER_MARKERS as u8,
- _ => unreachable!(),
- };
- order |= geckoval << (pos * structs::NS_STYLE_PAINT_ORDER_BITWIDTH as u8);
- }
-
- self.gecko.mPaintOrder = order;
- }
+ self.gecko.mPaintOrder = v.0;
}
${impl_simple_copy('paint_order', 'mPaintOrder')}
pub fn clone_paint_order(&self) -> longhands::paint_order::computed_value::T {
- use self::longhands::paint_order::{COUNT, FILL, MARKERS, NORMAL, SHIFT, STROKE};
- use self::longhands::paint_order::computed_value::T;
-
- if self.gecko.mPaintOrder == structs::NS_STYLE_PAINT_ORDER_NORMAL as u8 {
- return T(NORMAL);
- }
-
- const PAINT_ORDER_BITWIDTH: u8 = structs::NS_STYLE_PAINT_ORDER_BITWIDTH as u8;
- let mask = (1 << PAINT_ORDER_BITWIDTH) - 1;
- let mut order = 0;
- for pos in 0..COUNT {
- let value =
- match (self.gecko.mPaintOrder >> pos * PAINT_ORDER_BITWIDTH & mask) as u32 {
- structs::NS_STYLE_PAINT_ORDER_FILL => FILL,
- structs::NS_STYLE_PAINT_ORDER_STROKE => STROKE,
- structs::NS_STYLE_PAINT_ORDER_MARKERS => MARKERS,
- _ => unreachable!(),
- };
- order |= value << (pos * SHIFT);
- };
- T(order)
+ use properties::longhands::paint_order::computed_value::T;
+ T(self.gecko.mPaintOrder)
}
pub fn set_stroke_dasharray(&mut self, v: longhands::stroke_dasharray::computed_value::T) {
diff --git a/components/style/properties/longhand/inherited_svg.mako.rs b/components/style/properties/longhand/inherited_svg.mako.rs
index 3742adb5f63..920c12f3f44 100644
--- a/components/style/properties/longhand/inherited_svg.mako.rs
+++ b/components/style/properties/longhand/inherited_svg.mako.rs
@@ -137,21 +137,27 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
use std::fmt;
use style_traits::ToCss;
- pub const NORMAL: u8 = 0;
- pub const FILL: u8 = 1;
- pub const STROKE: u8 = 2;
- pub const MARKERS: u8 = 3;
-
- // number of bits for each component
- pub const SHIFT: u8 = 2;
- // mask with above bits set
- pub const MASK: u8 = 0b11;
- // number of non-normal keyword values
- pub const COUNT: u8 = 3;
- // all keywords
- pub const ALL: [u8; 3] = [FILL, STROKE, MARKERS];
-
- /// Represented as a six-bit field, of 3 two-bit pairs
+ /// The specified value for a single CSS paint-order property.
+ #[repr(u8)]
+ #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, ToCss)]
+ pub enum PaintOrder {
+ Normal = 0,
+ Fill = 1,
+ Stroke = 2,
+ Markers = 3,
+ }
+
+ /// Number of non-normal components.
+ const COUNT: u8 = 3;
+
+ /// Number of bits for each component
+ const SHIFT: u8 = 2;
+
+ /// Mask with above bits set
+ const MASK: u8 = 0b11;
+
+ /// The specified value is tree `PaintOrder` values packed into the
+ /// bitfields below, as a six-bit field, of 3 two-bit pairs
///
/// Each pair can be set to FILL, STROKE, or MARKERS
/// Lowest significant bit pairs are highest priority.
@@ -165,74 +171,83 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
#[derive(Clone, Copy, Debug, PartialEq, ToComputedValue)]
pub struct SpecifiedValue(pub u8);
+ impl SpecifiedValue {
+ fn normal() -> Self {
+ SpecifiedValue(0)
+ }
+ }
+
pub mod computed_value {
pub use super::SpecifiedValue as T;
}
pub fn get_initial_value() -> SpecifiedValue {
- SpecifiedValue(NORMAL)
+ SpecifiedValue::normal()
}
impl SpecifiedValue {
- pub fn bits_at(&self, pos: u8) -> u8 {
- (self.0 >> pos * SHIFT) & MASK
+ fn order_at(&self, pos: u8) -> PaintOrder {
+ // Safe because PaintOrder covers all possible patterns.
+ unsafe { ::std::mem::transmute((self.0 >> pos * SHIFT) & MASK) }
}
}
- pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
- -> Result<SpecifiedValue,ParseError<'i>> {
+ pub fn parse<'i, 't>(
+ _context: &ParserContext,
+ input: &mut Parser<'i, 't>
+ ) -> Result<SpecifiedValue,ParseError<'i>> {
if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
- Ok(SpecifiedValue(0))
- } else {
- let mut value = 0;
- // bitfield representing what we've seen so far
- // bit 1 is fill, bit 2 is stroke, bit 3 is markers
- let mut seen = 0;
- let mut pos = 0;
-
- loop {
- let result: Result<_, ParseError> = input.try(|i| {
- try_match_ident_ignore_ascii_case! { i.expect_ident()?,
- "fill" => Ok(FILL),
- "stroke" => Ok(STROKE),
- "markers" => Ok(MARKERS),
- }
- });
-
- match result {
- Ok(val) => {
- if (seen & (1 << val)) != 0 {
- // don't parse the same ident twice
- return Err(StyleParseError::UnspecifiedError.into())
- } else {
- value |= val << (pos * SHIFT);
- seen |= 1 << val;
- pos += 1;
- }
- }
- Err(_) => break,
+ return Ok(SpecifiedValue::normal())
+ }
+
+ let mut value = 0;
+ // bitfield representing what we've seen so far
+ // bit 1 is fill, bit 2 is stroke, bit 3 is markers
+ let mut seen = 0;
+ let mut pos = 0;
+
+ loop {
+ let result: Result<_, ParseError> = input.try(|i| {
+ try_match_ident_ignore_ascii_case! { i.expect_ident()?,
+ "fill" => Ok(PaintOrder::Fill),
+ "stroke" => Ok(PaintOrder::Stroke),
+ "markers" => Ok(PaintOrder::Markers),
}
- }
+ });
- if value == 0 {
- // couldn't find any keyword
- Err(StyleParseError::UnspecifiedError.into())
- } else {
- // fill in rest
- for i in pos..COUNT {
- for paint in &ALL {
- // if not seen, set bit at position, mark as seen
- if (seen & (1 << paint)) == 0 {
- seen |= 1 << paint;
- value |= paint << (i * SHIFT);
- break;
- }
+ match result {
+ Ok(val) => {
+ if (seen & (1 << val as u8)) != 0 {
+ // don't parse the same ident twice
+ return Err(StyleParseError::UnspecifiedError.into())
}
+
+ value |= (val as u8) << (pos * SHIFT);
+ seen |= 1 << (val as u8);
+ pos += 1;
}
+ Err(_) => break,
+ }
+ }
+
+ if value == 0 {
+ // Couldn't find any keyword
+ return Err(StyleParseError::UnspecifiedError.into())
+ }
- Ok(SpecifiedValue(value))
+ // fill in rest
+ for i in pos..COUNT {
+ for paint in 0..COUNT {
+ // if not seen, set bit at position, mark as seen
+ if (seen & (1 << paint)) == 0 {
+ seen |= 1 << paint;
+ value |= paint << (i * SHIFT);
+ break;
+ }
}
}
+
+ Ok(SpecifiedValue(value))
}
impl ToCss for SpecifiedValue {
@@ -241,16 +256,21 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
return dest.write_str("normal")
}
- for pos in 0..COUNT {
+ let mut last_pos_to_serialize = 0;
+ for i in (1..COUNT).rev() {
+ let component = self.order_at(i);
+ let earlier_component = self.order_at(i - 1);
+ if component < earlier_component {
+ last_pos_to_serialize = i - 1;
+ break;
+ }
+ }
+
+ for pos in 0..last_pos_to_serialize + 1 {
if pos != 0 {
dest.write_str(" ")?
}
- match self.bits_at(pos) {
- FILL => dest.write_str("fill")?,
- STROKE => dest.write_str("stroke")?,
- MARKERS => dest.write_str("markers")?,
- _ => unreachable!(),
- }
+ self.order_at(pos).to_css(dest)?;
}
Ok(())
}