diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-04-28 09:37:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-28 09:37:25 -0400 |
commit | da43a33fb11d0ebd640d5173f98be9f3571959eb (patch) | |
tree | d803a5f9180d3ab8cfbff08dcc92f3ecd71e8421 | |
parent | 625634a0275bb1ea1e918407368ab70990a728f1 (diff) | |
parent | 1eec31ace044963ff15e43e4edf2fe42aaa8ebdd (diff) | |
download | servo-da43a33fb11d0ebd640d5173f98be9f3571959eb.tar.gz servo-da43a33fb11d0ebd640d5173f98be9f3571959eb.zip |
Auto merge of #20692 - emilio:gecko-sync-next, r=emilio,Manishearth,nox
style: Sync more changes from m-c.
<!-- 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/20692)
<!-- Reviewable:end -->
67 files changed, 2095 insertions, 1771 deletions
diff --git a/.travis.yml b/.travis.yml index 278c18bd260..dec7987e178 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,6 @@ matrix: - ./mach build -d --verbose - ./mach test-unit - ./mach clean - - ./mach build-geckolib - - ./mach test-stylo - bash etc/ci/lockfile_changed.sh cache: directories: diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 09578168ea7..2cf92e6a328 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -19,7 +19,7 @@ use std::rc::Rc; use std::str; use std::sync::Arc; use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; -use style::computed_values::{font_stretch, font_variant_caps, font_weight}; +use style::computed_values::{font_stretch, font_style, font_variant_caps, font_weight}; use style::properties::style_structs::Font as FontStyleStruct; use style::values::computed::font::SingleFontFamily; use text::Shaper; @@ -47,18 +47,24 @@ static TEXT_SHAPING_PERFORMANCE_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; // resources needed by the graphics layer to draw glyphs. pub trait FontHandleMethods: Sized { - fn new_from_template(fctx: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>) - -> Result<Self, ()>; + fn new_from_template( + fctx: &FontContextHandle, + template: Arc<FontTemplateData>, + pt_size: Option<Au>, + ) -> Result<Self, ()>; + fn template(&self) -> Arc<FontTemplateData>; fn family_name(&self) -> String; fn face_name(&self) -> Option<String>; - fn is_italic(&self) -> bool; + + fn style(&self) -> font_style::T; fn boldness(&self) -> font_weight::T; fn stretchiness(&self) -> font_stretch::T; fn glyph_index(&self, codepoint: char) -> Option<GlyphId>; fn glyph_h_advance(&self, GlyphId) -> Option<FractionalPixel>; fn glyph_h_kerning(&self, glyph0: GlyphId, glyph1: GlyphId) -> FractionalPixel; + /// Can this font do basic horizontal LTR shaping without Harfbuzz? fn can_do_fast_shaping(&self) -> bool; fn metrics(&self) -> FontMetrics; diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs index fdb48e519fe..39375191ae1 100644 --- a/components/gfx/font_cache_thread.rs +++ b/components/gfx/font_cache_thread.rs @@ -18,14 +18,11 @@ use platform::font_list::system_default_family; use platform::font_template::FontTemplateData; use servo_atoms::Atom; use servo_url::ServoUrl; +use std::{fmt, f32, mem, thread}; use std::borrow::ToOwned; use std::collections::HashMap; -use std::fmt; -use std::mem; use std::ops::Deref; use std::sync::{Arc, Mutex}; -use std::thread; -use std::u32; use style::font_face::{EffectiveSources, Source}; use style::values::computed::font::{SingleFontFamily, FamilyName}; use webrender_api; @@ -63,7 +60,7 @@ impl FontTemplates { // We didn't find an exact match. Do more expensive fuzzy matching. // TODO(#190): Do a better job. - let (mut best_template_data, mut best_distance) = (None, u32::MAX); + let (mut best_template_data, mut best_distance) = (None, f32::MAX); for template in &mut self.templates { if let Some((template_data, distance)) = template.data_for_approximate_descriptor(fctx, desc) { diff --git a/components/gfx/font_template.rs b/components/gfx/font_template.rs index 239bfcdd8c9..13c531f4d43 100644 --- a/components/gfx/font_template.rs +++ b/components/gfx/font_template.rs @@ -10,7 +10,6 @@ use servo_atoms::Atom; use std::fmt::{Debug, Error, Formatter}; use std::io::Error as IoError; use std::sync::{Arc, Weak}; -use std::u32; use style::computed_values::font_stretch::T as FontStretch; use style::computed_values::font_style::T as FontStyle; use style::properties::style_structs::Font as FontStyleStruct; @@ -20,21 +19,35 @@ use style::values::computed::font::FontWeight; /// to be expanded or refactored when we support more of the font styling parameters. /// /// NB: If you change this, you will need to update `style::properties::compute_font_hash()`. -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct FontTemplateDescriptor { pub weight: FontWeight, pub stretch: FontStretch, - pub italic: bool, + pub style: FontStyle, } +fn style_to_number(s: &FontStyle) -> f32 { + use style::values::generics::font::FontStyle as GenericFontStyle; + + match *s { + GenericFontStyle::Normal => 0., + GenericFontStyle::Italic => FontStyle::default_angle().0.degrees(), + GenericFontStyle::Oblique(ref angle) => angle.0.degrees(), + } +} + + impl FontTemplateDescriptor { #[inline] - pub fn new(weight: FontWeight, stretch: FontStretch, italic: bool) - -> FontTemplateDescriptor { - FontTemplateDescriptor { - weight: weight, - stretch: stretch, - italic: italic, + pub fn new( + weight: FontWeight, + stretch: FontStretch, + style: FontStyle, + ) -> Self { + Self { + weight, + stretch, + style, } } @@ -46,30 +59,15 @@ impl FontTemplateDescriptor { /// /// The policy is to care most about differences in italicness, then weight, then stretch #[inline] - fn distance_from(&self, other: &FontTemplateDescriptor) -> u32 { - let italic_part = if self.italic == other.italic { 0 } else { 1000 }; + fn distance_from(&self, other: &FontTemplateDescriptor) -> f32 { + // 0 <= style_part <= 180, since font-style obliqueness should be + // between -90 and +90deg. + let style_part = (style_to_number(&self.style) - style_to_number(&other.style)).abs(); // 0 <= weightPart <= 800 - let weight_part = ((self.weight.0 as i16) - (other.weight.0 as i16)).abs() as u32; + let weight_part = (self.weight.0 - other.weight.0).abs(); // 0 <= stretchPart <= 8 - let stretch_part = (self.stretch_number() - other.stretch_number()).abs() as u32; - italic_part + weight_part + stretch_part - } - - /// Returns a number between 1 and 9 for the stretch property. - /// 1 is ultra_condensed, 5 is normal, and 9 is ultra_expanded - #[inline] - fn stretch_number(&self) -> i32 { - match self.stretch { - FontStretch::UltraCondensed => 1, - FontStretch::ExtraCondensed => 2, - FontStretch::Condensed => 3, - FontStretch::SemiCondensed => 4, - FontStretch::Normal => 5, - FontStretch::SemiExpanded => 6, - FontStretch::Expanded => 7, - FontStretch::ExtraExpanded => 8, - FontStretch::UltraExpanded => 9, - } + let stretch_part = ((self.stretch.0).0 - (other.stretch.0).0).abs(); + style_part + weight_part + stretch_part } } @@ -78,17 +76,11 @@ impl<'a> From<&'a FontStyleStruct> for FontTemplateDescriptor { FontTemplateDescriptor { weight: style.font_weight, stretch: style.font_stretch, - italic: style.font_style == FontStyle::Italic || style.font_style == FontStyle::Oblique, + style: style.font_style, } } } -impl PartialEq for FontTemplateDescriptor { - fn eq(&self, other: &FontTemplateDescriptor) -> bool { - self.weight == other.weight && self.stretch == other.stretch && self.italic == other.italic - } -} - /// This describes all the information needed to create /// font instance handles. It contains a unique /// FontTemplateData structure that is platform specific. @@ -173,10 +165,11 @@ impl FontTemplate { /// Returns the font data along with the distance between this font's descriptor and the given /// descriptor, if the font can be loaded. - pub fn data_for_approximate_descriptor(&mut self, - font_context: &FontContextHandle, - requested_descriptor: &FontTemplateDescriptor) - -> Option<(Arc<FontTemplateData>, u32)> { + pub fn data_for_approximate_descriptor( + &mut self, + font_context: &FontContextHandle, + requested_descriptor: &FontTemplateDescriptor, + ) -> Option<(Arc<FontTemplateData>, f32)> { self.descriptor(&font_context).and_then(|descriptor| { self.data().ok().map(|data| { (data, descriptor.distance_from(requested_descriptor)) @@ -195,9 +188,11 @@ impl FontTemplate { None); self.is_valid = handle.is_ok(); let handle = handle?; - self.descriptor = Some(FontTemplateDescriptor::new(handle.boldness(), - handle.stretchiness(), - handle.is_italic())); + self.descriptor = Some(FontTemplateDescriptor::new( + handle.boldness(), + handle.stretchiness(), + handle.style(), + )); Ok(()) } diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index 940563d7d29..506d6be2117 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -24,6 +24,7 @@ use std::os::raw::{c_char, c_long}; use std::sync::Arc; use style::computed_values::font_stretch::T as FontStretch; use style::computed_values::font_weight::T as FontWeight; +use style::values::computed::font::FontStyle; use super::c_str_to_string; use text::glyph::GlyphId; use text::util::fixed_to_float; @@ -149,43 +150,44 @@ impl FontHandleMethods for FontHandle { } } - fn is_italic(&self) -> bool { - unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC as c_long != 0 } + fn style(&self) -> FontStyle { + use style::values::generics::font::FontStyle::*; + if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC as c_long != 0 } { + Italic + } else { + Normal + } } fn boldness(&self) -> FontWeight { - if let Some(os2) = self.os2_table() { - let weight = os2.us_weight_class as i32; - - if weight < 10 { - FontWeight::from_int(weight * 100).unwrap() - } else if weight >= 100 && weight < 1000 { - FontWeight::from_int(weight / 100 * 100).unwrap() - } else { - FontWeight::normal() - } - } else { - FontWeight::normal() - } + let os2 = match self.os2_table() { + None => return FontWeight::normal(), + Some(os2) => os2, + }; + let weight = os2.us_weight_class as f32; + FontWeight(weight.max(1.).min(1000.)) } fn stretchiness(&self) -> FontStretch { - if let Some(os2) = self.os2_table() { + use style::values::generics::NonNegative; + use style::values::specified::font::FontStretchKeyword; + let percentage = if let Some(os2) = self.os2_table() { match os2.us_width_class { - 1 => FontStretch::UltraCondensed, - 2 => FontStretch::ExtraCondensed, - 3 => FontStretch::Condensed, - 4 => FontStretch::SemiCondensed, - 5 => FontStretch::Normal, - 6 => FontStretch::SemiExpanded, - 7 => FontStretch::Expanded, - 8 => FontStretch::ExtraExpanded, - 9 => FontStretch::UltraExpanded, - _ => FontStretch::Normal + 1 => FontStretchKeyword::UltraCondensed, + 2 => FontStretchKeyword::ExtraCondensed, + 3 => FontStretchKeyword::Condensed, + 4 => FontStretchKeyword::SemiCondensed, + 5 => FontStretchKeyword::Normal, + 6 => FontStretchKeyword::SemiExpanded, + 7 => FontStretchKeyword::Expanded, + 8 => FontStretchKeyword::ExtraExpanded, + 9 => FontStretchKeyword::UltraExpanded, + _ => FontStretchKeyword::Normal } } else { - FontStretch::Normal - } + FontStretchKeyword::Normal + }.compute(); + NonNegative(percentage) } fn glyph_index(&self, codepoint: char) -> Option<GlyphId> { diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs index ca719ddf5b7..5eacf92ffd6 100644 --- a/components/gfx/platform/macos/font.rs +++ b/components/gfx/platform/macos/font.rs @@ -22,8 +22,7 @@ use servo_atoms::Atom; use std::{fmt, ptr}; use std::ops::Range; use std::sync::Arc; -use style::computed_values::font_stretch::T as FontStretch; -use style::computed_values::font_weight::T as FontWeight; +use style::values::computed::font::{FontStretch, FontStyle, FontWeight}; use text::glyph::GlyphId; const KERN_PAIR_LEN: usize = 6; @@ -204,34 +203,33 @@ impl FontHandleMethods for FontHandle { Some(self.ctfont.face_name()) } - fn is_italic(&self) -> bool { - self.ctfont.symbolic_traits().is_italic() + fn style(&self) -> FontStyle { + use style::values::generics::font::FontStyle::*; + if self.ctfont.symbolic_traits().is_italic() { + Italic + } else { + Normal + } } fn boldness(&self) -> FontWeight { let normalized = self.ctfont.all_traits().normalized_weight(); // [-1.0, 1.0] + // TODO(emilio): It may make sense to make this range [.01, 10.0], to + // align with css-fonts-4's range of [1, 1000]. let normalized = if normalized <= 0.0 { 4.0 + normalized * 3.0 // [1.0, 4.0] } else { 4.0 + normalized * 5.0 // [4.0, 9.0] }; // [1.0, 9.0], centered on 4.0 - FontWeight::from_int(normalized.round() as i32 * 100).unwrap() + FontWeight(normalized as f32 * 100.) } fn stretchiness(&self) -> FontStretch { + use style::values::computed::Percentage; + use style::values::generics::NonNegative; + let normalized = self.ctfont.all_traits().normalized_width(); // [-1.0, 1.0] - let normalized = (normalized + 1.0) / 2.0 * 9.0; // [0.0, 9.0] - match normalized { - v if v < 1.0 => FontStretch::UltraCondensed, - v if v < 2.0 => FontStretch::ExtraCondensed, - v if v < 3.0 => FontStretch::Condensed, - v if v < 4.0 => FontStretch::SemiCondensed, - v if v < 5.0 => FontStretch::Normal, - v if v < 6.0 => FontStretch::SemiExpanded, - v if v < 7.0 => FontStretch::Expanded, - v if v < 8.0 => FontStretch::ExtraExpanded, - _ => FontStretch::UltraExpanded, - } + NonNegative(Percentage(normalized as f32 + 1.0)) } fn glyph_index(&self, codepoint: char) -> Option<GlyphId> { diff --git a/components/gfx/platform/windows/font.rs b/components/gfx/platform/windows/font.rs index 12df6d547d2..ed94d0fc5a2 100644 --- a/components/gfx/platform/windows/font.rs +++ b/components/gfx/platform/windows/font.rs @@ -19,6 +19,10 @@ use servo_atoms::Atom; use std::sync::Arc; use style::computed_values::font_stretch::T as StyleFontStretch; use style::computed_values::font_weight::T as StyleFontWeight; +use style::values::computed::font::FontStyle as StyleFontStyle; +use style::values::generics::NonNegative; +use style::values::generics::font::FontStyle as GenericFontStyle; +use style::values::specified::font::FontStretchKeyword; use text::glyph::GlyphId; use truetype; @@ -98,7 +102,7 @@ struct FontInfo { face_name: String, weight: StyleFontWeight, stretch: StyleFontStretch, - style: FontStyle, + style: StyleFontStyle, } impl FontInfo { @@ -157,75 +161,76 @@ impl FontInfo { }, }; - let weight = - StyleFontWeight::from_int( - min(9, max(1, weight_val as i32 / 100)) * 100 - ).unwrap(); - - let stretch = match min(9, max(1, width_val)) { - 1 => StyleFontStretch::UltraCondensed, - 2 => StyleFontStretch::ExtraCondensed, - 3 => StyleFontStretch::Condensed, - 4 => StyleFontStretch::SemiCondensed, - 5 => StyleFontStretch::Normal, - 6 => StyleFontStretch::SemiExpanded, - 7 => StyleFontStretch::Expanded, - 8 => StyleFontStretch::ExtraExpanded, - 9 => StyleFontStretch::UltraExpanded, + let weight = StyleFontWeight(weight_val as f32); + + let stretch = NonNegative(match min(9, max(1, width_val)) { + 1 => FontStretchKeyword::UltraCondensed, + 2 => FontStretchKeyword::ExtraCondensed, + 3 => FontStretchKeyword::Condensed, + 4 => FontStretchKeyword::SemiCondensed, + 5 => FontStretchKeyword::Normal, + 6 => FontStretchKeyword::SemiExpanded, + 7 => FontStretchKeyword::Expanded, + 8 => FontStretchKeyword::ExtraExpanded, + 9 => FontStretchKeyword::UltraExpanded, _ => return Err(()), - }; + }.compute()); let style = if italic_bool { - FontStyle::Italic + GenericFontStyle::Italic } else { - FontStyle::Normal + GenericFontStyle::Normal }; Ok(FontInfo { family_name: family, face_name: face, - weight: weight, - stretch: stretch, - style: style, + weight, + stretch, + style, }) } fn new_from_font(font: &Font) -> Result<FontInfo, ()> { - let style = font.style(); + let style = match font.style() { + FontStyle::Normal => GenericFontStyle::Normal, + FontStyle::Oblique => GenericFontStyle::Oblique(StyleFontStyle::default_angle()), + FontStyle::Italic => GenericFontStyle::Italic, + }; let weight = StyleFontWeight(match font.weight() { - FontWeight::Thin => 100, - FontWeight::ExtraLight => 200, - FontWeight::Light => 300, + FontWeight::Thin => 100., + FontWeight::ExtraLight => 200., + FontWeight::Light => 300., // slightly grayer gray - FontWeight::SemiLight => 300, - FontWeight::Regular => 400, - FontWeight::Medium => 500, - FontWeight::SemiBold => 600, - FontWeight::Bold => 700, - FontWeight::ExtraBold => 800, - FontWeight::Black => 900, + FontWeight::SemiLight => 300., + FontWeight::Regular => 400., + FontWeight::Medium => 500., + FontWeight::SemiBold => 600., + FontWeight::Bold => 700., + FontWeight::ExtraBold => 800., + FontWeight::Black => 900., // slightly blacker black - FontWeight::ExtraBlack => 900, + FontWeight::ExtraBlack => 1000., }); - let stretch = match font.stretch() { - FontStretch::Undefined => StyleFontStretch::Normal, - FontStretch::UltraCondensed => StyleFontStretch::UltraCondensed, - FontStretch::ExtraCondensed => StyleFontStretch::ExtraCondensed, - FontStretch::Condensed => StyleFontStretch::Condensed, - FontStretch::SemiCondensed => StyleFontStretch::SemiCondensed, - FontStretch::Normal => StyleFontStretch::Normal, - FontStretch::SemiExpanded => StyleFontStretch::SemiExpanded, - FontStretch::Expanded => StyleFontStretch::Expanded, - FontStretch::ExtraExpanded => StyleFontStretch::ExtraExpanded, - FontStretch::UltraExpanded => StyleFontStretch::UltraExpanded, - }; + let stretch = NonNegative(match font.stretch() { + FontStretch::Undefined => FontStretchKeyword::Normal, + FontStretch::UltraCondensed => FontStretchKeyword::UltraCondensed, + FontStretch::ExtraCondensed => FontStretchKeyword::ExtraCondensed, + FontStretch::Condensed => FontStretchKeyword::Condensed, + FontStretch::SemiCondensed => FontStretchKeyword::SemiCondensed, + FontStretch::Normal => FontStretchKeyword::Normal, + FontStretch::SemiExpanded => FontStretchKeyword::SemiExpanded, + FontStretch::Expanded => FontStretchKeyword::Expanded, + FontStretch::ExtraExpanded => FontStretchKeyword::ExtraExpanded, + FontStretch::UltraExpanded => FontStretchKeyword::UltraExpanded, + }.compute()); Ok(FontInfo { family_name: font.family_name(), face_name: font.face_name(), - style: style, - weight: weight, - stretch: stretch, + style, + weight, + stretch, }) } } @@ -297,11 +302,8 @@ impl FontHandleMethods for FontHandle { Some(self.info.face_name.clone()) } - fn is_italic(&self) -> bool { - match self.info.style { - FontStyle::Normal => false, - FontStyle::Oblique | FontStyle::Italic => true, - } + fn style(&self) -> StyleFontStyle { + self.info.style } fn boldness(&self) -> StyleFontWeight { diff --git a/components/gfx/tests/font_context.rs b/components/gfx/tests/font_context.rs index f7fef58a5c2..c918ef86e90 100644 --- a/components/gfx/tests/font_context.rs +++ b/components/gfx/tests/font_context.rs @@ -22,12 +22,13 @@ use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; use std::rc::Rc; -use style::properties::longhands::font_stretch::computed_value::T as FontStretch; -use style::properties::longhands::font_style::computed_value::T as FontStyle; use style::properties::longhands::font_variant_caps::computed_value::T as FontVariantCaps; use style::properties::style_structs::Font as FontStyleStruct; +use style::values::computed::Percentage; use style::values::computed::font::{FamilyName, FamilyNameSyntax, FontFamily, FontFamilyList, FontSize}; use style::values::computed::font::{FontWeight, SingleFontFamily}; +use style::values::generics::NonNegative; +use style::values::generics::font::FontStyle; struct TestFontSource { handle: FontContextHandle, @@ -108,7 +109,7 @@ fn style() -> FontStyleStruct { font_variant_caps: FontVariantCaps::Normal, font_weight: FontWeight::normal(), font_size: FontSize::medium(), - font_stretch: FontStretch::Normal, + font_stretch: NonNegative(Percentage(1.)), hash: 0, }; style.compute_font_hash(); diff --git a/components/gfx/tests/font_template.rs b/components/gfx/tests/font_template.rs index 4b513d9f0c4..af31d8f229d 100644 --- a/components/gfx/tests/font_template.rs +++ b/components/gfx/tests/font_template.rs @@ -16,8 +16,10 @@ fn test_font_template_descriptor() { use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; - use style::computed_values::font_stretch::T as FontStretch; + use style::values::computed::Percentage; use style::values::computed::font::FontWeight; + use style::values::generics::NonNegative; + use style::values::generics::font::FontStyle; fn descriptor(filename: &str) -> FontTemplateDescriptor { let mut path: PathBuf = [ @@ -43,25 +45,25 @@ fn test_font_template_descriptor() { assert_eq!(descriptor("DejaVuSans"), FontTemplateDescriptor { weight: FontWeight::normal(), - stretch: FontStretch::Normal, - italic: false, + stretch: NonNegative(Percentage(1.)), + style: FontStyle::Normal, }); assert_eq!(descriptor("DejaVuSans-Bold"), FontTemplateDescriptor { weight: FontWeight::bold(), - stretch: FontStretch::Normal, - italic: false, + stretch: NonNegative(Percentage(1.)), + style: FontStyle::Normal, }); assert_eq!(descriptor("DejaVuSans-Oblique"), FontTemplateDescriptor { weight: FontWeight::normal(), - stretch: FontStretch::Normal, - italic: true, + stretch: NonNegative(Percentage(1.)), + style: FontStyle::Italic, }); assert_eq!(descriptor("DejaVuSansCondensed-BoldOblique"), FontTemplateDescriptor { weight: FontWeight::bold(), - stretch: FontStretch::SemiCondensed, - italic: true, + stretch: NonNegative(Percentage(0.875)), + style: FontStyle::Italic, }); } diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index 3659d50e219..487a878c08b 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -104,13 +104,13 @@ impl Flow for MulticolFlow { self.block_flow.fragment.border_box.size.inline - padding_and_borders; let column_width; { - let column_style = self.block_flow.fragment.style.get_column(); - - let column_gap = match column_style.column_gap { + let style = &self.block_flow.fragment.style; + let column_gap = match style.get_position().column_gap { Either::First(len) => len.0.to_pixel_length(content_inline_size).into(), Either::Second(_normal) => self.block_flow.fragment.style.get_font().font_size.size(), }; + let column_style = style.get_column(); let mut column_count; if let Either::First(column_width) = column_style.column_width { let column_width = Au::from(column_width); diff --git a/components/style/applicable_declarations.rs b/components/style/applicable_declarations.rs index ab7c47307d7..d4674fa1bc7 100644 --- a/components/style/applicable_declarations.rs +++ b/components/style/applicable_declarations.rs @@ -5,12 +5,11 @@ //! Applicable declarations management. use properties::PropertyDeclarationBlock; -use rule_tree::{CascadeLevel, StyleSource}; +use rule_tree::{CascadeLevel, ShadowCascadeOrder, StyleSource}; use servo_arc::Arc; use shared_lock::Locked; use smallvec::SmallVec; use std::fmt::{self, Debug}; -use std::mem; /// List of applicable declarations. This is a transient structure that shuttles /// declarations between selector matching and inserting into the rule tree, and @@ -25,45 +24,67 @@ pub type ApplicableDeclarationList = SmallVec<[ApplicableDeclarationBlock; 16]>; /// That's a limit that could be reached in realistic webpages, so we use /// 24 bits and enforce defined behavior in the overflow case. /// -/// Note that the value of 24 is also hard-coded into the level() accessor, -/// which does a byte-aligned load of the 4th byte. If you change this value -/// you'll need to change that as well. -/// /// [1] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/css/ /// RuleSet.h?l=128&rcl=90140ab80b84d0f889abc253410f44ed54ae04f3 +const SOURCE_ORDER_SHIFT: usize = 0; const SOURCE_ORDER_BITS: usize = 24; -const SOURCE_ORDER_MASK: u32 = (1 << SOURCE_ORDER_BITS) - 1; -const SOURCE_ORDER_MAX: u32 = SOURCE_ORDER_MASK; +const SOURCE_ORDER_MAX: u32 = (1 << SOURCE_ORDER_BITS) - 1; +const SOURCE_ORDER_MASK: u32 = SOURCE_ORDER_MAX << SOURCE_ORDER_SHIFT; + +/// We store up-to-15 shadow order levels. +/// +/// You'd need an element slotted across 16 components with ::slotted rules to +/// trigger this as of this writing, which looks... Unlikely. +const SHADOW_CASCADE_ORDER_SHIFT: usize = SOURCE_ORDER_BITS; +const SHADOW_CASCADE_ORDER_BITS: usize = 4; +const SHADOW_CASCADE_ORDER_MAX: u8 = (1 << SHADOW_CASCADE_ORDER_BITS) - 1; +const SHADOW_CASCADE_ORDER_MASK: u32 = (SHADOW_CASCADE_ORDER_MAX as u32) << SHADOW_CASCADE_ORDER_SHIFT; -/// Stores the source order of a block and the cascade level it belongs to. +const CASCADE_LEVEL_SHIFT: usize = SOURCE_ORDER_BITS + SHADOW_CASCADE_ORDER_BITS; +const CASCADE_LEVEL_BITS: usize = 4; +const CASCADE_LEVEL_MAX: u8 = (1 << CASCADE_LEVEL_BITS) - 1; +const CASCADE_LEVEL_MASK: u32 = (CASCADE_LEVEL_MAX as u32) << CASCADE_LEVEL_SHIFT; + +/// Stores the source order of a block, the cascade level it belongs to, and the +/// counter needed to handle Shadow DOM cascade order properly. #[derive(Clone, Copy, Eq, MallocSizeOf, PartialEq)] -struct SourceOrderAndCascadeLevel(u32); +struct ApplicableDeclarationBits(u32); -impl SourceOrderAndCascadeLevel { - fn new(source_order: u32, cascade_level: CascadeLevel) -> SourceOrderAndCascadeLevel { +impl ApplicableDeclarationBits { + fn new( + source_order: u32, + cascade_level: CascadeLevel, + shadow_cascade_order: ShadowCascadeOrder, + ) -> Self { + debug_assert!( + cascade_level as u8 <= CASCADE_LEVEL_MAX, + "Gotta find more bits!" + ); let mut bits = ::std::cmp::min(source_order, SOURCE_ORDER_MAX); - bits |= (cascade_level as u8 as u32) << SOURCE_ORDER_BITS; - SourceOrderAndCascadeLevel(bits) + bits |= ((shadow_cascade_order & SHADOW_CASCADE_ORDER_MAX) as u32) << SHADOW_CASCADE_ORDER_SHIFT; + bits |= (cascade_level as u8 as u32) << CASCADE_LEVEL_SHIFT; + ApplicableDeclarationBits(bits) } - fn order(&self) -> u32 { - self.0 & SOURCE_ORDER_MASK + fn source_order(&self) -> u32 { + (self.0 & SOURCE_ORDER_MASK) >> SOURCE_ORDER_SHIFT + } + + fn shadow_cascade_order(&self) -> ShadowCascadeOrder { + ((self.0 & SHADOW_CASCADE_ORDER_MASK) >> SHADOW_CASCADE_ORDER_SHIFT) as ShadowCascadeOrder } fn level(&self) -> CascadeLevel { - unsafe { - // Transmute rather than shifting so that we're sure the compiler - // emits a simple byte-aligned load. - let as_bytes: [u8; 4] = mem::transmute(self.0); - CascadeLevel::from_byte(as_bytes[3]) - } + let byte = ((self.0 & CASCADE_LEVEL_MASK) >> CASCADE_LEVEL_SHIFT) as u8; + unsafe { CascadeLevel::from_byte(byte) } } } -impl Debug for SourceOrderAndCascadeLevel { +impl Debug for ApplicableDeclarationBits { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("SourceOrderAndCascadeLevel") - .field("order", &self.order()) + f.debug_struct("ApplicableDeclarationBits") + .field("source_order", &self.source_order()) + .field("shadow_cascade_order", &self.shadow_cascade_order()) .field("level", &self.level()) .finish() } @@ -79,8 +100,9 @@ pub struct ApplicableDeclarationBlock { /// The style source, either a style rule, or a property declaration block. #[ignore_malloc_size_of = "Arc"] pub source: StyleSource, - /// The source order of the block, and the cascade level it belongs to. - order_and_level: SourceOrderAndCascadeLevel, + /// The bits containing the source order, cascade level, and shadow cascade + /// order. + bits: ApplicableDeclarationBits, /// The specificity of the selector this block is represented by. pub specificity: u32, } @@ -95,38 +117,45 @@ impl ApplicableDeclarationBlock { ) -> Self { ApplicableDeclarationBlock { source: StyleSource::Declarations(declarations), - order_and_level: SourceOrderAndCascadeLevel::new(0, level), + bits: ApplicableDeclarationBits::new(0, level, 0), specificity: 0, } } /// Constructs an applicable declaration block from the given components #[inline] - pub fn new(source: StyleSource, order: u32, level: CascadeLevel, specificity: u32) -> Self { + pub fn new( + source: StyleSource, + order: u32, + level: CascadeLevel, + specificity: u32, + shadow_cascade_order: ShadowCascadeOrder, + ) -> Self { ApplicableDeclarationBlock { - source: source, - order_and_level: SourceOrderAndCascadeLevel::new(order, level), - specificity: specificity, + source, + bits: ApplicableDeclarationBits::new(order, level, shadow_cascade_order), + specificity, } } /// Returns the source order of the block. #[inline] pub fn source_order(&self) -> u32 { - self.order_and_level.order() + self.bits.source_order() } /// Returns the cascade level of the block. #[inline] pub fn level(&self) -> CascadeLevel { - self.order_and_level.level() + self.bits.level() } - /// Convenience method to consume self and return the source alongside the - /// level. + /// Convenience method to consume self and return the right thing for the + /// rule tree to iterate over. #[inline] - pub fn order_and_level(self) -> (StyleSource, CascadeLevel) { + pub fn for_rule_tree(self) -> (StyleSource, CascadeLevel, ShadowCascadeOrder) { let level = self.level(); - (self.source, level) + let cascade_order = self.bits.shadow_cascade_order(); + (self.source, level, cascade_order) } } diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index 2d1db9e7037..95bb1622942 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -3,38 +3,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ mod common { - use std::{env, fs, io}; - use std::path::{Path, PathBuf}; + use std::env; + use std::path::PathBuf; lazy_static! { pub static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("gecko"); } - - /// Copy contents of one directory into another. - /// It currently only does a shallow copy. - pub fn copy_dir<P, Q, F>(from: P, to: Q, callback: F) -> io::Result<()> - where - P: AsRef<Path>, - Q: AsRef<Path>, - F: Fn(&Path), - { - let to = to.as_ref(); - for entry in from.as_ref().read_dir()? { - let entry = entry?; - let path = entry.path(); - callback(&path); - fs::copy(&path, to.join(entry.file_name()))?; - } - Ok(()) - } } #[cfg(feature = "bindgen")] mod bindings { use bindgen::{Builder, CodegenConfig}; - use bindgen::callbacks::{EnumVariantCustomBehavior, EnumVariantValue, ParseCallbacks}; - use regex::{Regex, RegexSet}; + use regex::Regex; use std::cmp; use std::collections::{HashMap, HashSet}; use std::env; @@ -416,27 +397,6 @@ mod bindings { } fn generate_structs() { - #[derive(Debug)] - struct Callbacks(HashMap<String, RegexSet>); - impl ParseCallbacks for Callbacks { - fn enum_variant_behavior( - &self, - enum_name: Option<&str>, - variant_name: &str, - _variant_value: EnumVariantValue, - ) -> Option<EnumVariantCustomBehavior> { - enum_name - .and_then(|enum_name| self.0.get(enum_name)) - .and_then(|regex| { - if regex.is_match(variant_name) { - Some(EnumVariantCustomBehavior::Constify) - } else { - None - } - }) - } - } - let builder = Builder::get_initial_builder() .enable_cxx_namespaces() .with_codegen_config(CodegenConfig { @@ -452,21 +412,6 @@ mod bindings { .handle_str_items("whitelist-vars", |b, item| b.whitelist_var(item)) .handle_str_items("whitelist-types", |b, item| b.whitelist_type(item)) .handle_str_items("opaque-types", |b, item| b.opaque_type(item)) - .handle_list("constified-enum-variants", |builder, iter| { - let mut map = HashMap::new(); - for item in iter { - let item = item.as_table().unwrap(); - let name = item["enum"].as_str().unwrap(); - let variants = item["variants"] - .as_array() - .unwrap() - .as_slice() - .iter() - .map(|item| item.as_str().unwrap()); - map.insert(name.into(), RegexSet::new(variants).unwrap()); - } - builder.parse_callbacks(Box::new(Callbacks(map))) - }) .handle_table_items("mapped-generic-types", |builder, item| { let generic = item["generic"].as_bool().unwrap(); let gecko = item["gecko"].as_str().unwrap(); @@ -650,23 +595,33 @@ mod bindings { generate_bindings(), generate_atoms(), } - - // Copy all generated files to dist for the binding package - let path = DISTDIR_PATH.join("rust_bindings/style"); - if path.exists() { - fs::remove_dir_all(&path).expect("Fail to remove binding dir in dist"); - } - fs::create_dir_all(&path).expect("Fail to create bindings dir in dist"); - copy_dir(&*OUTDIR_PATH, &path, |_| {}).expect("Fail to copy generated files to dist dir"); } } #[cfg(not(feature = "bindgen"))] mod bindings { - use std::env; - use std::path::PathBuf; + use std::{env, fs, io}; + use std::path::{Path, PathBuf}; use super::common::*; + /// Copy contents of one directory into another. + /// It currently only does a shallow copy. + fn copy_dir<P, Q, F>(from: P, to: Q, callback: F) -> io::Result<()> + where + P: AsRef<Path>, + Q: AsRef<Path>, + F: Fn(&Path), + { + let to = to.as_ref(); + for entry in from.as_ref().read_dir()? { + let entry = entry?; + let path = entry.path(); + callback(&path); + fs::copy(&path, to.join(entry.file_name()))?; + } + Ok(()) + } + pub fn generate() { let dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("gecko/generated"); println!("cargo:rerun-if-changed={}", dir.display()); diff --git a/components/style/font_face.rs b/components/style/font_face.rs index a890822d02f..5a111925ae7 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -6,10 +6,6 @@ //! //! [ff]: https://drafts.csswg.org/css-fonts/#at-font-face-rule -#![deny(missing_docs)] - -#[cfg(feature = "gecko")] -use computed_values::{font_stretch, font_style, font_weight}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{CowRcStr, SourceLocation}; #[cfg(feature = "gecko")] @@ -26,8 +22,12 @@ use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError}; use style_traits::{StyleParseErrorKind, ToCss}; use style_traits::values::SequenceWriter; use values::computed::font::FamilyName; +use values::generics::font::FontStyle as GenericFontStyle; +use values::specified::Angle; +use values::specified::font::{AbsoluteFontWeight, FontStretch as SpecifiedFontStretch}; #[cfg(feature = "gecko")] use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; +use values::specified::font::SpecifiedFontStyle; use values::specified::url::SpecifiedUrl; /// A source for a font-face rule. @@ -92,41 +92,97 @@ pub enum FontDisplay { Optional, } -/// A font-weight value for a @font-face rule. -/// The font-weight CSS property specifies the weight or boldness of the font. -#[cfg(feature = "gecko")] -#[derive(Clone, Debug, Eq, PartialEq, ToCss)] -pub enum FontWeight { - /// Numeric font weights for fonts that provide more than just normal and bold. - Weight(font_weight::T), - /// Normal font weight. Same as 400. +/// The font-weight descriptor: +/// +/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-weight +#[derive(Clone, Debug, PartialEq, ToCss)] +pub struct FontWeight(pub AbsoluteFontWeight, pub Option<AbsoluteFontWeight>); + +impl Parse for FontWeight { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + let first = AbsoluteFontWeight::parse(context, input)?; + let second = + input.try(|input| AbsoluteFontWeight::parse(context, input)).ok(); + Ok(FontWeight(first, second)) + } +} + +/// The font-stretch descriptor: +/// +/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-stretch +#[derive(Clone, Debug, PartialEq, ToCss)] +pub struct FontStretch(pub SpecifiedFontStretch, pub Option<SpecifiedFontStretch>); + +impl Parse for FontStretch { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + let first = SpecifiedFontStretch::parse(context, input)?; + let second = + input.try(|input| SpecifiedFontStretch::parse(context, input)).ok(); + Ok(FontStretch(first, second)) + } +} + +/// The font-style descriptor: +/// +/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-style +#[derive(Clone, Debug, PartialEq)] +#[allow(missing_docs)] +pub enum FontStyle { Normal, - /// Bold font weight. Same as 700. - Bold, + Italic, + Oblique(Angle, Angle), } -#[cfg(feature = "gecko")] -impl Parse for FontWeight { +impl Parse for FontStyle { fn parse<'i, 't>( - _: &ParserContext, + context: &ParserContext, input: &mut Parser<'i, 't>, - ) -> Result<FontWeight, ParseError<'i>> { - let result = input.try(|input| { - let ident = input.expect_ident().map_err(|_| ())?; - match_ignore_ascii_case! { &ident, - "normal" => Ok(FontWeight::Normal), - "bold" => Ok(FontWeight::Bold), - _ => Err(()) + ) -> Result<Self, ParseError<'i>> { + let style = SpecifiedFontStyle::parse(context, input)?; + Ok(match style { + GenericFontStyle::Normal => FontStyle::Normal, + GenericFontStyle::Italic => FontStyle::Italic, + GenericFontStyle::Oblique(angle) => { + let second_angle = input.try(|input| { + SpecifiedFontStyle::parse_angle(context, input) + }).unwrap_or_else(|_| angle.clone()); + + FontStyle::Oblique(angle, second_angle) } - }); - result.or_else(|_| { - font_weight::T::from_int(input.expect_integer()?) - .map(FontWeight::Weight) - .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) }) } } +impl ToCss for FontStyle { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: fmt::Write, + { + match *self { + FontStyle::Normal => dest.write_str("normal"), + FontStyle::Italic => dest.write_str("italic"), + FontStyle::Oblique(ref first, ref second) => { + dest.write_str("oblique")?; + if *first != SpecifiedFontStyle::default_angle() || first != second { + dest.write_char(' ')?; + first.to_css(dest)?; + } + if first != second { + dest.write_char(' ')?; + second.to_css(dest)?; + } + Ok(()) + } + } + } +} + /// Parse the block inside a `@font-face` rule. /// /// Note that the prelude parsing code lives in the `stylesheets` module. @@ -403,16 +459,16 @@ font_face_descriptors! { "src" sources / mSrc: Vec<Source>, ] optional descriptors = [ - /// The style of this font face - "font-style" style / mStyle: font_style::T, + /// The style of this font face. + "font-style" style / mStyle: FontStyle, - /// The weight of this font face + /// The weight of this font face. "font-weight" weight / mWeight: FontWeight, - /// The stretch of this font face - "font-stretch" stretch / mStretch: font_stretch::T, + /// The stretch of this font face. + "font-stretch" stretch / mStretch: FontStretch, - /// The display of this font face + /// The display of this font face. "font-display" display / mDisplay: FontDisplay, /// The ranges of code points outside of which this font face should not be used. diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 508f9ce4345..d5c7443b5a3 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -232,6 +232,7 @@ use gecko_bindings::structs::nsresult; use gecko_bindings::structs::Loader; use gecko_bindings::structs::LoaderReusableStyleSheets; use gecko_bindings::structs::SheetLoadData; +use gecko_bindings::structs::SheetLoadDataHolder; use gecko_bindings::structs::ServoStyleSheet; use gecko_bindings::structs::ServoComputedData; use gecko_bindings::structs::ComputedStyleStrong; @@ -628,18 +629,36 @@ extern "C" { ) -> RawGeckoNodeBorrowedOrNull; } extern "C" { + pub fn Gecko_AddRefSheetLoadDataHolderArbitraryThread(aPtr: *mut SheetLoadDataHolder); +} +extern "C" { + pub fn Gecko_ReleaseSheetLoadDataHolderArbitraryThread(aPtr: *mut SheetLoadDataHolder); +} +extern "C" { + pub fn Gecko_StyleSheet_FinishAsyncParse( + data: *mut SheetLoadDataHolder, + sheet_contents: RawServoStyleSheetContentsStrong, + ); +} +extern "C" { pub fn Gecko_LoadStyleSheet( loader: *mut Loader, parent: *mut ServoStyleSheet, parent_load_data: *mut SheetLoadData, reusable_sheets: *mut LoaderReusableStyleSheets, - base_url_data: *mut RawGeckoURLExtraData, - url_bytes: *const u8, - url_length: u32, + url: ServoBundledURI, media_list: RawServoMediaListStrong, ) -> *mut ServoStyleSheet; } extern "C" { + pub fn Gecko_LoadStyleSheetAsync( + parent_data: *mut SheetLoadDataHolder, + url: ServoBundledURI, + media_list: RawServoMediaListStrong, + import_rule: RawServoImportRuleStrong, + ); +} +extern "C" { pub fn Gecko_ElementState(element: RawGeckoElementBorrowed) -> u64; } extern "C" { @@ -1996,8 +2015,7 @@ extern "C" { loader: *mut Loader, gecko_stylesheet: *mut ServoStyleSheet, load_data: *mut SheetLoadData, - data: *const u8, - data_len: usize, + bytes: *const nsACString, parsing_mode: SheetParsingMode, extra_data: *mut RawGeckoURLExtraData, line_number_offset: u32, @@ -2006,6 +2024,16 @@ extern "C" { ) -> RawServoStyleSheetContentsStrong; } extern "C" { + pub fn Servo_StyleSheet_FromUTF8BytesAsync( + load_data: *mut SheetLoadDataHolder, + extra_data: *mut RawGeckoURLExtraData, + bytes: *const nsACString, + parsing_mode: SheetParsingMode, + line_number_offset: u32, + quirks_mode: nsCompatibility, + ); +} +extern "C" { pub fn Servo_StyleSheet_Empty( parsing_mode: SheetParsingMode, ) -> RawServoStyleSheetContentsStrong; @@ -2513,12 +2541,22 @@ extern "C" { ) -> bool; } extern "C" { + pub fn Servo_StyleRule_SetSelectorText( + sheet: RawServoStyleSheetContentsBorrowed, + rule: RawServoStyleRuleBorrowed, + text: *const nsAString, + ) -> bool; +} +extern "C" { pub fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, result: *mut nsAString); } extern "C" { pub fn Servo_ImportRule_GetSheet(rule: RawServoImportRuleBorrowed) -> *const ServoStyleSheet; } extern "C" { + pub fn Servo_ImportRule_SetSheet(rule: RawServoImportRuleBorrowed, sheet: *mut ServoStyleSheet); +} +extern "C" { pub fn Servo_Keyframe_GetKeyText(keyframe: RawServoKeyframeBorrowed, result: *mut nsAString); } extern "C" { diff --git a/components/style/gecko/generated/structs.rs b/components/style/gecko/generated/structs.rs index ebe6b79afbc..f88b116b646 100644 --- a/components/style/gecko/generated/structs.rs +++ b/components/style/gecko/generated/structs.rs @@ -149,15 +149,15 @@ pub mod root { pub const NS_FONT_WEIGHT_NORMAL: u32 = 400; pub const NS_FONT_WEIGHT_BOLD: u32 = 700; pub const NS_FONT_WEIGHT_THIN: u32 = 100; - pub const NS_FONT_STRETCH_ULTRA_CONDENSED: i32 = -4; - pub const NS_FONT_STRETCH_EXTRA_CONDENSED: i32 = -3; - pub const NS_FONT_STRETCH_CONDENSED: i32 = -2; - pub const NS_FONT_STRETCH_SEMI_CONDENSED: i32 = -1; - pub const NS_FONT_STRETCH_NORMAL: u32 = 0; - pub const NS_FONT_STRETCH_SEMI_EXPANDED: u32 = 1; - pub const NS_FONT_STRETCH_EXPANDED: u32 = 2; - pub const NS_FONT_STRETCH_EXTRA_EXPANDED: u32 = 3; - pub const NS_FONT_STRETCH_ULTRA_EXPANDED: u32 = 4; + pub const NS_FONT_STRETCH_ULTRA_CONDENSED: u32 = 50; + pub const NS_FONT_STRETCH_EXTRA_CONDENSED: u32 = 62; + pub const NS_FONT_STRETCH_CONDENSED: u32 = 75; + pub const NS_FONT_STRETCH_SEMI_CONDENSED: u32 = 87; + pub const NS_FONT_STRETCH_NORMAL: u32 = 100; + pub const NS_FONT_STRETCH_SEMI_EXPANDED: u32 = 112; + pub const NS_FONT_STRETCH_EXPANDED: u32 = 125; + pub const NS_FONT_STRETCH_EXTRA_EXPANDED: u32 = 150; + pub const NS_FONT_STRETCH_ULTRA_EXPANDED: u32 = 200; pub const NS_FONT_SMOOTHING_AUTO: u32 = 0; pub const NS_FONT_SMOOTHING_GRAYSCALE: u32 = 1; pub const NS_FONT_KERNING_AUTO: u32 = 0; @@ -429,15 +429,15 @@ pub mod root { pub const NS_STYLE_FONT_SIZE_LARGER: u32 = 8; pub const NS_STYLE_FONT_SIZE_SMALLER: u32 = 9; pub const NS_STYLE_FONT_SIZE_NO_KEYWORD: u32 = 10; - pub const NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED: i32 = -4; - pub const NS_STYLE_FONT_STRETCH_EXTRA_CONDENSED: i32 = -3; - pub const NS_STYLE_FONT_STRETCH_CONDENSED: i32 = -2; - pub const NS_STYLE_FONT_STRETCH_SEMI_CONDENSED: i32 = -1; - pub const NS_STYLE_FONT_STRETCH_NORMAL: u32 = 0; - pub const NS_STYLE_FONT_STRETCH_SEMI_EXPANDED: u32 = 1; - pub const NS_STYLE_FONT_STRETCH_EXPANDED: u32 = 2; - pub const NS_STYLE_FONT_STRETCH_EXTRA_EXPANDED: u32 = 3; - pub const NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED: u32 = 4; + pub const NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED: u32 = 50; + pub const NS_STYLE_FONT_STRETCH_EXTRA_CONDENSED: u32 = 62; + pub const NS_STYLE_FONT_STRETCH_CONDENSED: u32 = 75; + pub const NS_STYLE_FONT_STRETCH_SEMI_CONDENSED: u32 = 87; + pub const NS_STYLE_FONT_STRETCH_NORMAL: u32 = 100; + pub const NS_STYLE_FONT_STRETCH_SEMI_EXPANDED: u32 = 112; + pub const NS_STYLE_FONT_STRETCH_EXPANDED: u32 = 125; + pub const NS_STYLE_FONT_STRETCH_EXTRA_EXPANDED: u32 = 150; + pub const NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED: u32 = 200; pub const NS_STYLE_FONT_CAPTION: u32 = 1; pub const NS_STYLE_FONT_ICON: u32 = 2; pub const NS_STYLE_FONT_MENU: u32 = 3; @@ -6471,6 +6471,8 @@ pub mod root { __bindgen_bitfield_unit } } + pub type SheetLoadDataHolder = + root::nsMainThreadPtrHolder<root::mozilla::css::SheetLoadData>; #[repr(C)] #[derive(Debug, Copy)] pub struct ImageLoader { @@ -17422,6 +17424,16 @@ pub mod root { ); } #[repr(C)] + #[derive(Debug)] + pub struct nsMainThreadPtrHolder<T> { + pub mRefCnt: root::mozilla::ThreadSafeAutoRefCnt, + pub mRawPtr: *mut T, + pub mStrict: bool, + pub mMainThreadEventTarget: root::nsCOMPtr, + pub mName: *const ::std::os::raw::c_char, + pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>, + } + #[repr(C)] #[derive(Debug, Copy)] pub struct nsISerializable { pub _base: root::nsISupports, @@ -18354,18 +18366,6 @@ pub mod root { pub type nsRefPtrHashKey_KeyTypePointer<T> = *mut T; pub const nsRefPtrHashKey_ALLOW_MEMMOVE: root::nsRefPtrHashKey__bindgen_ty_1 = 0; pub type nsRefPtrHashKey__bindgen_ty_1 = i32; - pub const nsCSSPropertyID_eCSSProperty_COUNT_no_shorthands: root::nsCSSPropertyID = - nsCSSPropertyID::eCSSProperty_all; - pub const nsCSSPropertyID_eCSSProperty_COUNT_DUMMY: root::nsCSSPropertyID = - nsCSSPropertyID::eCSSProperty_z_index; - pub const nsCSSPropertyID_eCSSProperty_COUNT: root::nsCSSPropertyID = - nsCSSPropertyID::eCSSPropertyAlias_WordWrap; - pub const nsCSSPropertyID_eCSSProperty_COUNT_DUMMY2: root::nsCSSPropertyID = - nsCSSPropertyID::eCSSProperty_transition; - pub const nsCSSPropertyID_eCSSProperty_COUNT_with_aliases: root::nsCSSPropertyID = - nsCSSPropertyID::eCSSPropertyExtra_no_properties; - pub const nsCSSPropertyID_eCSSProperty_COUNT_DUMMY3: root::nsCSSPropertyID = - nsCSSPropertyID::eCSSPropertyAlias_WebkitMaskSize; #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum nsCSSPropertyID { @@ -18516,11 +18516,11 @@ pub mod root { eCSSProperty_grid_template_rows = 143, eCSSProperty_height = 144, eCSSProperty_hyphens = 145, - eCSSProperty_initial_letter = 146, - eCSSProperty_image_orientation = 147, - eCSSProperty__moz_image_region = 148, - eCSSProperty_image_rendering = 149, - eCSSProperty_ime_mode = 150, + eCSSProperty_image_orientation = 146, + eCSSProperty__moz_image_region = 147, + eCSSProperty_image_rendering = 148, + eCSSProperty_ime_mode = 149, + eCSSProperty_initial_letter = 150, eCSSProperty_inline_size = 151, eCSSProperty_isolation = 152, eCSSProperty_justify_content = 153, @@ -18587,113 +18587,113 @@ pub mod root { eCSSProperty_outline_width = 214, eCSSProperty_overflow_clip_box_block = 215, eCSSProperty_overflow_clip_box_inline = 216, - eCSSProperty_overflow_x = 217, - eCSSProperty_overflow_y = 218, - eCSSProperty_padding_block_end = 219, - eCSSProperty_padding_block_start = 220, - eCSSProperty_padding_bottom = 221, - eCSSProperty_padding_inline_end = 222, - eCSSProperty_padding_inline_start = 223, - eCSSProperty_padding_left = 224, - eCSSProperty_padding_right = 225, - eCSSProperty_padding_top = 226, - eCSSProperty_page_break_after = 227, - eCSSProperty_page_break_before = 228, - eCSSProperty_page_break_inside = 229, - eCSSProperty_paint_order = 230, - eCSSProperty_perspective = 231, - eCSSProperty_perspective_origin = 232, - eCSSProperty_pointer_events = 233, - eCSSProperty_position = 234, - eCSSProperty_quotes = 235, - eCSSProperty_resize = 236, - eCSSProperty_right = 237, - eCSSProperty_rotate = 238, - eCSSProperty_ruby_align = 239, - eCSSProperty_ruby_position = 240, - eCSSProperty__moz_script_level = 241, - eCSSProperty__moz_script_min_size = 242, - eCSSProperty__moz_script_size_multiplier = 243, - eCSSProperty_scroll_behavior = 244, - eCSSProperty_overscroll_behavior_x = 245, - eCSSProperty_overscroll_behavior_y = 246, - eCSSProperty_scroll_snap_coordinate = 247, - eCSSProperty_scroll_snap_destination = 248, - eCSSProperty_scroll_snap_points_x = 249, - eCSSProperty_scroll_snap_points_y = 250, - eCSSProperty_scroll_snap_type_x = 251, - eCSSProperty_scroll_snap_type_y = 252, - eCSSProperty_shape_image_threshold = 253, - eCSSProperty_shape_outside = 254, - eCSSProperty_shape_rendering = 255, - eCSSProperty__x_span = 256, - eCSSProperty__moz_stack_sizing = 257, - eCSSProperty_stop_color = 258, - eCSSProperty_stop_opacity = 259, - eCSSProperty_stroke = 260, - eCSSProperty_stroke_dasharray = 261, - eCSSProperty_stroke_dashoffset = 262, - eCSSProperty_stroke_linecap = 263, - eCSSProperty_stroke_linejoin = 264, - eCSSProperty_stroke_miterlimit = 265, - eCSSProperty_stroke_opacity = 266, - eCSSProperty_stroke_width = 267, - eCSSProperty__moz_tab_size = 268, - eCSSProperty_table_layout = 269, - eCSSProperty_text_align = 270, - eCSSProperty_text_align_last = 271, - eCSSProperty_text_anchor = 272, - eCSSProperty_text_combine_upright = 273, - eCSSProperty_text_decoration_color = 274, - eCSSProperty_text_decoration_line = 275, - eCSSProperty_text_decoration_style = 276, - eCSSProperty_text_emphasis_color = 277, - eCSSProperty_text_emphasis_position = 278, - eCSSProperty_text_emphasis_style = 279, - eCSSProperty__webkit_text_fill_color = 280, - eCSSProperty_text_indent = 281, - eCSSProperty_text_justify = 282, - eCSSProperty_text_orientation = 283, - eCSSProperty_text_overflow = 284, - eCSSProperty_text_rendering = 285, - eCSSProperty_text_shadow = 286, - eCSSProperty__moz_text_size_adjust = 287, - eCSSProperty__webkit_text_stroke_color = 288, - eCSSProperty__webkit_text_stroke_width = 289, - eCSSProperty_scale = 290, - eCSSProperty_text_transform = 291, - eCSSProperty__x_text_zoom = 292, - eCSSProperty_top = 293, - eCSSProperty__moz_top_layer = 294, - eCSSProperty_touch_action = 295, - eCSSProperty_transform = 296, - eCSSProperty_transform_box = 297, - eCSSProperty_transform_origin = 298, - eCSSProperty_transform_style = 299, - eCSSProperty_transition_delay = 300, - eCSSProperty_transition_duration = 301, - eCSSProperty_transition_property = 302, - eCSSProperty_transition_timing_function = 303, - eCSSProperty_translate = 304, - eCSSProperty_unicode_bidi = 305, - eCSSProperty__moz_user_focus = 306, - eCSSProperty__moz_user_input = 307, - eCSSProperty__moz_user_modify = 308, - eCSSProperty__moz_user_select = 309, - eCSSProperty_vector_effect = 310, - eCSSProperty_vertical_align = 311, - eCSSProperty_visibility = 312, - eCSSProperty_white_space = 313, - eCSSProperty_width = 314, - eCSSProperty_will_change = 315, - eCSSProperty__moz_window_dragging = 316, - eCSSProperty__moz_window_shadow = 317, + eCSSProperty_overflow_wrap = 217, + eCSSProperty_overflow_x = 218, + eCSSProperty_overflow_y = 219, + eCSSProperty_overscroll_behavior_x = 220, + eCSSProperty_overscroll_behavior_y = 221, + eCSSProperty_padding_block_end = 222, + eCSSProperty_padding_block_start = 223, + eCSSProperty_padding_bottom = 224, + eCSSProperty_padding_inline_end = 225, + eCSSProperty_padding_inline_start = 226, + eCSSProperty_padding_left = 227, + eCSSProperty_padding_right = 228, + eCSSProperty_padding_top = 229, + eCSSProperty_page_break_after = 230, + eCSSProperty_page_break_before = 231, + eCSSProperty_page_break_inside = 232, + eCSSProperty_paint_order = 233, + eCSSProperty_perspective = 234, + eCSSProperty_perspective_origin = 235, + eCSSProperty_pointer_events = 236, + eCSSProperty_position = 237, + eCSSProperty_quotes = 238, + eCSSProperty_resize = 239, + eCSSProperty_right = 240, + eCSSProperty_rotate = 241, + eCSSProperty_ruby_align = 242, + eCSSProperty_ruby_position = 243, + eCSSProperty_scale = 244, + eCSSProperty__moz_script_level = 245, + eCSSProperty__moz_script_min_size = 246, + eCSSProperty__moz_script_size_multiplier = 247, + eCSSProperty_scroll_behavior = 248, + eCSSProperty_scroll_snap_coordinate = 249, + eCSSProperty_scroll_snap_destination = 250, + eCSSProperty_scroll_snap_points_x = 251, + eCSSProperty_scroll_snap_points_y = 252, + eCSSProperty_scroll_snap_type_x = 253, + eCSSProperty_scroll_snap_type_y = 254, + eCSSProperty_shape_image_threshold = 255, + eCSSProperty_shape_outside = 256, + eCSSProperty_shape_rendering = 257, + eCSSProperty__x_span = 258, + eCSSProperty__moz_stack_sizing = 259, + eCSSProperty_stop_color = 260, + eCSSProperty_stop_opacity = 261, + eCSSProperty_stroke = 262, + eCSSProperty_stroke_dasharray = 263, + eCSSProperty_stroke_dashoffset = 264, + eCSSProperty_stroke_linecap = 265, + eCSSProperty_stroke_linejoin = 266, + eCSSProperty_stroke_miterlimit = 267, + eCSSProperty_stroke_opacity = 268, + eCSSProperty_stroke_width = 269, + eCSSProperty__moz_tab_size = 270, + eCSSProperty_table_layout = 271, + eCSSProperty_text_align = 272, + eCSSProperty_text_align_last = 273, + eCSSProperty_text_anchor = 274, + eCSSProperty_text_combine_upright = 275, + eCSSProperty_text_decoration_color = 276, + eCSSProperty_text_decoration_line = 277, + eCSSProperty_text_decoration_style = 278, + eCSSProperty_text_emphasis_color = 279, + eCSSProperty_text_emphasis_position = 280, + eCSSProperty_text_emphasis_style = 281, + eCSSProperty__webkit_text_fill_color = 282, + eCSSProperty_text_indent = 283, + eCSSProperty_text_justify = 284, + eCSSProperty_text_orientation = 285, + eCSSProperty_text_overflow = 286, + eCSSProperty_text_rendering = 287, + eCSSProperty_text_shadow = 288, + eCSSProperty__moz_text_size_adjust = 289, + eCSSProperty__webkit_text_stroke_color = 290, + eCSSProperty__webkit_text_stroke_width = 291, + eCSSProperty_text_transform = 292, + eCSSProperty__x_text_zoom = 293, + eCSSProperty_top = 294, + eCSSProperty__moz_top_layer = 295, + eCSSProperty_touch_action = 296, + eCSSProperty_transform = 297, + eCSSProperty_transform_box = 298, + eCSSProperty_transform_origin = 299, + eCSSProperty_transform_style = 300, + eCSSProperty_transition_delay = 301, + eCSSProperty_transition_duration = 302, + eCSSProperty_transition_property = 303, + eCSSProperty_transition_timing_function = 304, + eCSSProperty_translate = 305, + eCSSProperty_unicode_bidi = 306, + eCSSProperty__moz_user_focus = 307, + eCSSProperty__moz_user_input = 308, + eCSSProperty__moz_user_modify = 309, + eCSSProperty__moz_user_select = 310, + eCSSProperty_vector_effect = 311, + eCSSProperty_vertical_align = 312, + eCSSProperty_visibility = 313, + eCSSProperty_white_space = 314, + eCSSProperty_width = 315, + eCSSProperty_will_change = 316, + eCSSProperty__moz_window_dragging = 317, eCSSProperty__moz_window_opacity = 318, - eCSSProperty__moz_window_transform = 319, - eCSSProperty__moz_window_transform_origin = 320, - eCSSProperty_word_break = 321, - eCSSProperty_word_spacing = 322, - eCSSProperty_overflow_wrap = 323, + eCSSProperty__moz_window_shadow = 319, + eCSSProperty__moz_window_transform = 320, + eCSSProperty__moz_window_transform_origin = 321, + eCSSProperty_word_break = 322, + eCSSProperty_word_spacing = 323, eCSSProperty_writing_mode = 324, eCSSProperty_z_index = 325, eCSSProperty_all = 326, @@ -18735,132 +18735,129 @@ pub mod root { eCSSProperty__moz_outline_radius = 362, eCSSProperty_overflow = 363, eCSSProperty_overflow_clip_box = 364, - eCSSProperty_padding = 365, - eCSSProperty_place_content = 366, - eCSSProperty_place_items = 367, - eCSSProperty_place_self = 368, - eCSSProperty_overscroll_behavior = 369, + eCSSProperty_overscroll_behavior = 365, + eCSSProperty_padding = 366, + eCSSProperty_place_content = 367, + eCSSProperty_place_items = 368, + eCSSProperty_place_self = 369, eCSSProperty_scroll_snap_type = 370, eCSSProperty_text_decoration = 371, eCSSProperty_text_emphasis = 372, eCSSProperty__webkit_text_stroke = 373, eCSSProperty_transition = 374, - eCSSPropertyAlias_WordWrap = 375, - eCSSPropertyAlias_MozTransform = 376, - eCSSPropertyAlias_MozTransformOrigin = 377, - eCSSPropertyAlias_MozPerspectiveOrigin = 378, - eCSSPropertyAlias_MozPerspective = 379, - eCSSPropertyAlias_MozTransformStyle = 380, - eCSSPropertyAlias_MozBackfaceVisibility = 381, - eCSSPropertyAlias_MozBorderImage = 382, - eCSSPropertyAlias_MozTransition = 383, - eCSSPropertyAlias_MozTransitionDelay = 384, - eCSSPropertyAlias_MozTransitionDuration = 385, - eCSSPropertyAlias_MozTransitionProperty = 386, - eCSSPropertyAlias_MozTransitionTimingFunction = 387, - eCSSPropertyAlias_MozAnimation = 388, - eCSSPropertyAlias_MozAnimationDelay = 389, - eCSSPropertyAlias_MozAnimationDirection = 390, - eCSSPropertyAlias_MozAnimationDuration = 391, - eCSSPropertyAlias_MozAnimationFillMode = 392, - eCSSPropertyAlias_MozAnimationIterationCount = 393, - eCSSPropertyAlias_MozAnimationName = 394, - eCSSPropertyAlias_MozAnimationPlayState = 395, - eCSSPropertyAlias_MozAnimationTimingFunction = 396, - eCSSPropertyAlias_MozBoxSizing = 397, - eCSSPropertyAlias_MozFontFeatureSettings = 398, - eCSSPropertyAlias_MozFontLanguageOverride = 399, - eCSSPropertyAlias_MozPaddingEnd = 400, - eCSSPropertyAlias_MozPaddingStart = 401, - eCSSPropertyAlias_MozMarginEnd = 402, - eCSSPropertyAlias_MozMarginStart = 403, - eCSSPropertyAlias_MozBorderEnd = 404, - eCSSPropertyAlias_MozBorderEndColor = 405, - eCSSPropertyAlias_MozBorderEndStyle = 406, - eCSSPropertyAlias_MozBorderEndWidth = 407, - eCSSPropertyAlias_MozBorderStart = 408, - eCSSPropertyAlias_MozBorderStartColor = 409, - eCSSPropertyAlias_MozBorderStartStyle = 410, - eCSSPropertyAlias_MozBorderStartWidth = 411, - eCSSPropertyAlias_MozHyphens = 412, - eCSSPropertyAlias_MozColumnCount = 413, - eCSSPropertyAlias_MozColumnFill = 414, - eCSSPropertyAlias_MozColumnGap = 415, - eCSSPropertyAlias_MozColumnRule = 416, - eCSSPropertyAlias_MozColumnRuleColor = 417, - eCSSPropertyAlias_MozColumnRuleStyle = 418, - eCSSPropertyAlias_MozColumnRuleWidth = 419, - eCSSPropertyAlias_MozColumnSpan = 420, - eCSSPropertyAlias_MozColumnWidth = 421, - eCSSPropertyAlias_MozColumns = 422, - eCSSPropertyAlias_WebkitAnimation = 423, - eCSSPropertyAlias_WebkitAnimationDelay = 424, - eCSSPropertyAlias_WebkitAnimationDirection = 425, - eCSSPropertyAlias_WebkitAnimationDuration = 426, - eCSSPropertyAlias_WebkitAnimationFillMode = 427, - eCSSPropertyAlias_WebkitAnimationIterationCount = 428, - eCSSPropertyAlias_WebkitAnimationName = 429, - eCSSPropertyAlias_WebkitAnimationPlayState = 430, - eCSSPropertyAlias_WebkitAnimationTimingFunction = 431, - eCSSPropertyAlias_WebkitFilter = 432, - eCSSPropertyAlias_WebkitTextSizeAdjust = 433, - eCSSPropertyAlias_WebkitTransform = 434, - eCSSPropertyAlias_WebkitTransformOrigin = 435, - eCSSPropertyAlias_WebkitTransformStyle = 436, - eCSSPropertyAlias_WebkitBackfaceVisibility = 437, - eCSSPropertyAlias_WebkitPerspective = 438, - eCSSPropertyAlias_WebkitPerspectiveOrigin = 439, - eCSSPropertyAlias_WebkitTransition = 440, - eCSSPropertyAlias_WebkitTransitionDelay = 441, - eCSSPropertyAlias_WebkitTransitionDuration = 442, - eCSSPropertyAlias_WebkitTransitionProperty = 443, - eCSSPropertyAlias_WebkitTransitionTimingFunction = 444, - eCSSPropertyAlias_WebkitBorderRadius = 445, - eCSSPropertyAlias_WebkitBorderTopLeftRadius = 446, - eCSSPropertyAlias_WebkitBorderTopRightRadius = 447, - eCSSPropertyAlias_WebkitBorderBottomLeftRadius = 448, - eCSSPropertyAlias_WebkitBorderBottomRightRadius = 449, - eCSSPropertyAlias_WebkitBackgroundClip = 450, - eCSSPropertyAlias_WebkitBackgroundOrigin = 451, - eCSSPropertyAlias_WebkitBackgroundSize = 452, - eCSSPropertyAlias_WebkitBorderImage = 453, - eCSSPropertyAlias_WebkitBoxShadow = 454, - eCSSPropertyAlias_WebkitBoxSizing = 455, - eCSSPropertyAlias_WebkitBoxFlex = 456, - eCSSPropertyAlias_WebkitBoxOrdinalGroup = 457, - eCSSPropertyAlias_WebkitBoxOrient = 458, - eCSSPropertyAlias_WebkitBoxDirection = 459, - eCSSPropertyAlias_WebkitBoxAlign = 460, - eCSSPropertyAlias_WebkitBoxPack = 461, - eCSSPropertyAlias_WebkitFlexDirection = 462, - eCSSPropertyAlias_WebkitFlexWrap = 463, - eCSSPropertyAlias_WebkitFlexFlow = 464, - eCSSPropertyAlias_WebkitOrder = 465, - eCSSPropertyAlias_WebkitFlex = 466, - eCSSPropertyAlias_WebkitFlexGrow = 467, - eCSSPropertyAlias_WebkitFlexShrink = 468, - eCSSPropertyAlias_WebkitFlexBasis = 469, - eCSSPropertyAlias_WebkitJustifyContent = 470, - eCSSPropertyAlias_WebkitAlignItems = 471, - eCSSPropertyAlias_WebkitAlignSelf = 472, - eCSSPropertyAlias_WebkitAlignContent = 473, - eCSSPropertyAlias_WebkitUserSelect = 474, - eCSSPropertyAlias_WebkitMask = 475, - eCSSPropertyAlias_WebkitMaskClip = 476, - eCSSPropertyAlias_WebkitMaskComposite = 477, - eCSSPropertyAlias_WebkitMaskImage = 478, - eCSSPropertyAlias_WebkitMaskOrigin = 479, - eCSSPropertyAlias_WebkitMaskPosition = 480, - eCSSPropertyAlias_WebkitMaskPositionX = 481, - eCSSPropertyAlias_WebkitMaskPositionY = 482, - eCSSPropertyAlias_WebkitMaskRepeat = 483, - eCSSPropertyAlias_WebkitMaskSize = 484, + eCSSPropertyAlias__moz_animation = 375, + eCSSPropertyAlias__moz_animation_delay = 376, + eCSSPropertyAlias__moz_animation_direction = 377, + eCSSPropertyAlias__moz_animation_duration = 378, + eCSSPropertyAlias__moz_animation_fill_mode = 379, + eCSSPropertyAlias__moz_animation_iteration_count = 380, + eCSSPropertyAlias__moz_animation_name = 381, + eCSSPropertyAlias__moz_animation_play_state = 382, + eCSSPropertyAlias__moz_animation_timing_function = 383, + eCSSPropertyAlias__moz_backface_visibility = 384, + eCSSPropertyAlias__moz_border_end = 385, + eCSSPropertyAlias__moz_border_end_color = 386, + eCSSPropertyAlias__moz_border_end_style = 387, + eCSSPropertyAlias__moz_border_end_width = 388, + eCSSPropertyAlias__moz_border_image = 389, + eCSSPropertyAlias__moz_border_start = 390, + eCSSPropertyAlias__moz_border_start_color = 391, + eCSSPropertyAlias__moz_border_start_style = 392, + eCSSPropertyAlias__moz_border_start_width = 393, + eCSSPropertyAlias__moz_box_sizing = 394, + eCSSPropertyAlias__moz_column_count = 395, + eCSSPropertyAlias__moz_column_fill = 396, + eCSSPropertyAlias__moz_column_gap = 397, + eCSSPropertyAlias__moz_column_rule = 398, + eCSSPropertyAlias__moz_column_rule_color = 399, + eCSSPropertyAlias__moz_column_rule_style = 400, + eCSSPropertyAlias__moz_column_rule_width = 401, + eCSSPropertyAlias__moz_column_span = 402, + eCSSPropertyAlias__moz_column_width = 403, + eCSSPropertyAlias__moz_columns = 404, + eCSSPropertyAlias__moz_font_feature_settings = 405, + eCSSPropertyAlias__moz_font_language_override = 406, + eCSSPropertyAlias__moz_hyphens = 407, + eCSSPropertyAlias__moz_margin_end = 408, + eCSSPropertyAlias__moz_margin_start = 409, + eCSSPropertyAlias__moz_padding_end = 410, + eCSSPropertyAlias__moz_padding_start = 411, + eCSSPropertyAlias__moz_perspective = 412, + eCSSPropertyAlias__moz_perspective_origin = 413, + eCSSPropertyAlias__moz_transform = 414, + eCSSPropertyAlias__moz_transform_origin = 415, + eCSSPropertyAlias__moz_transform_style = 416, + eCSSPropertyAlias__moz_transition = 417, + eCSSPropertyAlias__moz_transition_delay = 418, + eCSSPropertyAlias__moz_transition_duration = 419, + eCSSPropertyAlias__moz_transition_property = 420, + eCSSPropertyAlias__moz_transition_timing_function = 421, + eCSSPropertyAlias__webkit_align_content = 422, + eCSSPropertyAlias__webkit_align_items = 423, + eCSSPropertyAlias__webkit_align_self = 424, + eCSSPropertyAlias__webkit_animation = 425, + eCSSPropertyAlias__webkit_animation_delay = 426, + eCSSPropertyAlias__webkit_animation_direction = 427, + eCSSPropertyAlias__webkit_animation_duration = 428, + eCSSPropertyAlias__webkit_animation_fill_mode = 429, + eCSSPropertyAlias__webkit_animation_iteration_count = 430, + eCSSPropertyAlias__webkit_animation_name = 431, + eCSSPropertyAlias__webkit_animation_play_state = 432, + eCSSPropertyAlias__webkit_animation_timing_function = 433, + eCSSPropertyAlias__webkit_backface_visibility = 434, + eCSSPropertyAlias__webkit_background_clip = 435, + eCSSPropertyAlias__webkit_background_origin = 436, + eCSSPropertyAlias__webkit_background_size = 437, + eCSSPropertyAlias__webkit_border_bottom_left_radius = 438, + eCSSPropertyAlias__webkit_border_bottom_right_radius = 439, + eCSSPropertyAlias__webkit_border_image = 440, + eCSSPropertyAlias__webkit_border_radius = 441, + eCSSPropertyAlias__webkit_border_top_left_radius = 442, + eCSSPropertyAlias__webkit_border_top_right_radius = 443, + eCSSPropertyAlias__webkit_box_align = 444, + eCSSPropertyAlias__webkit_box_direction = 445, + eCSSPropertyAlias__webkit_box_flex = 446, + eCSSPropertyAlias__webkit_box_ordinal_group = 447, + eCSSPropertyAlias__webkit_box_orient = 448, + eCSSPropertyAlias__webkit_box_pack = 449, + eCSSPropertyAlias__webkit_box_shadow = 450, + eCSSPropertyAlias__webkit_box_sizing = 451, + eCSSPropertyAlias__webkit_filter = 452, + eCSSPropertyAlias__webkit_flex = 453, + eCSSPropertyAlias__webkit_flex_basis = 454, + eCSSPropertyAlias__webkit_flex_direction = 455, + eCSSPropertyAlias__webkit_flex_flow = 456, + eCSSPropertyAlias__webkit_flex_grow = 457, + eCSSPropertyAlias__webkit_flex_shrink = 458, + eCSSPropertyAlias__webkit_flex_wrap = 459, + eCSSPropertyAlias__webkit_justify_content = 460, + eCSSPropertyAlias__webkit_mask = 461, + eCSSPropertyAlias__webkit_mask_clip = 462, + eCSSPropertyAlias__webkit_mask_composite = 463, + eCSSPropertyAlias__webkit_mask_image = 464, + eCSSPropertyAlias__webkit_mask_origin = 465, + eCSSPropertyAlias__webkit_mask_position = 466, + eCSSPropertyAlias__webkit_mask_position_x = 467, + eCSSPropertyAlias__webkit_mask_position_y = 468, + eCSSPropertyAlias__webkit_mask_repeat = 469, + eCSSPropertyAlias__webkit_mask_size = 470, + eCSSPropertyAlias__webkit_order = 471, + eCSSPropertyAlias__webkit_perspective = 472, + eCSSPropertyAlias__webkit_perspective_origin = 473, + eCSSPropertyAlias__webkit_text_size_adjust = 474, + eCSSPropertyAlias__webkit_transform = 475, + eCSSPropertyAlias__webkit_transform_origin = 476, + eCSSPropertyAlias__webkit_transform_style = 477, + eCSSPropertyAlias__webkit_transition = 478, + eCSSPropertyAlias__webkit_transition_delay = 479, + eCSSPropertyAlias__webkit_transition_duration = 480, + eCSSPropertyAlias__webkit_transition_property = 481, + eCSSPropertyAlias__webkit_transition_timing_function = 482, + eCSSPropertyAlias__webkit_user_select = 483, + eCSSPropertyAlias_word_wrap = 484, eCSSPropertyExtra_no_properties = 485, eCSSPropertyExtra_all_properties = 486, - eCSSPropertyExtra_x_none_value = 487, - eCSSPropertyExtra_x_auto_value = 488, - eCSSPropertyExtra_variable = 489, - eCSSProperty_DOM = 490, + eCSSPropertyExtra_variable = 487, } #[repr(i32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/components/style/gecko/rules.rs b/components/style/gecko/rules.rs index 2f144279656..a57314a418c 100644 --- a/components/style/gecko/rules.rs +++ b/components/style/gecko/rules.rs @@ -5,17 +5,18 @@ //! Bindings for CSS Rule objects use byteorder::{BigEndian, WriteBytesExt}; -use computed_values::{font_stretch, font_style, font_weight}; use counter_style::{self, CounterBound}; use cssparser::UnicodeRange; -use font_face::{FontDisplay, FontWeight, Source}; +use font_face::{FontDisplay, FontWeight, FontStretch, FontStyle, Source}; use gecko_bindings::structs::{self, nsCSSValue}; use gecko_bindings::sugar::ns_css_value::ToNsCssValue; use properties::longhands::font_language_override; use std::str; use values::computed::font::FamilyName; use values::generics::font::FontTag; +use values::specified::font::{AbsoluteFontWeight, FontStretch as SpecifiedFontStretch}; use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; +use values::specified::font::SpecifiedFontStyle; impl<'a> ToNsCssValue for &'a FamilyName { fn convert(self, nscssvalue: &mut nsCSSValue) { @@ -23,19 +24,20 @@ impl<'a> ToNsCssValue for &'a FamilyName { } } -impl ToNsCssValue for font_weight::T { +impl<'a> ToNsCssValue for &'a SpecifiedFontStretch { fn convert(self, nscssvalue: &mut nsCSSValue) { - nscssvalue.set_font_weight(self.0) + let number = match *self { + SpecifiedFontStretch::Stretch(ref p) => p.get(), + SpecifiedFontStretch::Keyword(ref kw) => kw.compute().0, + SpecifiedFontStretch::System(..) => unreachable!(), + }; + nscssvalue.set_font_stretch(number); } } -impl<'a> ToNsCssValue for &'a FontWeight { +impl<'a> ToNsCssValue for &'a AbsoluteFontWeight { fn convert(self, nscssvalue: &mut nsCSSValue) { - match *self { - FontWeight::Normal => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32), - FontWeight::Bold => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), - FontWeight::Weight(weight) => nscssvalue.set_font_weight(weight.0), - } + nscssvalue.set_font_weight(self.compute().0) } } @@ -77,6 +79,52 @@ impl<'a> ToNsCssValue for &'a SpecifiedFontVariationSettings { } } +macro_rules! descriptor_range_conversion { + ($name:ident) => { + impl<'a> ToNsCssValue for &'a $name { + fn convert(self, nscssvalue: &mut nsCSSValue) { + let $name(ref first, ref second) = *self; + let second = match *second { + None => { + nscssvalue.set_from(first); + return; + } + Some(ref second) => second, + }; + + let mut a = nsCSSValue::null(); + let mut b = nsCSSValue::null(); + + a.set_from(first); + b.set_from(second); + + nscssvalue.set_pair(&a, &b); + } + } + } +} + +descriptor_range_conversion!(FontWeight); +descriptor_range_conversion!(FontStretch); + +impl<'a> ToNsCssValue for &'a FontStyle { + fn convert(self, nscssvalue: &mut nsCSSValue) { + match *self { + FontStyle::Normal => nscssvalue.set_normal(), + FontStyle::Italic => nscssvalue.set_enum(structs::NS_FONT_STYLE_ITALIC as i32), + FontStyle::Oblique(ref first, ref second) => { + let mut a = nsCSSValue::null(); + let mut b = nsCSSValue::null(); + + a.set_font_style(SpecifiedFontStyle::compute_angle(first).degrees()); + b.set_font_style(SpecifiedFontStyle::compute_angle(second).degrees()); + + nscssvalue.set_pair(&a, &b); + } + } + } +} + impl<'a> ToNsCssValue for &'a font_language_override::SpecifiedValue { fn convert(self, nscssvalue: &mut nsCSSValue) { match *self { @@ -90,46 +138,6 @@ impl<'a> ToNsCssValue for &'a font_language_override::SpecifiedValue { } } -macro_rules! map_enum { - ( - $( - $prop:ident { - $($servo:ident => $gecko:ident,)+ - } - )+ - ) => { - $( - impl<'a> ToNsCssValue for &'a $prop::T { - fn convert(self, nscssvalue: &mut nsCSSValue) { - nscssvalue.set_enum(match *self { - $( $prop::T::$servo => structs::$gecko as i32, )+ - }) - } - } - )+ - } -} - -map_enum! { - font_style { - Normal => NS_FONT_STYLE_NORMAL, - Italic => NS_FONT_STYLE_ITALIC, - Oblique => NS_FONT_STYLE_OBLIQUE, - } - - font_stretch { - Normal => NS_FONT_STRETCH_NORMAL, - UltraCondensed => NS_FONT_STRETCH_ULTRA_CONDENSED, - ExtraCondensed => NS_FONT_STRETCH_EXTRA_CONDENSED, - Condensed => NS_FONT_STRETCH_CONDENSED, - SemiCondensed => NS_FONT_STRETCH_SEMI_CONDENSED, - SemiExpanded => NS_FONT_STRETCH_SEMI_EXPANDED, - Expanded => NS_FONT_STRETCH_EXPANDED, - ExtraExpanded => NS_FONT_STRETCH_EXTRA_EXPANDED, - UltraExpanded => NS_FONT_STRETCH_ULTRA_EXPANDED, - } -} - impl<'a> ToNsCssValue for &'a Vec<Source> { fn convert(self, nscssvalue: &mut nsCSSValue) { let src_len = self.iter().fold(0, |acc, src| { diff --git a/components/style/gecko_bindings/sugar/ns_css_value.rs b/components/style/gecko_bindings/sugar/ns_css_value.rs index 45693561510..644166e3797 100644 --- a/components/style/gecko_bindings/sugar/ns_css_value.rs +++ b/components/style/gecko_bindings/sugar/ns_css_value.rs @@ -167,19 +167,29 @@ impl nsCSSValue { unsafe { bindings::Gecko_CSSValue_SetAtomIdent(self, s.into_addrefed()) } } - /// Set to a font format + /// Set to a font format. pub fn set_font_format(&mut self, s: &str) { self.set_string_internal(s, nsCSSUnit::eCSSUnit_Font_Format); } - /// Set to a local font value + /// Set to a local font value. pub fn set_local_font(&mut self, s: &Atom) { self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_Local_Font); } + /// Set to a font stretch. + pub fn set_font_stretch(&mut self, s: f32) { + unsafe { bindings::Gecko_CSSValue_SetFontStretch(self, s) } + } + + /// Set to a font style + pub fn set_font_style(&mut self, s: f32) { + unsafe { bindings::Gecko_CSSValue_SetFontSlantStyle(self, s) } + } + /// Set to a font weight - pub fn set_font_weight(&mut self, w: u16) { - unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w as f32) } + pub fn set_font_weight(&mut self, w: f32) { + unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w) } } fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) { diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index 0d8fb817a85..76a7021ef5b 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -312,3 +312,9 @@ impl_threadsafe_refcount!( Gecko_AddRefSharedFontListArbitraryThread, Gecko_ReleaseSharedFontListArbitraryThread ); + +impl_threadsafe_refcount!( + ::gecko_bindings::structs::SheetLoadDataHolder, + Gecko_AddRefSheetLoadDataHolderArbitraryThread, + Gecko_ReleaseSheetLoadDataHolderArbitraryThread +); diff --git a/components/style/properties/build.py b/components/style/properties/build.py index 326859ea6d8..04418723ee4 100644 --- a/components/style/properties/build.py +++ b/components/style/properties/build.py @@ -21,7 +21,7 @@ RE_PYTHON_ADDR = re.compile(r'<.+? object at 0x[0-9a-fA-F]+>') def main(): - usage = "Usage: %s [ servo | gecko ] [ style-crate | html ]" % sys.argv[0] + usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib <template> | html ]" % sys.argv[0] if len(sys.argv) < 3: abort(usage) product = sys.argv[1] @@ -39,6 +39,12 @@ def main(): template = os.path.join(BASE, "gecko.mako.rs") rust = render(template, data=properties) write(os.environ["OUT_DIR"], "gecko_properties.rs", rust) + elif output == "geckolib": + if len(sys.argv) < 4: + abort(usage) + template = sys.argv[3] + header = render(template, data=properties) + sys.stdout.write(header) elif output == "html": write_html(properties) diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 938b2c2c2bf..3ca9d347157 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -385,6 +385,7 @@ class Alias(object): self.name = name self.ident = to_rust_ident(name) self.camel_case = to_camel_case(self.ident) + self.original = original self.enabled_in = original.enabled_in self.servo_pref = original.servo_pref self.gecko_pref = gecko_pref @@ -406,7 +407,7 @@ class Alias(object): return self.enabled_in == "content" def nscsspropertyid(self): - return "nsCSSPropertyID::eCSSPropertyAlias_%s" % self.camel_case + return "nsCSSPropertyID::eCSSPropertyAlias_%s" % self.ident class Method(object): diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 067d014442d..a3d316df321 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -25,8 +25,6 @@ use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom; use gecko_bindings::bindings::Gecko_CopyImageValueFrom; use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom; use gecko_bindings::bindings::Gecko_EnsureImageLayersLength; -use gecko_bindings::bindings::Gecko_FontWeight_SetFloat; -use gecko_bindings::bindings::Gecko_FontWeight_ToFloat; use gecko_bindings::bindings::Gecko_SetCursorArrayLength; use gecko_bindings::bindings::Gecko_SetCursorImageValue; use gecko_bindings::bindings::Gecko_StyleTransition_SetUnsupportedProperty; @@ -1806,7 +1804,7 @@ fn static_assert() { } pub fn set_computed_justify_items(&mut self, v: values::specified::JustifyItems) { - debug_assert_ne!(v.0, ::values::specified::align::AlignFlags::AUTO); + debug_assert_ne!(v.0, ::values::specified::align::AlignFlags::LEGACY); self.gecko.mJustifyItems = v.into(); } @@ -2601,15 +2599,49 @@ fn static_assert() { } pub fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) { - unsafe { Gecko_FontWeight_SetFloat(&mut self.gecko.mFont.weight, v.0 as f32) }; + unsafe { bindings::Gecko_FontWeight_SetFloat(&mut self.gecko.mFont.weight, v.0) }; } ${impl_simple_copy('font_weight', 'mFont.weight')} pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T { - let weight: f32 = unsafe { Gecko_FontWeight_ToFloat(self.gecko.mFont.weight) }; - debug_assert!(weight >= 0.0 && - weight <= ::std::u16::MAX as f32); - longhands::font_weight::computed_value::T(weight as u16) + let weight: f32 = unsafe { + bindings::Gecko_FontWeight_ToFloat(self.gecko.mFont.weight) + }; + longhands::font_weight::computed_value::T(weight) + } + + pub fn set_font_stretch(&mut self, v: longhands::font_stretch::computed_value::T) { + unsafe { bindings::Gecko_FontStretch_SetFloat(&mut self.gecko.mFont.stretch, (v.0).0) }; + } + ${impl_simple_copy('font_stretch', 'mFont.stretch')} + pub fn clone_font_stretch(&self) -> longhands::font_stretch::computed_value::T { + use values::computed::Percentage; + use values::generics::NonNegative; + + let stretch = + unsafe { bindings::Gecko_FontStretch_ToFloat(self.gecko.mFont.stretch) }; + debug_assert!(stretch >= 0.); + + NonNegative(Percentage(stretch)) + } + + pub fn set_font_style(&mut self, v: longhands::font_style::computed_value::T) { + use values::generics::font::FontStyle; + let s = &mut self.gecko.mFont.style; + unsafe { + match v { + FontStyle::Normal => bindings::Gecko_FontSlantStyle_SetNormal(s), + FontStyle::Italic => bindings::Gecko_FontSlantStyle_SetItalic(s), + FontStyle::Oblique(ref angle) => { + bindings::Gecko_FontSlantStyle_SetOblique(s, angle.0.degrees()) + } + } + } + } + ${impl_simple_copy('font_style', 'mFont.style')} + pub fn clone_font_style(&self) -> longhands::font_style::computed_value::T { + use values::computed::font::FontStyle; + FontStyle::from_gecko(self.gecko.mFont.style) } ${impl_simple_type_with_conversion("font_synthesis", "mFont.synthesis")} diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index a06d9f62f71..e2d15139128 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -19,7 +19,6 @@ use num_traits::Zero; use properties::{CSSWideKeyword, PropertyDeclaration}; use properties::longhands; use properties::longhands::font_weight::computed_value::T as FontWeight; -use properties::longhands::font_stretch::computed_value::T as FontStretch; use properties::longhands::visibility::computed_value::T as Visibility; use properties::PropertyId; use properties::{LonghandId, ShorthandId}; @@ -873,20 +872,6 @@ impl ToAnimatedZero for MaxLength { fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) } } -/// <http://dev.w3.org/csswg/css-transitions/#animtype-font-weight> -impl Animate for FontWeight { - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { - let a = self.0 as f64; - let b = other.0 as f64; - const NORMAL: f64 = 400.; - let (this_weight, other_weight) = procedure.weights(); - let weight = (a - NORMAL) * this_weight + (b - NORMAL) * other_weight + NORMAL; - let weight = (weight.max(100.).min(900.) / 100.).round() * 100.; - Ok(FontWeight(weight as u16)) - } -} - impl ToAnimatedZero for FontWeight { #[inline] fn to_animated_zero(&self) -> Result<Self, ()> { @@ -894,62 +879,6 @@ impl ToAnimatedZero for FontWeight { } } -/// <https://drafts.csswg.org/css-fonts/#font-stretch-prop> -impl Animate for FontStretch { - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> - { - let from = f64::from(*self); - let to = f64::from(*other); - let normal = f64::from(FontStretch::Normal); - let (this_weight, other_weight) = procedure.weights(); - let result = (from - normal) * this_weight + (to - normal) * other_weight + normal; - Ok(result.into()) - } -} - -impl ComputeSquaredDistance for FontStretch { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { - f64::from(*self).compute_squared_distance(&(*other).into()) - } -} - -impl ToAnimatedZero for FontStretch { - #[inline] - fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) } -} - -/// We should treat font stretch as real number in order to interpolate this property. -/// <https://drafts.csswg.org/css-fonts-3/#font-stretch-animation> -impl From<FontStretch> for f64 { - fn from(stretch: FontStretch) -> f64 { - use self::FontStretch::*; - match stretch { - UltraCondensed => 1.0, - ExtraCondensed => 2.0, - Condensed => 3.0, - SemiCondensed => 4.0, - Normal => 5.0, - SemiExpanded => 6.0, - Expanded => 7.0, - ExtraExpanded => 8.0, - UltraExpanded => 9.0, - } - } -} - -impl Into<FontStretch> for f64 { - fn into(self) -> FontStretch { - use properties::longhands::font_stretch::computed_value::T::*; - let index = (self + 0.5).floor().min(9.0).max(1.0); - static FONT_STRETCH_ENUM_MAP: [FontStretch; 9] = - [ UltraCondensed, ExtraCondensed, Condensed, SemiCondensed, Normal, - SemiExpanded, Expanded, ExtraExpanded, UltraExpanded ]; - FONT_STRETCH_ENUM_MAP[(index - 1.0) as usize] - } -} - /// <https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def> impl Animate for FontVariationSettings { #[inline] diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index bf2e8e9210b..9bb3dbcec28 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -43,17 +43,19 @@ needs_context=False, )} - ${helpers.predefined_type("border-%s-width" % side_name, - "BorderSideWidth", - "::values::computed::NonNegativeLength::new(3.)", - computed_type="::values::computed::NonNegativeLength", - alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-width"), - spec=maybe_logical_spec(side, "width"), - animation_value_type="NonNegativeLength", - logical=is_logical, - flags="APPLIES_TO_FIRST_LETTER", - allow_quirks=not is_logical, - servo_restyle_damage = "reflow rebuild_and_reflow_inline")} + ${helpers.predefined_type( + "border-%s-width" % side_name, + "BorderSideWidth", + "::values::computed::NonNegativeLength::new(3.)", + computed_type="::values::computed::NonNegativeLength", + alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-width"), + spec=maybe_logical_spec(side, "width"), + animation_value_type="NonNegativeLength", + logical=is_logical, + flags="APPLIES_TO_FIRST_LETTER GETCS_NEEDS_LAYOUT_FLUSH", + allow_quirks=not is_logical, + servo_restyle_damage="reflow rebuild_and_reflow_inline" + )} % endfor ${helpers.gecko_keyword_conversion(Keyword('border-style', diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index f671144b126..806afcbd1b6 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -403,14 +403,18 @@ ${helpers.predefined_type( <% transform_extra_prefixes = "moz:layout.css.prefixes.transforms webkit" %> -${helpers.predefined_type("transform", "Transform", - "generics::transform::Transform::none()", - extra_prefixes=transform_extra_prefixes, - animation_value_type="ComputedValue", - gecko_ffi_name="mSpecifiedTransform", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", - spec="https://drafts.csswg.org/css-transforms/#propdef-transform", - servo_restyle_damage = "reflow_out_of_flow")} +${helpers.predefined_type( + "transform", + "Transform", + "generics::transform::Transform::none()", + extra_prefixes=transform_extra_prefixes, + animation_value_type="ComputedValue", + gecko_ffi_name="mSpecifiedTransform", + flags="CREATES_STACKING_CONTEXT FIXPOS_CB \ + GETCS_NEEDS_LAYOUT_FLUSH CAN_ANIMATE_ON_COMPOSITOR", + spec="https://drafts.csswg.org/css-transforms/#propdef-transform", + servo_restyle_damage="reflow_out_of_flow" +)} ${helpers.predefined_type("rotate", "Rotate", "generics::transform::Rotate::None", @@ -430,14 +434,17 @@ ${helpers.predefined_type("scale", "Scale", spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms", servo_restyle_damage = "reflow_out_of_flow")} -${helpers.predefined_type("translate", "Translate", - "generics::transform::Translate::None", - animation_value_type="ComputedValue", - boxed=True, - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", - gecko_pref="layout.css.individual-transform.enabled", - spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms", - servo_restyle_damage = "reflow_out_of_flow")} +${helpers.predefined_type( + "translate", + "Translate", + "generics::transform::Translate::None", + animation_value_type="ComputedValue", + boxed=True, + flags="CREATES_STACKING_CONTEXT FIXPOS_CB GETCS_NEEDS_LAYOUT_FLUSH", + gecko_pref="layout.css.individual-transform.enabled", + spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms", + servo_restyle_damage="reflow_out_of_flow" +)} // CSSOM View Module // https://www.w3.org/TR/cssom-view-1/ @@ -529,14 +536,17 @@ ${helpers.predefined_type( servo_restyle_damage = "reflow_out_of_flow", )} -${helpers.predefined_type("perspective-origin", - "position::Position", - "computed::position::Position::center()", - boxed=True, - extra_prefixes=transform_extra_prefixes, - spec="https://drafts.csswg.org/css-transforms-2/#perspective-origin-property", - animation_value_type="ComputedValue", - servo_restyle_damage = "reflow_out_of_flow")} +${helpers.predefined_type( + "perspective-origin", + "position::Position", + "computed::position::Position::center()", + boxed=True, + extra_prefixes=transform_extra_prefixes, + spec="https://drafts.csswg.org/css-transforms-2/#perspective-origin-property", + flags="GETCS_NEEDS_LAYOUT_FLUSH", + animation_value_type="ComputedValue", + servo_restyle_damage="reflow_out_of_flow" +)} ${helpers.single_keyword("backface-visibility", "visible hidden", @@ -565,15 +575,18 @@ ${helpers.predefined_type( servo_restyle_damage = "reflow_out_of_flow", )} -${helpers.predefined_type("transform-origin", - "TransformOrigin", - "computed::TransformOrigin::initial_value()", - animation_value_type="ComputedValue", - extra_prefixes=transform_extra_prefixes, - gecko_ffi_name="mTransformOrigin", - boxed=True, - spec="https://drafts.csswg.org/css-transforms/#transform-origin-property", - servo_restyle_damage = "reflow_out_of_flow")} +${helpers.predefined_type( + "transform-origin", + "TransformOrigin", + "computed::TransformOrigin::initial_value()", + animation_value_type="ComputedValue", + extra_prefixes=transform_extra_prefixes, + gecko_ffi_name="mTransformOrigin", + boxed=True, + flags="GETCS_NEEDS_LAYOUT_FLUSH", + spec="https://drafts.csswg.org/css-transforms/#transform-origin-property", + servo_restyle_damage="reflow_out_of_flow" +)} ${helpers.predefined_type("contain", "Contain", diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index 3b2a3ec38ed..7a97c3f41e3 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -31,17 +31,6 @@ ${helpers.predefined_type( -${helpers.predefined_type( - "column-gap", - "length::NonNegativeLengthOrPercentageOrNormal", - "Either::Second(Normal)", - extra_prefixes="moz", - servo_pref="layout.columns.enabled", - animation_value_type="NonNegativeLengthOrPercentageOrNormal", - spec="https://drafts.csswg.org/css-multicol/#propdef-column-gap", - servo_restyle_damage = "reflow", -)} - ${helpers.single_keyword("column-fill", "balance auto", extra_prefixes="moz", products="gecko", animation_value_type="discrete", spec="https://drafts.csswg.org/css-multicol/#propdef-column-fill")} diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 3292e1bf36c..30493bd270d 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -7,13 +7,16 @@ // Box-shadow, etc. <% data.new_style_struct("Effects", inherited=False) %> -${helpers.predefined_type("opacity", - "Opacity", - "1.0", - animation_value_type="ComputedValue", - flags="CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER", - spec="https://drafts.csswg.org/css-color/#opacity", - servo_restyle_damage = "reflow_out_of_flow")} +${helpers.predefined_type( + "opacity", + "Opacity", + "1.0", + animation_value_type="ComputedValue", + flags="CREATES_STACKING_CONTEXT APPLIES_TO_PLACEHOLDER \ + CAN_ANIMATE_ON_COMPOSITOR", + spec="https://drafts.csswg.org/css-color/#opacity", + servo_restyle_damage = "reflow_out_of_flow" +)} ${helpers.predefined_type( "box-shadow", diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 0d246d3b358..0477a2cd0d5 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -15,15 +15,15 @@ ${helpers.predefined_type("font-family", spec="https://drafts.csswg.org/css-fonts/#propdef-font-family", servo_restyle_damage="rebuild_and_reflow")} -${helpers.single_keyword_system( +${helpers.predefined_type( "font-style", - "normal italic oblique", - gecko_constant_prefix="NS_FONT_STYLE", - gecko_ffi_name="mFont.style", - spec="https://drafts.csswg.org/css-fonts/#propdef-font-style", + "FontStyle", + initial_value="computed::FontStyle::normal()", + initial_specified_value="specified::FontStyle::normal()", + animation_value_type="FontStyle", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", - animation_value_type="discrete", - servo_restyle_damage="rebuild_and_reflow" + spec="https://drafts.csswg.org/css-fonts/#propdef-font-style", + servo_restyle_damage="rebuild_and_reflow", )} <% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS", @@ -43,14 +43,16 @@ ${helpers.single_keyword_system("font-variant-caps", animation_value_type="discrete", servo_restyle_damage="rebuild_and_reflow")} -${helpers.predefined_type("font-weight", - "FontWeight", - initial_value="computed::FontWeight::normal()", - initial_specified_value="specified::FontWeight::Normal", - animation_value_type="ComputedValue", - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", - spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight", - servo_restyle_damage="rebuild_and_reflow")} +${helpers.predefined_type( + "font-weight", + "FontWeight", + initial_value="computed::FontWeight::normal()", + initial_specified_value="specified::FontWeight::normal()", + animation_value_type="Number", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight", + servo_restyle_damage="rebuild_and_reflow", +)} ${helpers.predefined_type("font-size", "FontSize", @@ -79,17 +81,16 @@ ${helpers.predefined_type("font-synthesis", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-fonts/#propdef-font-synthesis")} -${helpers.single_keyword_system("font-stretch", - "normal ultra-condensed extra-condensed condensed \ - semi-condensed semi-expanded expanded extra-expanded \ - ultra-expanded", - gecko_ffi_name="mFont.stretch", - gecko_constant_prefix="NS_FONT_STRETCH", - cast_type='i16', - spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch", - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", - animation_value_type="ComputedValue", - servo_restyle_damage="rebuild_and_reflow")} +${helpers.predefined_type( + "font-stretch", + "FontStretch", + initial_value="computed::NonNegativePercentage::hundred()", + initial_specified_value="specified::FontStretch::normal()", + animation_value_type="Percentage", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch", + servo_restyle_damage="rebuild_and_reflow", +)} ${helpers.single_keyword_system("font-kerning", "auto none normal", @@ -288,12 +289,11 @@ ${helpers.predefined_type("-x-text-zoom", -moz-window -moz-document -moz-workspace -moz-desktop -moz-info -moz-dialog -moz-button -moz-pull-down-menu -moz-list -moz-field""".split() - kw_font_props = """font_style font_variant_caps font_stretch + kw_font_props = """font_variant_caps font_kerning font_variant_position font_variant_ligatures font_variant_east_asian font_variant_numeric font_optical_sizing""".split() - kw_cast = """font_style font_variant_caps font_stretch - font_kerning font_variant_position + kw_cast = """font_variant_caps font_kerning font_variant_position font_optical_sizing""".split() %> #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)] @@ -328,7 +328,9 @@ ${helpers.predefined_type("-x-text-zoom", use gecko_bindings::bindings; use gecko_bindings::structs::{LookAndFeel_FontID, nsFont}; use std::mem; - use values::computed::font::{FontSize, FontFamilyList}; + use values::computed::Percentage; + use values::computed::font::{FontSize, FontStyle, FontFamilyList}; + use values::generics::NonNegative; let id = match *self { % for font in system_fonts: @@ -347,7 +349,11 @@ ${helpers.predefined_type("-x-text-zoom", cx.device().pres_context() ) } - let weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight); + let font_weight = longhands::font_weight::computed_value::T::from_gecko_weight(system.weight); + let font_stretch = NonNegative(Percentage(unsafe { + bindings::Gecko_FontStretch_ToFloat(system.stretch) + })); + let font_style = FontStyle::from_gecko(system.style); let ret = ComputedSystemFont { font_family: longhands::font_family::computed_value::T( FontFamilyList( @@ -355,10 +361,12 @@ ${helpers.predefined_type("-x-text-zoom", ) ), font_size: FontSize { - size: Au(system.size).into(), - keyword_info: None + size: Au(system.size).into(), + keyword_info: None }, - font_weight: weight, + font_weight, + font_stretch, + font_style, font_size_adjust: longhands::font_size_adjust::computed_value ::T::from_gecko_adjust(system.sizeAdjust), % for kwprop in kw_font_props: diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 99efd55c60f..abf1054675c 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -6,13 +6,16 @@ <% from data import Keyword %> <% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %> -${helpers.predefined_type("line-height", - "LineHeight", - "computed::LineHeight::normal()", - animation_value_type="LineHeight", - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", - spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height", - servo_restyle_damage = "reflow")} +${helpers.predefined_type( + "line-height", + "LineHeight", + "computed::LineHeight::normal()", + animation_value_type="LineHeight", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE \ + APPLIES_TO_PLACEHOLDER GETCS_NEEDS_LAYOUT_FLUSH", + spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height", + servo_restyle_damage="reflow" +)} // CSS Text Module Level 3 diff --git a/components/style/properties/longhand/margin.mako.rs b/components/style/properties/longhand/margin.mako.rs index 5c0d06f8206..1a964bcbb74 100644 --- a/components/style/properties/longhand/margin.mako.rs +++ b/components/style/properties/longhand/margin.mako.rs @@ -12,12 +12,17 @@ if side[1]: spec = "https://drafts.csswg.org/css-logical-props/#propdef-margin-%s" % side[1] %> - ${helpers.predefined_type("margin-%s" % side[0], "LengthOrPercentageOrAuto", - "computed::LengthOrPercentageOrAuto::Length(computed::Length::new(0.))", - alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"), - allow_quirks=not side[1], - animation_value_type="ComputedValue", logical = side[1], spec = spec, - flags="APPLIES_TO_FIRST_LETTER", - allowed_in_page_rule=True, - servo_restyle_damage = "reflow")} + ${helpers.predefined_type( + "margin-%s" % side[0], + "LengthOrPercentageOrAuto", + "computed::LengthOrPercentageOrAuto::Length(computed::Length::new(0.))", + alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"), + allow_quirks=not side[1], + animation_value_type="ComputedValue", + logical=side[1], + spec=spec, + flags="APPLIES_TO_FIRST_LETTER GETCS_NEEDS_LAYOUT_FLUSH", + allowed_in_page_rule=True, + servo_restyle_damage="reflow" + )} % endfor diff --git a/components/style/properties/longhand/padding.mako.rs b/components/style/properties/longhand/padding.mako.rs index be0f9553cd2..3d2467c0ca0 100644 --- a/components/style/properties/longhand/padding.mako.rs +++ b/components/style/properties/longhand/padding.mako.rs @@ -14,13 +14,16 @@ if side[1]: spec = "https://drafts.csswg.org/css-logical-props/#propdef-padding-%s" % side[1] %> - ${helpers.predefined_type("padding-%s" % side[0], "NonNegativeLengthOrPercentage", - "computed::NonNegativeLengthOrPercentage::zero()", - alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"), - animation_value_type="NonNegativeLengthOrPercentage", - logical = side[1], - spec = spec, - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_PLACEHOLDER", - allow_quirks=not side[1], - servo_restyle_damage = "reflow rebuild_and_reflow_inline")} + ${helpers.predefined_type( + "padding-%s" % side[0], + "NonNegativeLengthOrPercentage", + "computed::NonNegativeLengthOrPercentage::zero()", + alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"), + animation_value_type="NonNegativeLengthOrPercentage", + logical=side[1], + spec=spec, + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_PLACEHOLDER GETCS_NEEDS_LAYOUT_FLUSH", + allow_quirks=not side[1], + servo_restyle_damage="reflow rebuild_and_reflow_inline" + )} % endfor diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 5d64159654c..a99cebfdba9 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -10,18 +10,28 @@ // "top" / "left" / "bottom" / "right" % for side in PHYSICAL_SIDES: - ${helpers.predefined_type(side, "LengthOrPercentageOrAuto", - "computed::LengthOrPercentageOrAuto::Auto", - spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side, - animation_value_type="ComputedValue", - allow_quirks=True, servo_restyle_damage = "reflow_out_of_flow")} + ${helpers.predefined_type( + side, + "LengthOrPercentageOrAuto", + "computed::LengthOrPercentageOrAuto::Auto", + spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side, + flags="GETCS_NEEDS_LAYOUT_FLUSH", + animation_value_type="ComputedValue", + allow_quirks=True, + servo_restyle_damage="reflow_out_of_flow" + )} % endfor // offset-* logical properties, map to "top" / "left" / "bottom" / "right" % for side in LOGICAL_SIDES: - ${helpers.predefined_type("offset-%s" % side, "LengthOrPercentageOrAuto", - "computed::LengthOrPercentageOrAuto::Auto", - spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side, - animation_value_type="ComputedValue", logical=True)} + ${helpers.predefined_type( + "offset-%s" % side, + "LengthOrPercentageOrAuto", + "computed::LengthOrPercentageOrAuto::Auto", + spec="https://drafts.csswg.org/css-logical-props/#propdef-offset-%s" % side, + flags="GETCS_NEEDS_LAYOUT_FLUSH", + animation_value_type="ComputedValue", + logical=True, + )} % endfor #[cfg(feature = "gecko")] @@ -118,11 +128,13 @@ ${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse", #[cfg(feature = "gecko")] impl_align_conversions!(::values::specified::align::AlignItems); - ${helpers.predefined_type(name="justify-items", - type="JustifyItems", - initial_value="computed::JustifyItems::auto()", - spec="https://drafts.csswg.org/css-align/#propdef-justify-items", - animation_value_type="discrete")} + ${helpers.predefined_type( + name="justify-items", + type="JustifyItems", + initial_value="computed::JustifyItems::legacy()", + spec="https://drafts.csswg.org/css-align/#propdef-justify-items", + animation_value_type="discrete", + )} #[cfg(feature = "gecko")] impl_align_conversions!(::values::specified::align::JustifyItems); @@ -211,7 +223,8 @@ ${helpers.predefined_type( allow_quirks=not logical, spec=spec % size, animation_value_type="MozLength", - servo_restyle_damage = "reflow" + flags="GETCS_NEEDS_LAYOUT_FLUSH", + servo_restyle_damage="reflow" )} // min-width, min-height, min-block-size, min-inline-size, ${helpers.predefined_type( @@ -289,13 +302,6 @@ ${helpers.predefined_type("object-position", animation_value_type="ComputedValue")} % for kind in ["row", "column"]: - ${helpers.predefined_type("grid-%s-gap" % kind, - "NonNegativeLengthOrPercentage", - "computed::NonNegativeLengthOrPercentage::zero()", - spec="https://drafts.csswg.org/css-grid/#propdef-grid-%s-gap" % kind, - animation_value_type="NonNegativeLengthOrPercentage", - products="gecko")} - % for range in ["start", "end"]: ${helpers.predefined_type("grid-%s-%s" % (kind, range), "GridLine", @@ -316,13 +322,16 @@ ${helpers.predefined_type("object-position", products="gecko", boxed=True)} - ${helpers.predefined_type("grid-template-%ss" % kind, - "GridTemplateComponent", - "specified::GenericGridTemplateComponent::None", - products="gecko", - spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind, - boxed=True, - animation_value_type="discrete")} + ${helpers.predefined_type( + "grid-template-%ss" % kind, + "GridTemplateComponent", + "specified::GenericGridTemplateComponent::None", + products="gecko", + spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-%ss" % kind, + boxed=True, + flags="GETCS_NEEDS_LAYOUT_FLUSH", + animation_value_type="discrete" + )} % endfor @@ -339,3 +348,23 @@ ${helpers.predefined_type("grid-template-areas", products="gecko", animation_value_type="discrete", spec="https://drafts.csswg.org/css-grid/#propdef-grid-template-areas")} + +${helpers.predefined_type("column-gap", + "length::NonNegativeLengthOrPercentageOrNormal", + "Either::Second(Normal)", + alias="grid-column-gap" if product == "gecko" else "", + extra_prefixes="moz", + servo_pref="layout.columns.enabled", + spec="https://drafts.csswg.org/css-align-3/#propdef-column-gap", + animation_value_type="NonNegativeLengthOrPercentageOrNormal", + servo_restyle_damage = "reflow")} + +// no need for -moz- prefixed alias for this property +${helpers.predefined_type("row-gap", + "length::NonNegativeLengthOrPercentageOrNormal", + "Either::Second(Normal)", + alias="grid-row-gap", + products="gecko", + spec="https://drafts.csswg.org/css-align-3/#propdef-row-gap", + animation_value_type="NonNegativeLengthOrPercentageOrNormal", + servo_restyle_damage = "reflow")} diff --git a/components/style/properties/longhand/ui.mako.rs b/components/style/properties/longhand/ui.mako.rs index 5f2215760f8..683a8967ea3 100644 --- a/components/style/properties/longhand/ui.mako.rs +++ b/components/style/properties/longhand/ui.mako.rs @@ -41,28 +41,36 @@ ${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet" enabled_in="chrome", spec="None (Nonstandard internal property)")} +// TODO(bug 1419695) This should be hidden from content. ${helpers.predefined_type("-moz-window-opacity", "Opacity", "1.0", products="gecko", gecko_ffi_name="mWindowOpacity", animation_value_type="ComputedValue", - enabled_in="chrome", spec="None (Nonstandard internal property)")} -${helpers.predefined_type("-moz-window-transform", "Transform", - "generics::transform::Transform::none()", - products="gecko", gecko_ffi_name="mSpecifiedWindowTransform", - animation_value_type="ComputedValue", - enabled_in="chrome", - spec="None (Nonstandard internal property)")} +// TODO(bug 1419695) This should be hidden from content. +${helpers.predefined_type( + "-moz-window-transform", + "Transform", + "generics::transform::Transform::none()", + products="gecko", + gecko_ffi_name="mSpecifiedWindowTransform", + flags="GETCS_NEEDS_LAYOUT_FLUSH", + animation_value_type="ComputedValue", + spec="None (Nonstandard internal property)" +)} -${helpers.predefined_type("-moz-window-transform-origin", - "TransformOrigin", - "computed::TransformOrigin::initial_value()", - animation_value_type="ComputedValue", - gecko_ffi_name="mWindowTransformOrigin", - products="gecko", - boxed=True, - enabled_in="chrome", - spec="None (Nonstandard internal property)")} +// TODO(bug 1419695) This should be hidden from content. +${helpers.predefined_type( + "-moz-window-transform-origin", + "TransformOrigin", + "computed::TransformOrigin::initial_value()", + animation_value_type="ComputedValue", + gecko_ffi_name="mWindowTransformOrigin", + products="gecko", + boxed=True, + flags="GETCS_NEEDS_LAYOUT_FLUSH", + spec="None (Nonstandard internal property)" +)} // TODO(emilio): Probably also should be hidden from content. ${helpers.predefined_type("-moz-force-broken-image-icon", diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index a27a2d2e579..1042a5d1a4d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -781,6 +781,15 @@ bitflags! { const APPLIES_TO_FIRST_LINE = 1 << 4; /// This longhand property applies to ::placeholder. const APPLIES_TO_PLACEHOLDER = 1 << 5; + + /* The following flags are currently not used in Rust code, they + * only need to be listed in corresponding properties so that + * they can be checked in the C++ side via ServoCSSPropList.h. */ + /// This property's getComputedStyle implementation requires layout + /// to be flushed. + const GETCS_NEEDS_LAYOUT_FLUSH = 0; + /// This property can be animated on the compositor. + const CAN_ANIMATE_ON_COMPOSITOR = 0; } } @@ -2233,9 +2242,13 @@ pub mod style_structs { pub fn compute_font_hash(&mut self) { // Corresponds to the fields in // `gfx::font_template::FontTemplateDescriptor`. + // + // FIXME(emilio): Where's font-style? let mut hasher: FnvHasher = Default::default(); - hasher.write_u16(self.font_weight.0); - self.font_stretch.hash(&mut hasher); + // We hash the floating point number with four decimal + // places. + hasher.write_u64((self.font_weight.0 * 10000.).trunc() as u64); + hasher.write_u64(((self.font_stretch.0).0 * 10000.).trunc() as u64); self.font_family.hash(&mut hasher); self.hash = hasher.finish() } diff --git a/components/style/properties/shorthand/font.mako.rs b/components/style/properties/shorthand/font.mako.rs index cc3cd819cf2..5e14fd6ab50 100644 --- a/components/style/properties/shorthand/font.mako.rs +++ b/components/style/properties/shorthand/font.mako.rs @@ -27,6 +27,7 @@ use properties::longhands::system_font::SystemFont; use values::specified::text::LineHeight; use values::specified::FontSize; + use values::specified::font::{FontStretch, FontStretchKeyword}; <% gecko_sub_properties = "kerning language_override size_adjust \ @@ -94,8 +95,8 @@ } } if stretch.is_none() { - if let Ok(value) = input.try(|input| font_stretch::parse(context, input)) { - stretch = Some(value); + if let Ok(value) = input.try(FontStretchKeyword::parse) { + stretch = Some(FontStretch::Keyword(value)); continue } } @@ -180,15 +181,31 @@ % endfor % endif - // In case of serialization for canvas font, we need to drop - // initial values of properties other than size and family. - % for name in "style variant_caps weight stretch".split(): + // Only font-stretch keywords are allowed as part as the font + // shorthand. + let font_stretch = match *self.font_stretch { + FontStretch::Keyword(kw) => kw, + FontStretch::Stretch(percentage) => { + match FontStretchKeyword::from_percentage(percentage.get()) { + Some(kw) => kw, + None => return Ok(()), + } + } + FontStretch::System(..) => return Ok(()), + }; + + % for name in "style variant_caps weight".split(): if self.font_${name} != &font_${name}::get_initial_specified_value() { self.font_${name}.to_css(dest)?; dest.write_str(" ")?; } % endfor + if font_stretch != FontStretchKeyword::Normal { + font_stretch.to_css(dest)?; + dest.write_str(" ")?; + } + self.font_size.to_css(dest)?; if *self.line_height != LineHeight::normal() { diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index e5b07d616e4..19ca0cf1916 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -108,30 +108,30 @@ } </%helpers:shorthand> -<%helpers:shorthand name="grid-gap" sub_properties="grid-row-gap grid-column-gap" - spec="https://drafts.csswg.org/css-grid/#propdef-grid-gap" +<%helpers:shorthand name="gap" alias="grid-gap" sub_properties="row-gap column-gap" + spec="https://drafts.csswg.org/css-align-3/#gap-shorthand" products="gecko"> - use properties::longhands::{grid_row_gap, grid_column_gap}; + use properties::longhands::{row_gap, column_gap}; pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Longhands, ParseError<'i>> { - let row_gap = grid_row_gap::parse(context, input)?; - let column_gap = input.try(|input| grid_column_gap::parse(context, input)).unwrap_or(row_gap.clone()); + let r_gap = row_gap::parse(context, input)?; + let c_gap = input.try(|input| column_gap::parse(context, input)).unwrap_or(r_gap.clone()); Ok(expanded! { - grid_row_gap: row_gap, - grid_column_gap: column_gap, + row_gap: r_gap, + column_gap: c_gap, }) } impl<'a> ToCss for LonghandsToSerialize<'a> { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { - if self.grid_row_gap == self.grid_column_gap { - self.grid_row_gap.to_css(dest) + if self.row_gap == self.column_gap { + self.row_gap.to_css(dest) } else { - self.grid_row_gap.to_css(dest)?; + self.row_gap.to_css(dest)?; dest.write_str(" ")?; - self.grid_column_gap.to_css(dest) + self.column_gap.to_css(dest) } } } diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index 25d7a8e896d..1527a743de5 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -162,6 +162,16 @@ const FREE_LIST_SENTINEL: *mut RuleNode = 0x01 as *mut RuleNode; /// another thread is currently adding an entry). We spin if we find this value. const FREE_LIST_LOCKED: *mut RuleNode = 0x02 as *mut RuleNode; +/// A counter to track how many inner shadow roots rules deep we are. +/// +/// This is used to handle: +/// +/// https://drafts.csswg.org/css-scoping/#shadow-cascading +/// +/// In particular, it'd be `0` for the innermost shadow host, `1` for the next, +/// and so on. +pub type ShadowCascadeOrder = u8; + impl RuleTree { /// Construct a new rule tree. pub fn new() -> Self { @@ -198,7 +208,7 @@ impl RuleTree { guards: &StylesheetGuards, ) -> StrongRuleNode where - I: Iterator<Item = (StyleSource, CascadeLevel)>, + I: Iterator<Item = (StyleSource, CascadeLevel, ShadowCascadeOrder)>, { use self::CascadeLevel::*; let mut current = self.root.clone(); @@ -206,13 +216,18 @@ impl RuleTree { let mut found_important = false; let mut important_style_attr = None; - let mut important_author = SmallVec::<[StyleSource; 4]>::new(); + + let mut important_same_tree = SmallVec::<[StyleSource; 4]>::new(); + let mut important_inner_shadow = SmallVec::<[SmallVec<[StyleSource; 4]>; 4]>::new(); + important_inner_shadow.push(SmallVec::new()); + let mut important_user = SmallVec::<[StyleSource; 4]>::new(); let mut important_ua = SmallVec::<[StyleSource; 4]>::new(); let mut transition = None; - for (source, level) in iter { - debug_assert!(last_level <= level, "Not really ordered"); + let mut last_cascade_order = 0; + for (source, level, shadow_cascade_order) in iter { + debug_assert!(level >= last_level, "Not really ordered"); debug_assert!(!level.is_important(), "Important levels handled internally"); let any_important = { let pdb = source.read(level.guard(guards)); @@ -222,7 +237,22 @@ impl RuleTree { if any_important { found_important = true; match level { - AuthorNormal => important_author.push(source.clone()), + InnerShadowNormal => { + debug_assert!( + shadow_cascade_order >= last_cascade_order, + "Not really ordered" + ); + if shadow_cascade_order > last_cascade_order && + !important_inner_shadow.last().unwrap().is_empty() + { + last_cascade_order = shadow_cascade_order; + important_inner_shadow.push(SmallVec::new()); + } + important_inner_shadow.last_mut().unwrap().push(source.clone()) + } + SameTreeAuthorNormal => { + important_same_tree.push(source.clone()) + }, UANormal => important_ua.push(source.clone()), UserNormal => important_user.push(source.clone()), StyleAttributeNormal => { @@ -265,14 +295,20 @@ impl RuleTree { // followed by any transition rule. // - for source in important_author.drain() { - current = current.ensure_child(self.root.downgrade(), source, AuthorImportant); + for source in important_same_tree.drain() { + current = current.ensure_child(self.root.downgrade(), source, SameTreeAuthorImportant); } if let Some(source) = important_style_attr { current = current.ensure_child(self.root.downgrade(), source, StyleAttributeImportant); } + for mut list in important_inner_shadow.drain().rev() { + for source in list.drain() { + current = current.ensure_child(self.root.downgrade(), source, InnerShadowImportant); + } + } + for source in important_user.drain() { current = current.ensure_child(self.root.downgrade(), source, UserImportant); } @@ -295,9 +331,10 @@ impl RuleTree { applicable_declarations: &mut ApplicableDeclarationList, guards: &StylesheetGuards, ) -> StrongRuleNode { - let rules = applicable_declarations.drain().map(|d| d.order_and_level()); - let rule_node = self.insert_ordered_rules_with_important(rules, guards); - rule_node + self.insert_ordered_rules_with_important( + applicable_declarations.drain().map(|d| d.for_rule_tree()), + guards, + ) } /// Insert the given rules, that must be in proper order by specifity, and @@ -381,8 +418,8 @@ impl RuleTree { // also equally valid. This is less likely, and would require an // in-place mutation of the source, which is, at best, fiddly, // so let's skip it for now. - let is_here_already = match ¤t.get().source { - &StyleSource::Declarations(ref already_here) => { + let is_here_already = match current.get().source { + StyleSource::Declarations(ref already_here) => { pdb.with_arc(|arc| Arc::ptr_eq(arc, already_here)) }, _ => unreachable!("Replacing non-declarations style?"), @@ -500,9 +537,22 @@ const RULE_TREE_GC_INTERVAL: usize = 300; /// The order of variants declared here is significant, and must be in /// _ascending_ order of precedence. /// +/// See also [4] for the Shadow DOM bits. We rely on the invariant that rules +/// from outside the tree the element is in can't affect the element. +/// +/// The opposite is not true (i.e., :host and ::slotted) from an "inner" shadow +/// tree may affect an element connected to the document or an "outer" shadow +/// tree. +/// +/// We need to differentiate between rules from the same tree and "inner" shadow +/// trees in order to be able to find the right position for the style attribute +/// easily. Otherwise we wouldn't be able to avoid selector-matching when a +/// style attribute is added or removed. +/// /// [1]: https://drafts.csswg.org/css-cascade/#cascade-origin /// [2]: https://drafts.csswg.org/css-cascade/#preshint /// [3]: https://html.spec.whatwg.org/multipage/#presentational-hints +/// [4]: https://drafts.csswg.org/css-scoping/#shadow-cascading #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)] #[cfg_attr(feature = "servo", derive(MallocSizeOf))] @@ -513,18 +563,27 @@ pub enum CascadeLevel { UserNormal, /// Presentational hints. PresHints, - /// Author normal rules. - AuthorNormal, + /// Shadow DOM styles from "inner" shadow trees. + /// + /// See above for why this is needed instead of merging InnerShadowNormal, + /// SameTreeAuthorNormal and StyleAttributeNormal inside something like + /// AuthorNormal. + InnerShadowNormal, + /// Author normal rules from the same tree the element is in. + SameTreeAuthorNormal, /// Style attribute normal rules. StyleAttributeNormal, /// SVG SMIL animations. SMILOverride, /// CSS animations and script-generated animations. Animations, - /// Author-supplied important rules. - AuthorImportant, + /// Author-supplied important rules from the same tree the element came + /// from. + SameTreeAuthorImportant, /// Style attribute important rules. StyleAttributeImportant, + /// Shadow DOM important rules. + InnerShadowImportant, /// User important rules. UserImportant, /// User-agent important rules. @@ -571,7 +630,8 @@ impl CascadeLevel { #[inline] pub fn is_important(&self) -> bool { match *self { - CascadeLevel::AuthorImportant | + CascadeLevel::SameTreeAuthorImportant | + CascadeLevel::InnerShadowImportant | CascadeLevel::StyleAttributeImportant | CascadeLevel::UserImportant | CascadeLevel::UAImportant => true, @@ -1302,11 +1362,13 @@ impl StrongRuleNode { }, // Author rules: CascadeLevel::PresHints | - CascadeLevel::AuthorNormal | + CascadeLevel::SameTreeAuthorNormal | + CascadeLevel::InnerShadowNormal | CascadeLevel::StyleAttributeNormal | CascadeLevel::SMILOverride | CascadeLevel::Animations | - CascadeLevel::AuthorImportant | + CascadeLevel::SameTreeAuthorImportant | + CascadeLevel::InnerShadowImportant | CascadeLevel::StyleAttributeImportant | CascadeLevel::Transitions => { for (id, declaration) in longhands { diff --git a/components/style/selector_map.rs b/components/style/selector_map.rs index 3db37a4b7f2..3b9b6f20184 100644 --- a/components/style/selector_map.rs +++ b/components/style/selector_map.rs @@ -14,7 +14,7 @@ use hash::{HashMap, HashSet}; use hash::map as hash_map; use hashglobe::FailedAllocationError; use precomputed_hash::PrecomputedHash; -use rule_tree::CascadeLevel; +use rule_tree::{CascadeLevel, ShadowCascadeOrder}; use selector_parser::SelectorImpl; use selectors::matching::{matches_selector, ElementSelectorFlags, MatchingContext}; use selectors::parser::{Combinator, Component, SelectorIter}; @@ -163,6 +163,7 @@ impl SelectorMap<Rule> { context: &mut MatchingContext<E::Impl>, flags_setter: &mut F, cascade_level: CascadeLevel, + shadow_cascade_order: ShadowCascadeOrder, ) where E: TElement, F: FnMut(&E, ElementSelectorFlags), @@ -185,6 +186,7 @@ impl SelectorMap<Rule> { context, flags_setter, cascade_level, + shadow_cascade_order, ) } } @@ -198,6 +200,7 @@ impl SelectorMap<Rule> { context, flags_setter, cascade_level, + shadow_cascade_order, ) } }); @@ -210,6 +213,7 @@ impl SelectorMap<Rule> { context, flags_setter, cascade_level, + shadow_cascade_order, ) } @@ -220,6 +224,7 @@ impl SelectorMap<Rule> { context, flags_setter, cascade_level, + shadow_cascade_order, ); // Sort only the rules we just added. @@ -235,6 +240,7 @@ impl SelectorMap<Rule> { context: &mut MatchingContext<E::Impl>, flags_setter: &mut F, cascade_level: CascadeLevel, + shadow_cascade_order: ShadowCascadeOrder, ) where E: TElement, F: FnMut(&E, ElementSelectorFlags), @@ -248,7 +254,7 @@ impl SelectorMap<Rule> { context, flags_setter, ) { - matching_rules.push(rule.to_applicable_declaration_block(cascade_level)); + matching_rules.push(rule.to_applicable_declaration_block(cascade_level, shadow_cascade_order)); } } } @@ -448,13 +454,7 @@ fn specific_bucket_for<'a>(component: &'a Component<SelectorImpl>) -> Bucket<'a> // // So inserting `span` in the rule hash makes sense since we want to // match the slotted <span>. - // - // FIXME(emilio, bug 1426516): The line below causes valgrind failures - // and it's probably a false positive, we should uncomment whenever - // jseward is back to confirm / whitelist it. - // - // Meanwhile taking the code path below is slower, but still correct. - // Component::Slotted(ref selector) => find_bucket(selector.iter()), + Component::Slotted(ref selector) => find_bucket(selector.iter()), Component::Host(Some(ref selector)) => find_bucket(selector.iter()), _ => Bucket::Universal, } diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index b7270976ead..4fcbffc5345 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -359,12 +359,10 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { #[cfg(feature = "gecko")] fn adjust_for_mathvariant(&mut self) { use properties::longhands::_moz_math_variant::computed_value::T as MozMathVariant; - use properties::longhands::font_style::computed_value::T as FontStyle; use properties::longhands::font_weight::computed_value::T as FontWeight; + use values::generics::font::FontStyle; if self.style.get_font().clone__moz_math_variant() != MozMathVariant::None { let font_style = self.style.mutate_font(); - // Sadly we don't have a nice name for the computed value - // of "font-weight: normal". font_style.set_font_weight(FontWeight::normal()); font_style.set_font_style(FontStyle::Normal); } @@ -673,17 +671,15 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } - /// Resolves "justify-items: auto" based on the inherited style if needed to - /// comply with: + /// Resolves "justify-items: legacy" based on the inherited style if needed + /// to comply with: /// /// <https://drafts.csswg.org/css-align/#valdef-justify-items-legacy> - /// - /// (Note that "auto" is being renamed to "legacy") #[cfg(feature = "gecko")] fn adjust_for_justify_items(&mut self) { use values::specified::align; let justify_items = self.style.get_position().clone_justify_items(); - if justify_items.specified.0 != align::AlignFlags::AUTO { + if justify_items.specified.0 != align::AlignFlags::LEGACY { return; } diff --git a/components/style/stylesheets/import_rule.rs b/components/style/stylesheets/import_rule.rs index fb50ec69732..576cb31eff3 100644 --- a/components/style/stylesheets/import_rule.rs +++ b/components/style/stylesheets/import_rule.rs @@ -171,10 +171,9 @@ pub struct ImportRule { /// The `<url>` this `@import` rule is loading. pub url: CssUrl, - /// The stylesheet is always present. - /// - /// It contains an empty list of rules and namespace set that is updated - /// when it loads. + /// The stylesheet is always present. However, in the case of gecko async + /// parsing, we don't actually have a Gecko sheet at first, and so the + /// ImportSheet just has stub behavior until it appears. pub stylesheet: ImportSheet, /// The line and column of the rule's source code. diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 931b667d38b..ccd668b0bed 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -23,7 +23,7 @@ use media_queries::Device; use properties::{self, CascadeFlags, ComputedValues}; use properties::{AnimationRules, PropertyDeclarationBlock}; use rule_cache::{RuleCache, RuleCacheConditions}; -use rule_tree::{CascadeLevel, RuleTree, StrongRuleNode, StyleSource}; +use rule_tree::{CascadeLevel, RuleTree, ShadowCascadeOrder, StrongRuleNode, StyleSource}; use selector_map::{PrecomputedHashMap, SelectorMap, SelectorMapEntry}; use selector_parser::{PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap}; use selectors::NthIndexCache; @@ -693,7 +693,7 @@ impl Stylist { match declarations { Some(decls) => self.rule_tree.insert_ordered_rules_with_important( - decls.into_iter().map(|a| (a.source.clone(), a.level())), + decls.into_iter().map(|a| a.clone().for_rule_tree()), guards, ), None => self.rule_tree.root().clone(), @@ -1020,7 +1020,7 @@ impl Stylist { ); if !declarations.is_empty() { let rule_node = self.rule_tree.insert_ordered_rules_with_important( - declarations.drain().map(|a| a.order_and_level()), + declarations.drain().map(|a| a.for_rule_tree()), guards, ); if rule_node != *self.rule_tree.root() { @@ -1187,6 +1187,7 @@ impl Stylist { context, flags_setter, CascadeLevel::UANormal, + 0, ); } @@ -1208,6 +1209,7 @@ impl Stylist { context, flags_setter, CascadeLevel::UserNormal, + 0, ); } } @@ -1232,6 +1234,7 @@ impl Stylist { } let mut match_document_author_rules = matches_author_rules; + let mut shadow_cascade_order = 0; // XBL / Shadow DOM rules, which are author rules too. // @@ -1249,9 +1252,11 @@ impl Stylist { applicable_declarations, context, flags_setter, - CascadeLevel::AuthorNormal, + CascadeLevel::InnerShadowNormal, + shadow_cascade_order, ); }); + shadow_cascade_order += 1; } } @@ -1275,9 +1280,11 @@ impl Stylist { applicable_declarations, context, flags_setter, - CascadeLevel::AuthorNormal, + CascadeLevel::InnerShadowNormal, + shadow_cascade_order, ); }); + shadow_cascade_order += 1; } } @@ -1291,9 +1298,11 @@ impl Stylist { applicable_declarations, context, flags_setter, - CascadeLevel::AuthorNormal, + CascadeLevel::SameTreeAuthorNormal, + shadow_cascade_order, ); }); + shadow_cascade_order += 1; } match_document_author_rules = false; @@ -1309,10 +1318,6 @@ impl Stylist { if let Some(map) = cascade_data.normal_rules(pseudo_element) { // NOTE(emilio): This is needed because the XBL stylist may // think it has a different quirks mode than the document. - // - // FIXME(emilio): this should use the same VisitedMatchingMode - // as `context`, write a test-case of :visited not working on - // Shadow DOM and fix it! let mut matching_context = MatchingContext::new( context.matching_mode(), context.bloom_filter, @@ -1322,13 +1327,16 @@ impl Stylist { matching_context.pseudo_element_matching_fn = context.pseudo_element_matching_fn; + // SameTreeAuthorNormal instead of InnerShadowNormal to + // preserve behavior, though that's kinda fishy... map.get_all_matching_rules( element, rule_hash_target, applicable_declarations, &mut matching_context, flags_setter, - CascadeLevel::AuthorNormal, + CascadeLevel::SameTreeAuthorNormal, + shadow_cascade_order, ); } }); @@ -1344,7 +1352,8 @@ impl Stylist { applicable_declarations, context, flags_setter, - CascadeLevel::AuthorNormal, + CascadeLevel::SameTreeAuthorNormal, + shadow_cascade_order, ); } } @@ -2172,6 +2181,7 @@ impl CascadeData { self.rules_source_order, CascadeLevel::UANormal, selector.specificity(), + 0, )); continue; } @@ -2468,9 +2478,10 @@ impl Rule { pub fn to_applicable_declaration_block( &self, level: CascadeLevel, + shadow_cascade_order: ShadowCascadeOrder, ) -> ApplicableDeclarationBlock { let source = StyleSource::Style(self.style_rule.clone()); - ApplicableDeclarationBlock::new(source, self.source_order, level, self.specificity()) + ApplicableDeclarationBlock::new(source, self.source_order, level, self.specificity(), shadow_cascade_order) } /// Creates a new Rule. diff --git a/components/style/values/computed/align.rs b/components/style/values/computed/align.rs index 940e3f747b8..1a26e41fd24 100644 --- a/components/style/values/computed/align.rs +++ b/components/style/values/computed/align.rs @@ -20,10 +20,10 @@ pub use super::specified::{AlignSelf, JustifySelf}; /// In particular, `justify-items` is a reset property, so we ought to be able /// to share its computed representation across elements as long as they match /// the same rules. Except that it's not true if the specified value for -/// `justify-items` is `auto` and the computed value of the parent has the +/// `justify-items` is `legacy` and the computed value of the parent has the /// `legacy` modifier. /// -/// So instead of computing `auto` "normally" looking at get_parent_position(), +/// So instead of computing `legacy` "normally" looking at get_parent_position(), /// marking it as uncacheable, we carry the specified value around and handle /// the special case in `StyleAdjuster` instead, only when the result of the /// computation would vary. @@ -35,18 +35,21 @@ pub use super::specified::{AlignSelf, JustifySelf}; /// See the discussion in https://bugzil.la/1384542. #[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss)] pub struct JustifyItems { - /// The specified value for the property. Can contain `auto`. + /// The specified value for the property. Can contain the bare `legacy` + /// keyword. #[css(skip)] pub specified: specified::JustifyItems, - /// The computed value for the property. Cannot contain `auto`. + /// The computed value for the property. Cannot contain the bare `legacy` + /// keyword, but note that it could contain it in combination with other + /// keywords like `left`, `right` or `center`. pub computed: specified::JustifyItems, } impl JustifyItems { - /// Returns the `auto` value. - pub fn auto() -> Self { + /// Returns the `legacy` value. + pub fn legacy() -> Self { Self { - specified: specified::JustifyItems::auto(), + specified: specified::JustifyItems::legacy(), computed: specified::JustifyItems::normal(), } } @@ -59,13 +62,13 @@ impl ToComputedValue for specified::JustifyItems { fn to_computed_value(&self, _context: &Context) -> JustifyItems { use values::specified::align; let specified = *self; - let computed = if self.0 != align::AlignFlags::AUTO { + let computed = if self.0 != align::AlignFlags::LEGACY { *self } else { // If the inherited value of `justify-items` includes the - // `legacy` keyword, `auto` computes to the inherited value, - // but we assume it computes to `normal`, and handle that - // special-case in StyleAdjuster. + // `legacy` keyword, `legacy` computes to the inherited value, but + // we assume it computes to `normal`, and handle that special-case + // in StyleAdjuster. Self::normal() }; diff --git a/components/style/values/computed/angle.rs b/components/style/values/computed/angle.rs index ec269df9796..67ea5d1231b 100644 --- a/components/style/values/computed/angle.rs +++ b/components/style/values/computed/angle.rs @@ -64,6 +64,12 @@ impl Angle { radians.min(f64::MAX).max(f64::MIN) } + /// Return the value in degrees. + pub fn degrees(&self) -> f32 { + use std::f32::consts::PI; + self.radians() * 360. / (2. * PI) + } + /// <https://drafts.csswg.org/css-transitions/#animtype-number> #[inline] fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index c270969a52f..1ca8400c16a 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -22,23 +22,38 @@ use std::slice; use style_traits::{CssWriter, ParseError, ToCss}; use values::CSSFloat; use values::animated::{ToAnimatedValue, ToAnimatedZero}; -use values::computed::{Context, Integer, NonNegativeLength, Number, ToComputedValue}; -use values::generics::font::{FeatureTagValue, FontSettings}; -use values::generics::font::{KeywordInfo as GenericKeywordInfo, VariationValue}; -use values::specified::font as specified; +use values::computed::{Angle, Context, Integer, NonNegativeLength, Number, ToComputedValue}; +use values::generics::font::{self as generics, FeatureTagValue, FontSettings, VariationValue}; +use values::specified::font::{self as specified, MIN_FONT_WEIGHT, MAX_FONT_WEIGHT}; use values::specified::length::{FontBaseSize, NoCalcLength}; pub use values::computed::Length as MozScriptMinSize; pub use values::specified::font::{FontSynthesis, MozScriptSizeMultiplier, XLang, XTextZoom}; +pub use values::computed::NonNegativePercentage as FontStretch; -/// As of CSS Fonts Module Level 3, only the following values are -/// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 +/// A value for the font-weight property per: /// -/// However, system fonts may provide other values. Pango -/// may provide 350, 380, and 1000 (on top of the existing values), for example. -#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)] +/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight +/// +/// This is effectively just a `Number`. +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, + ToCss)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] -pub struct FontWeight(pub u16); +pub struct FontWeight(pub Number); + +impl ToAnimatedValue for FontWeight { + type AnimatedValue = Number; + + #[inline] + fn to_animated_value(self) -> Self::AnimatedValue { + self.0 + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + FontWeight(animated.max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT)) + } +} #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss)] @@ -52,26 +67,17 @@ pub struct FontSize { } /// Additional information for computed keyword-derived font sizes. -pub type KeywordInfo = GenericKeywordInfo<NonNegativeLength>; +pub type KeywordInfo = generics::KeywordInfo<NonNegativeLength>; impl FontWeight { /// Value for normal pub fn normal() -> Self { - FontWeight(400) + FontWeight(400.) } /// Value for bold pub fn bold() -> Self { - FontWeight(700) - } - - /// Convert from an integer to Weight - pub fn from_int(n: i32) -> Result<Self, ()> { - if n >= 100 && n <= 900 && n % 100 == 0 { - Ok(FontWeight(n as u16)) - } else { - Err(()) - } + FontWeight(700.) } /// Convert from an Gecko weight @@ -80,33 +86,39 @@ impl FontWeight { // we allow a wider range of weights than is parseable // because system fonts may provide custom values let weight = unsafe { bindings::Gecko_FontWeight_ToFloat(weight) }; - FontWeight(weight as u16) + FontWeight(weight) } /// Weither this weight is bold pub fn is_bold(&self) -> bool { - self.0 > 500 + self.0 > 500. } - /// Return the bolder weight + /// Return the bolder weight. + /// + /// See the table in: + /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values pub fn bolder(self) -> Self { - if self.0 < 400 { - FontWeight(400) - } else if self.0 < 600 { - FontWeight(700) + if self.0 < 350. { + FontWeight(400.) + } else if self.0 < 550. { + FontWeight(700.) } else { - FontWeight(900) + FontWeight(self.0.max(900.)) } } - /// Returns the lighter weight + /// Return the lighter weight. + /// + /// See the table in: + /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values pub fn lighter(self) -> Self { - if self.0 < 600 { - FontWeight(100) - } else if self.0 < 800 { - FontWeight(400) + if self.0 < 550. { + FontWeight(self.0.min(100.)) + } else if self.0 < 750. { + FontWeight(400.) } else { - FontWeight(700) + FontWeight(700.) } } } @@ -816,3 +828,91 @@ impl ToComputedValue for specified::MozScriptLevel { specified::MozScriptLevel::MozAbsolute(*other as i32) } } + +/// A wrapper over an `Angle`, that handles clamping to the appropriate range +/// for `font-style` animation. +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +pub struct FontStyleAngle(pub Angle); + +impl ToAnimatedValue for FontStyleAngle { + type AnimatedValue = Angle; + + #[inline] + fn to_animated_value(self) -> Self::AnimatedValue { + self.0 + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + FontStyleAngle(Angle::Deg( + animated.degrees() + .min(specified::FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES) + .max(specified::FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES) + )) + } +} + +/// The computed value of `font-style`. +/// +/// FIXME(emilio): Angle should be a custom type to handle clamping during +/// animation. +pub type FontStyle = generics::FontStyle<FontStyleAngle>; + +impl FontStyle { + /// The `normal` value. + #[inline] + pub fn normal() -> Self { + generics::FontStyle::Normal + } + + /// The default angle for font-style: oblique. This is 20deg per spec: + /// + /// https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle + #[inline] + pub fn default_angle() -> FontStyleAngle { + FontStyleAngle(Angle::Deg(specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES)) + } + + + /// Get the font style from Gecko's nsFont struct. + #[cfg(feature = "gecko")] + pub fn from_gecko(style: structs::FontSlantStyle) -> Self { + let mut angle = 0.; + let mut italic = false; + let mut normal = false; + unsafe { + bindings::Gecko_FontSlantStyle_Get(style, &mut normal, &mut italic, &mut angle); + } + if normal { + return generics::FontStyle::Normal; + } + if italic { + return generics::FontStyle::Italic; + } + generics::FontStyle::Oblique(FontStyleAngle(Angle::Deg(angle))) + } +} + +impl ToCss for FontStyle { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: fmt::Write, + { + match *self { + generics::FontStyle::Normal => dest.write_str("normal"), + generics::FontStyle::Italic => dest.write_str("italic"), + generics::FontStyle::Oblique(ref angle) => { + dest.write_str("oblique")?; + // Use `degrees` instead of just comparing Angle because + // `degrees` can return slightly different values due to + // floating point conversions. + if angle.0.degrees() != Self::default_angle().0.degrees() { + dest.write_char(' ')?; + angle.to_css(dest)?; + } + Ok(()) + } + } + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 67529efb06f..4adf33253e8 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -39,8 +39,8 @@ pub use self::angle::Angle; pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::border::{BorderImageRepeat, BorderImageSideWidth, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderCornerRadius, BorderRadius, BorderSpacing}; -pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontVariantAlternates, FontWeight}; -pub use self::font::{FontFamily, FontLanguageOverride, FontVariantEastAsian, FontVariationSettings}; +pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight}; +pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings}; pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; @@ -66,7 +66,7 @@ pub use self::list::Quotes; #[cfg(feature = "gecko")] pub use self::list::ListStyleType; pub use self::outline::OutlineStyle; -pub use self::percentage::Percentage; +pub use self::percentage::{Percentage, NonNegativePercentage}; pub use self::pointing::{CaretColor, Cursor}; #[cfg(feature = "gecko")] pub use self::pointing::CursorImage; diff --git a/components/style/values/computed/percentage.rs b/components/style/values/computed/percentage.rs index ee881a22019..7ca504d2aff 100644 --- a/components/style/values/computed/percentage.rs +++ b/components/style/values/computed/percentage.rs @@ -7,6 +7,8 @@ use std::fmt; use style_traits::{CssWriter, ToCss}; use values::{serialize_percentage, CSSFloat}; +use values::animated::ToAnimatedValue; +use values::generics::NonNegative; /// A computed percentage. #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] @@ -48,3 +50,34 @@ impl ToCss for Percentage { serialize_percentage(self.0, dest) } } + +/// A wrapper over a `Percentage`, whose value should be clamped to 0. +pub type NonNegativePercentage = NonNegative<Percentage>; + +impl NonNegativePercentage { + /// 0% + #[inline] + pub fn zero() -> Self { + NonNegative(Percentage::zero()) + } + + /// 100% + #[inline] + pub fn hundred() -> Self { + NonNegative(Percentage::hundred()) + } +} + +impl ToAnimatedValue for NonNegativePercentage { + type AnimatedValue = Percentage; + + #[inline] + fn to_animated_value(self) -> Self::AnimatedValue { + self.0 + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + NonNegative(animated.clamp_to_non_negative()) + } +} diff --git a/components/style/values/generics/font.rs b/components/style/values/generics/font.rs index d951756f43b..cbcd64502c4 100644 --- a/components/style/values/generics/font.rs +++ b/components/style/values/generics/font.rs @@ -231,3 +231,18 @@ impl ToCss for KeywordSize { }) } } + +/// A generic value for the `font-style` property. +/// +/// https://drafts.csswg.org/css-fonts-4/#font-style-prop +#[allow(missing_docs)] +#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, + PartialEq, ToAnimatedValue, ToAnimatedZero)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +pub enum FontStyle<Angle> { + #[animation(error)] + Normal, + #[animation(error)] + Italic, + Oblique(Angle), +} diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs index 918c4ddf8ed..7b9b003a50c 100644 --- a/components/style/values/specified/align.rs +++ b/components/style/values/specified/align.rs @@ -9,9 +9,8 @@ use cssparser::Parser; use gecko_bindings::structs; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Write}; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; +use style_traits::{CssWriter, ParseError, ToCss}; bitflags! { /// Constants shared by multiple CSS Box Alignment properties @@ -81,14 +80,26 @@ impl ToCss for AlignFlags { where W: Write, { - match *self & AlignFlags::FLAG_BITS { - AlignFlags::LEGACY => dest.write_str("legacy ")?, + let extra_flags = *self & AlignFlags::FLAG_BITS; + let value = self.value(); + + match extra_flags { + AlignFlags::LEGACY => { + dest.write_str("legacy")?; + if value.is_empty() { + return Ok(()); + } + dest.write_char(' ')?; + }, AlignFlags::SAFE => dest.write_str("safe ")?, // Don't serialize "unsafe", since it's the default. - _ => {}, + AlignFlags::UNSAFE => {}, + _ => { + debug_assert_eq!(extra_flags, AlignFlags::empty()); + }, } - dest.write_str(match self.value() { + dest.write_str(match value { AlignFlags::AUTO => "auto", AlignFlags::NORMAL => "normal", AlignFlags::START => "start", @@ -436,10 +447,10 @@ impl Parse for AlignItems { pub struct JustifyItems(pub AlignFlags); impl JustifyItems { - /// The initial value 'auto' + /// The initial value 'legacy' #[inline] - pub fn auto() -> Self { - JustifyItems(AlignFlags::AUTO) + pub fn legacy() -> Self { + JustifyItems(AlignFlags::LEGACY) } /// The value 'normal' @@ -462,24 +473,12 @@ impl Parse for JustifyItems { return Ok(JustifyItems(baseline)); } - // auto | normal | stretch - // - // FIXME(emilio): auto is no longer a keyword in the current spec, and - // has been renamed to legacy, but that needs different changes because - // right now it's the initial value for both style systems, and has that - // weird behavior of "inheriting" into descendants. - // - // Fix this in both. - // - // See also: - // https://bugs.webkit.org/show_bug.cgi?id=172711 - // https://bugs.chromium.org/p/chromium/issues/detail?id=726148 - // - if let Ok(value) = input.try(parse_auto_normal_stretch) { + // normal | stretch + if let Ok(value) = input.try(parse_normal_stretch) { return Ok(JustifyItems(value)); } - // [ legacy || [ left | right | center ] ] + // legacy | [ legacy && [ left | right | center ] ] if let Ok(value) = input.try(parse_legacy) { return Ok(JustifyItems(value)); } @@ -567,29 +566,30 @@ fn parse_self_position<'i, 't>( }) } -// [ legacy && [ left | right | center ] ] +fn parse_left_right_center<'i, 't>( + input: &mut Parser<'i, 't>, +) -> Result<AlignFlags, ParseError<'i>> { + Ok(try_match_ident_ignore_ascii_case! { input, + "left" => AlignFlags::LEFT, + "right" => AlignFlags::RIGHT, + "center" => AlignFlags::CENTER, + }) +} + +// legacy | [ legacy && [ left | right | center ] ] fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> { - let a_location = input.current_source_location(); - let a = input.expect_ident()?.clone(); - let b_location = input.current_source_location(); - let b = input.expect_ident()?; - if a.eq_ignore_ascii_case("legacy") { - (match_ignore_ascii_case! { &b, - "left" => Ok(AlignFlags::LEGACY | AlignFlags::LEFT), - "right" => Ok(AlignFlags::LEGACY | AlignFlags::RIGHT), - "center" => Ok(AlignFlags::LEGACY | AlignFlags::CENTER), - _ => Err(()) - }).map_err(|()| { - b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone())) - }) - } else if b.eq_ignore_ascii_case("legacy") { - (match_ignore_ascii_case! { &a, - "left" => Ok(AlignFlags::LEGACY | AlignFlags::LEFT), - "right" => Ok(AlignFlags::LEGACY | AlignFlags::RIGHT), - "center" => Ok(AlignFlags::LEGACY | AlignFlags::CENTER), - _ => Err(()) - }).map_err(|()| a_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(a))) - } else { - Err(a_location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } + let flags = try_match_ident_ignore_ascii_case! { input, + "legacy" => { + let flags = input.try(parse_left_right_center) + .unwrap_or(AlignFlags::empty()); + + return Ok(AlignFlags::LEGACY | flags) + } + "left" => AlignFlags::LEFT, + "right" => AlignFlags::RIGHT, + "center" => AlignFlags::CENTER, + }; + + input.expect_ident_matching("legacy")?; + Ok(AlignFlags::LEGACY | flags) } diff --git a/components/style/values/specified/angle.rs b/components/style/values/specified/angle.rs index 90b990bf8ce..3f49862e406 100644 --- a/components/style/values/specified/angle.rs +++ b/components/style/values/specified/angle.rs @@ -41,13 +41,19 @@ impl ToCss for Angle { } } +// FIXME(emilio): Probably computed angles shouldn't preserve the unit and +// should serialize to degrees per: +// +// https://drafts.csswg.org/css-values/#compat impl ToComputedValue for Angle { type ComputedValue = ComputedAngle; + #[inline] fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue { self.value } + #[inline] fn from_computed_value(computed: &Self::ComputedValue) -> Self { Angle { value: *computed, @@ -89,6 +95,12 @@ impl Angle { } } + /// Whether this specified angle came from a `calc()` expression. + #[inline] + pub fn was_calc(&self) -> bool { + self.was_calc + } + /// Returns the amount of radians this angle represents. #[inline] pub fn radians(self) -> f32 { @@ -98,8 +110,7 @@ impl Angle { /// Returns the amount of degrees this angle represents. #[inline] pub fn degrees(self) -> f32 { - use std::f32::consts::PI; - self.radians() * 360. / (2. * PI) + self.value.degrees() } /// Returns `0deg`. diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index a386a329ac8..fa4d972ef16 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -17,79 +17,108 @@ use properties::longhands::system_font::SystemFont; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use values::CustomIdent; +use values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage}; use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue}; -use values::computed::font::{FamilyName, FontFamilyList, SingleFontFamily}; -use values::generics::font::{FeatureTagValue, FontSettings, FontTag}; -use values::generics::font::{KeywordInfo as GenericKeywordInfo, KeywordSize, VariationValue}; -use values::specified::{AllowQuirks, Integer, LengthOrPercentage, NoCalcLength, Number}; +use values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily}; +use values::generics::NonNegative; +use values::generics::font::{KeywordSize, VariationValue}; +use values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag}; +use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage}; use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX}; +// FIXME(emilio): The system font code is copy-pasta, and should be cleaned up. +macro_rules! system_font_methods { + ($ty:ident, $field:ident) => { + system_font_methods!($ty); + + fn compute_system(&self, _context: &Context) -> <$ty as ToComputedValue>::ComputedValue { + debug_assert!(matches!(*self, $ty::System(..))); + #[cfg(feature = "gecko")] + { + _context.cached_system_font.as_ref().unwrap().$field.clone() + } + #[cfg(feature = "servo")] + { + unreachable!() + } + } + }; + + ($ty:ident) => { + /// Get a specified value that represents a system font. + pub fn system_font(f: SystemFont) -> Self { + $ty::System(f) + } + + /// Retreive a SystemFont from the specified value. + pub fn get_system(&self) -> Option<SystemFont> { + if let $ty::System(s) = *self { + Some(s) + } else { + None + } + } + } +} + const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8; const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71; -#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] -/// A specified font-weight value +/// The minimum font-weight value per: +/// +/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values +pub const MIN_FONT_WEIGHT: f32 = 1.; + +/// The maximum font-weight value per: +/// +/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values +pub const MAX_FONT_WEIGHT: f32 = 1000.; + +/// A specified font-weight value. +/// +/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum FontWeight { - /// Normal variant - Normal, - /// Bold variant - Bold, + /// `<font-weight-absolute>` + Absolute(AbsoluteFontWeight), /// Bolder variant Bolder, /// Lighter variant Lighter, - /// Computed weight variant - Weight(computed::FontWeight), - /// System font varaint + /// System font variant. System(SystemFont), } impl FontWeight { - /// Get a specified FontWeight from a gecko keyword - pub fn from_gecko_keyword(kw: u32) -> Self { - computed::FontWeight::from_int(kw as i32) - .map(FontWeight::Weight) - .expect("Found unexpected value in style struct for font-weight property") - } + system_font_methods!(FontWeight, font_weight); - /// Get a specified FontWeight from a SystemFont - pub fn system_font(f: SystemFont) -> Self { - FontWeight::System(f) + /// `normal` + #[inline] + pub fn normal() -> Self { + FontWeight::Absolute(AbsoluteFontWeight::Normal) } - /// Retreive a SystemFont from FontWeight - pub fn get_system(&self) -> Option<SystemFont> { - if let FontWeight::System(s) = *self { - Some(s) - } else { - None - } + /// Get a specified FontWeight from a gecko keyword + pub fn from_gecko_keyword(kw: u32) -> Self { + debug_assert!(kw % 100 == 0); + debug_assert!(kw as f32 <= MAX_FONT_WEIGHT); + FontWeight::Absolute(AbsoluteFontWeight::Weight(Number::new(kw as f32))) } } impl Parse for FontWeight { fn parse<'i, 't>( - _: &ParserContext, + context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<FontWeight, ParseError<'i>> { - let result = match *input.next()? { - Token::Ident(ref ident) => { - match_ignore_ascii_case! { ident, - "normal" => Ok(FontWeight::Normal), - "bold" => Ok(FontWeight::Bold), - "bolder" => Ok(FontWeight::Bolder), - "lighter" => Ok(FontWeight::Lighter), - _ => Err(()), - } - }, - Token::Number { - int_value: Some(value), - .. - } => computed::FontWeight::from_int(value).map(FontWeight::Weight), - _ => Err(()), - }; + if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) { + return Ok(FontWeight::Absolute(absolute)); + } - result.map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + Ok(try_match_ident_ignore_ascii_case! { input, + "bolder" => FontWeight::Bolder, + "lighter" => FontWeight::Lighter, + }) } } @@ -99,9 +128,7 @@ impl ToComputedValue for FontWeight { #[inline] fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { - FontWeight::Weight(weight) => weight, - FontWeight::Normal => computed::FontWeight::normal(), - FontWeight::Bold => computed::FontWeight::bold(), + FontWeight::Absolute(ref abs) => abs.compute(), FontWeight::Bolder => context .builder .get_parent_font() @@ -112,21 +139,365 @@ impl ToComputedValue for FontWeight { .get_parent_font() .clone_font_weight() .lighter(), - #[cfg(feature = "gecko")] - FontWeight::System(_) => context - .cached_system_font - .as_ref() - .unwrap() - .font_weight - .clone(), - #[cfg(not(feature = "gecko"))] - FontWeight::System(_) => unreachable!(), + FontWeight::System(_) => self.compute_system(context), } } #[inline] fn from_computed_value(computed: &computed::FontWeight) -> Self { - FontWeight::Weight(*computed) + FontWeight::Absolute(AbsoluteFontWeight::Weight( + Number::from_computed_value(&computed.0) + )) + } +} + +/// An absolute font-weight value for a @font-face rule. +/// +/// https://drafts.csswg.org/css-fonts-4/#font-weight-absolute-values +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] +pub enum AbsoluteFontWeight { + /// A `<number>`, with the additional constraints specified in: + /// + /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values + Weight(Number), + /// Normal font weight. Same as 400. + Normal, + /// Bold font weight. Same as 700. + Bold, +} + +impl AbsoluteFontWeight { + /// Returns the computed value for this absolute font weight. + pub fn compute(&self) -> computed::FontWeight { + match *self { + AbsoluteFontWeight::Weight(weight) => { + computed::FontWeight( + weight.get().max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT) + ) + }, + AbsoluteFontWeight::Normal => computed::FontWeight::normal(), + AbsoluteFontWeight::Bold => computed::FontWeight::bold(), + } + } +} + +impl Parse for AbsoluteFontWeight { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + if let Ok(number) = input.try(|input| Number::parse(context, input)) { + // We could add another AllowedNumericType value, but it doesn't + // seem worth it just for a single property with such a weird range, + // so we do the clamping here manually. + if !number.was_calc() && + (number.get() < MIN_FONT_WEIGHT || number.get() > MAX_FONT_WEIGHT) { + return Err(input.new_custom_error( + StyleParseErrorKind::UnspecifiedError + )) + } + return Ok(AbsoluteFontWeight::Weight(number)) + } + + Ok(try_match_ident_ignore_ascii_case! { input, + "normal" => AbsoluteFontWeight::Normal, + "bold" => AbsoluteFontWeight::Bold, + }) + } +} + +/// The specified value of the `font-style` property, without the system font +/// crap. +pub type SpecifiedFontStyle = generics::FontStyle<Angle>; + +impl ToCss for SpecifiedFontStyle { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: Write, + { + match *self { + generics::FontStyle::Normal => dest.write_str("normal"), + generics::FontStyle::Italic => dest.write_str("italic"), + generics::FontStyle::Oblique(ref angle) => { + dest.write_str("oblique")?; + if *angle != Self::default_angle() { + dest.write_char(' ')?; + angle.to_css(dest)?; + } + Ok(()) + } + } + } +} + +impl Parse for SpecifiedFontStyle { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + Ok(try_match_ident_ignore_ascii_case! { input, + "normal" => generics::FontStyle::Normal, + "italic" => generics::FontStyle::Italic, + "oblique" => { + let angle = input.try(|input| Self::parse_angle(context, input)) + .unwrap_or_else(|_| Self::default_angle()); + + generics::FontStyle::Oblique(angle) + } + }) + } +} + +impl ToComputedValue for SpecifiedFontStyle { + type ComputedValue = computed::FontStyle; + + fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { + match *self { + generics::FontStyle::Normal => generics::FontStyle::Normal, + generics::FontStyle::Italic => generics::FontStyle::Italic, + generics::FontStyle::Oblique(ref angle) => { + generics::FontStyle::Oblique(FontStyleAngle(Self::compute_angle(angle))) + } + } + } + + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + match *computed { + generics::FontStyle::Normal => generics::FontStyle::Normal, + generics::FontStyle::Italic => generics::FontStyle::Italic, + generics::FontStyle::Oblique(ref angle) => { + generics::FontStyle::Oblique(Angle::from_computed_value(&angle.0)) + } + } + } +} + + +/// The default angle for `font-style: oblique`. +/// +/// NOTE(emilio): As of right now this diverges from the spec, which specifies +/// 20, because it's not updated yet to account for the resolution in: +/// +/// https://github.com/w3c/csswg-drafts/issues/2295 +pub const DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES: f32 = 14.; + +/// From https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle: +/// +/// Values less than -90deg or values greater than 90deg are +/// invalid and are treated as parse errors. +/// +/// The maximum angle value that `font-style: oblique` should compute to. +pub const FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES: f32 = 90.; + +/// The minimum angle value that `font-style: oblique` should compute to. +pub const FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES: f32 = -90.; + +impl SpecifiedFontStyle { + /// Gets a clamped angle from a specified Angle. + pub fn compute_angle(angle: &Angle) -> ComputedAngle { + ComputedAngle::Deg( + angle.degrees() + .max(FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES) + .min(FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES) + ) + } + + /// Parse a suitable angle for font-style: oblique. + pub fn parse_angle<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Angle, ParseError<'i>> { + let angle = Angle::parse(context, input)?; + if angle.was_calc() { + return Ok(angle); + } + + let degrees = angle.degrees(); + if degrees < FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES || + degrees > FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES + { + return Err(input.new_custom_error( + StyleParseErrorKind::UnspecifiedError + )); + } + return Ok(angle) + } + + /// The default angle for `font-style: oblique`. + pub fn default_angle() -> Angle { + Angle::from_degrees( + DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES, + /* was_calc = */ false, + ) + } +} + +/// The specified value of the `font-style` property. +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] +#[allow(missing_docs)] +pub enum FontStyle { + Specified(SpecifiedFontStyle), + System(SystemFont), +} + +impl FontStyle { + /// Return the `normal` value. + #[inline] + pub fn normal() -> Self { + FontStyle::Specified(generics::FontStyle::Normal) + } + + system_font_methods!(FontStyle, font_style); +} + +impl ToComputedValue for FontStyle { + type ComputedValue = computed::FontStyle; + + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + match *self { + FontStyle::Specified(ref specified) => specified.to_computed_value(context), + FontStyle::System(..) => self.compute_system(context), + } + } + + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + FontStyle::Specified(SpecifiedFontStyle::from_computed_value(computed)) + } +} + +impl Parse for FontStyle { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + Ok(FontStyle::Specified(SpecifiedFontStyle::parse(context, input)?)) + } +} + +/// A value for the `font-stretch` property. +/// +/// https://drafts.csswg.org/css-fonts-4/#font-stretch-prop +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] +pub enum FontStretch { + Stretch(Percentage), + Keyword(FontStretchKeyword), + System(SystemFont), +} + +/// A keyword value for `font-stretch`. +#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, ToCss)] +#[allow(missing_docs)] +pub enum FontStretchKeyword { + Normal, + Condensed, + UltraCondensed, + ExtraCondensed, + SemiCondensed, + SemiExpanded, + Expanded, + ExtraExpanded, + UltraExpanded, +} + +impl FontStretchKeyword { + /// Resolves the value of the keyword as specified in: + /// + /// https://drafts.csswg.org/css-fonts-4/#font-stretch-prop + pub fn compute(&self) -> ComputedPercentage { + use self::FontStretchKeyword::*; + ComputedPercentage(match *self { + UltraCondensed => 0.5, + ExtraCondensed => 0.625, + Condensed => 0.75, + SemiCondensed => 0.875, + Normal => 1., + SemiExpanded => 1.125, + Expanded => 1.25, + ExtraExpanded => 1.5, + UltraExpanded => 2., + }) + } + + /// Does the opposite operation to `compute`, in order to serialize keywords + /// if possible. + pub fn from_percentage(percentage: f32) -> Option<Self> { + use self::FontStretchKeyword::*; + // NOTE(emilio): Can't use `match` because of rust-lang/rust#41620. + if percentage == 0.5 { + return Some(UltraCondensed); + } + if percentage == 0.625 { + return Some(ExtraCondensed); + } + if percentage == 0.75 { + return Some(Condensed); + } + if percentage == 0.875 { + return Some(SemiCondensed); + } + if percentage == 1. { + return Some(Normal); + } + if percentage == 1.125 { + return Some(SemiExpanded); + } + if percentage == 1.25 { + return Some(Expanded); + } + if percentage == 1.5 { + return Some(ExtraExpanded); + } + if percentage == 2. { + return Some(UltraExpanded); + } + None + } +} + +impl FontStretch { + /// `normal`. + pub fn normal() -> Self { + FontStretch::Keyword(FontStretchKeyword::Normal) + } + + system_font_methods!(FontStretch, font_stretch); +} + +impl Parse for FontStretch { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + // From https://drafts.csswg.org/css-fonts-4/#font-stretch-prop: + // + // Values less than 0% are not allowed and are treated as parse + // errors. + if let Ok(percentage) = input.try(|input| Percentage::parse_non_negative(context, input)) { + return Ok(FontStretch::Stretch(percentage)); + } + + Ok(FontStretch::Keyword(FontStretchKeyword::parse(input)?)) + } +} + +impl ToComputedValue for FontStretch { + type ComputedValue = NonNegative<ComputedPercentage>; + + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + match *self { + FontStretch::Stretch(ref percentage) => { + NonNegative(percentage.to_computed_value(context)) + }, + FontStretch::Keyword(ref kw) => { + NonNegative(kw.compute()) + }, + FontStretch::System(_) => self.compute_system(context), + } + } + + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + FontStretch::Stretch(Percentage::from_computed_value(&computed.0)) } } @@ -171,19 +542,7 @@ pub enum FontFamily { } impl FontFamily { - /// Get `font-family` with system font - pub fn system_font(f: SystemFont) -> Self { - FontFamily::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontFamily::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontFamily, font_family); /// Parse a specified font-family value pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { @@ -205,19 +564,10 @@ impl FontFamily { impl ToComputedValue for FontFamily { type ComputedValue = computed::FontFamily; - fn to_computed_value(&self, _cx: &Context) -> Self::ComputedValue { + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { FontFamily::Values(ref v) => computed::FontFamily(v.clone()), - FontFamily::System(_) => { - #[cfg(feature = "gecko")] - { - _cx.cached_system_font.as_ref().unwrap().font_family.clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontFamily::System(_) => self.compute_system(context), } } @@ -287,19 +637,7 @@ impl FontSizeAdjust { FontSizeAdjust::None } - /// Get font-size-adjust with SystemFont - pub fn system_font(f: SystemFont) -> Self { - FontSizeAdjust::System(f) - } - - /// Get SystemFont variant - pub fn get_system(&self) -> Option<SystemFont> { - if let FontSizeAdjust::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontSizeAdjust, font_size_adjust); } impl ToComputedValue for FontSizeAdjust { @@ -311,20 +649,7 @@ impl ToComputedValue for FontSizeAdjust { FontSizeAdjust::Number(ref n) => { computed::FontSizeAdjust::Number(n.to_computed_value(context)) }, - FontSizeAdjust::System(_) => { - #[cfg(feature = "gecko")] - { - context - .cached_system_font - .as_ref() - .unwrap() - .font_size_adjust - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontSizeAdjust::System(_) => self.compute_system(context), } } @@ -359,7 +684,7 @@ impl Parse for FontSizeAdjust { } /// Additional information for specified keyword-derived font sizes. -pub type KeywordInfo = GenericKeywordInfo<NonNegativeLength>; +pub type KeywordInfo = generics::KeywordInfo<NonNegativeLength>; impl KeywordInfo { /// Computes the final size for this font-size keyword, accounting for @@ -648,22 +973,10 @@ impl ToComputedValue for FontSize { } impl FontSize { - /// Construct a system font value. - pub fn system_font(f: SystemFont) -> Self { - FontSize::System(f) - } + system_font_methods!(FontSize); - /// Obtain the system font, if any - pub fn get_system(&self) -> Option<SystemFont> { - if let FontSize::System(s) = *self { - Some(s) - } else { - None - } - } - - #[inline] /// Get initial value for specified font size. + #[inline] pub fn medium() -> Self { FontSize::Keyword(KeywordInfo::medium()) } @@ -828,42 +1141,16 @@ impl FontVariantAlternates { FontVariantAlternates::Value(VariantAlternatesList(vec![].into_boxed_slice())) } - /// Get FontVariantAlternates with system font - pub fn system_font(f: SystemFont) -> Self { - FontVariantAlternates::System(f) - } - - /// Get SystemFont of FontVariantAlternates - pub fn get_system(&self) -> Option<SystemFont> { - if let FontVariantAlternates::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontVariantAlternates, font_variant_alternates); } impl ToComputedValue for FontVariantAlternates { type ComputedValue = computed::FontVariantAlternates; - fn to_computed_value(&self, _context: &Context) -> computed::FontVariantAlternates { + fn to_computed_value(&self, context: &Context) -> computed::FontVariantAlternates { match *self { FontVariantAlternates::Value(ref v) => v.clone(), - FontVariantAlternates::System(_) => { - #[cfg(feature = "gecko")] - { - _context - .cached_system_font - .as_ref() - .unwrap() - .font_variant_alternates - .clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontVariantAlternates::System(_) => self.compute_system(context), } } @@ -1105,42 +1392,16 @@ impl FontVariantEastAsian { FontVariantEastAsian::Value(VariantEastAsian::empty()) } - /// Get `font-variant-east-asian` with system font - pub fn system_font(f: SystemFont) -> Self { - FontVariantEastAsian::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontVariantEastAsian::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontVariantEastAsian, font_variant_east_asian); } impl ToComputedValue for FontVariantEastAsian { type ComputedValue = computed::FontVariantEastAsian; - fn to_computed_value(&self, _context: &Context) -> computed::FontVariantEastAsian { + fn to_computed_value(&self, context: &Context) -> computed::FontVariantEastAsian { match *self { FontVariantEastAsian::Value(ref v) => v.clone(), - FontVariantEastAsian::System(_) => { - #[cfg(feature = "gecko")] - { - _context - .cached_system_font - .as_ref() - .unwrap() - .font_variant_east_asian - .clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontVariantEastAsian::System(_) => self.compute_system(context), } } @@ -1351,22 +1612,10 @@ pub enum FontVariantLigatures { } impl FontVariantLigatures { - /// Get `font-variant-ligatures` with system font - pub fn system_font(f: SystemFont) -> Self { - FontVariantLigatures::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontVariantLigatures::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontVariantLigatures, font_variant_ligatures); - #[inline] /// Default value of `font-variant-ligatures` as `empty` + #[inline] pub fn empty() -> FontVariantLigatures { FontVariantLigatures::Value(VariantLigatures::empty()) } @@ -1381,24 +1630,10 @@ impl FontVariantLigatures { impl ToComputedValue for FontVariantLigatures { type ComputedValue = computed::FontVariantLigatures; - fn to_computed_value(&self, _context: &Context) -> computed::FontVariantLigatures { + fn to_computed_value(&self, context: &Context) -> computed::FontVariantLigatures { match *self { FontVariantLigatures::Value(ref v) => v.clone(), - FontVariantLigatures::System(_) => { - #[cfg(feature = "gecko")] - { - _context - .cached_system_font - .as_ref() - .unwrap() - .font_variant_ligatures - .clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontVariantLigatures::System(_) => self.compute_system(context), } } @@ -1611,42 +1846,16 @@ impl FontVariantNumeric { FontVariantNumeric::Value(VariantNumeric::empty()) } - /// Get `font-variant-numeric` with system font - pub fn system_font(f: SystemFont) -> Self { - FontVariantNumeric::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontVariantNumeric::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontVariantNumeric, font_variant_numeric); } impl ToComputedValue for FontVariantNumeric { type ComputedValue = computed::FontVariantNumeric; - fn to_computed_value(&self, _context: &Context) -> computed::FontVariantNumeric { + fn to_computed_value(&self, context: &Context) -> computed::FontVariantNumeric { match *self { FontVariantNumeric::Value(ref v) => v.clone(), - FontVariantNumeric::System(_) => { - #[cfg(feature = "gecko")] - { - _context - .cached_system_font - .as_ref() - .unwrap() - .font_variant_numeric - .clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontVariantNumeric::System(_) => self.compute_system(context), } } @@ -1744,19 +1953,7 @@ impl FontFeatureSettings { FontFeatureSettings::Value(FontSettings::normal()) } - /// Get `font-feature-settings` with system font - pub fn system_font(f: SystemFont) -> Self { - FontFeatureSettings::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontFeatureSettings::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontFeatureSettings, font_feature_settings); } impl ToComputedValue for FontFeatureSettings { @@ -1765,21 +1962,7 @@ impl ToComputedValue for FontFeatureSettings { fn to_computed_value(&self, context: &Context) -> computed::FontFeatureSettings { match *self { FontFeatureSettings::Value(ref v) => v.to_computed_value(context), - FontFeatureSettings::System(_) => { - #[cfg(feature = "gecko")] - { - context - .cached_system_font - .as_ref() - .unwrap() - .font_feature_settings - .clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontFeatureSettings::System(_) => self.compute_system(context), } } @@ -1919,26 +2102,14 @@ impl FontLanguageOverride { FontLanguageOverride::Normal } - /// Get `font-language-override` with `system font` - pub fn system_font(f: SystemFont) -> Self { - FontLanguageOverride::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontLanguageOverride::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontLanguageOverride, font_language_override); } impl ToComputedValue for FontLanguageOverride { type ComputedValue = computed::FontLanguageOverride; #[inline] - fn to_computed_value(&self, _context: &Context) -> computed::FontLanguageOverride { + fn to_computed_value(&self, context: &Context) -> computed::FontLanguageOverride { match *self { FontLanguageOverride::Normal => computed::FontLanguageOverride(0), FontLanguageOverride::Override(ref lang) => { @@ -1952,20 +2123,7 @@ impl ToComputedValue for FontLanguageOverride { let bytes = computed_lang.into_bytes(); computed::FontLanguageOverride(BigEndian::read_u32(&bytes)) }, - FontLanguageOverride::System(_) => { - #[cfg(feature = "gecko")] - { - _context - .cached_system_font - .as_ref() - .unwrap() - .font_language_override - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontLanguageOverride::System(_) => self.compute_system(context), } } #[inline] @@ -2026,19 +2184,7 @@ impl FontVariationSettings { FontVariationSettings::Value(FontSettings::normal()) } - /// Get `font-variation-settings` with system font - pub fn system_font(f: SystemFont) -> Self { - FontVariationSettings::System(f) - } - - /// Get system font - pub fn get_system(&self) -> Option<SystemFont> { - if let FontVariationSettings::System(s) = *self { - Some(s) - } else { - None - } - } + system_font_methods!(FontVariationSettings, font_variation_settings); } impl ToComputedValue for FontVariationSettings { @@ -2047,21 +2193,7 @@ impl ToComputedValue for FontVariationSettings { fn to_computed_value(&self, context: &Context) -> computed::FontVariationSettings { match *self { FontVariationSettings::Value(ref v) => v.to_computed_value(context), - FontVariationSettings::System(_) => { - #[cfg(feature = "gecko")] - { - context - .cached_system_font - .as_ref() - .unwrap() - .font_variation_settings - .clone() - } - #[cfg(feature = "servo")] - { - unreachable!() - } - }, + FontVariationSettings::System(_) => self.compute_system(context), } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 570651ea2ef..20b49596ab7 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -34,8 +34,8 @@ pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; pub use self::border::{BorderImageRepeat, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing}; pub use self::column::ColumnCount; -pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontVariantAlternates, FontWeight}; -pub use self::font::{FontFamily, FontLanguageOverride, FontVariantEastAsian, FontVariationSettings}; +pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight}; +pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings}; pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; @@ -201,7 +201,14 @@ impl Number { } } + /// Returns whether this number came from a `calc()` expression. + #[inline] + pub fn was_calc(&self) -> bool { + self.calc_clamping_mode.is_some() + } + /// Returns the numeric value, clamped if needed. + #[inline] pub fn get(&self) -> f32 { self.calc_clamping_mode .map_or(self.value, |mode| mode.clamp(self.value)) diff --git a/etc/ci/buildbot_steps.yml b/etc/ci/buildbot_steps.yml index 12ba8a4b876..217c409b27b 100644 --- a/etc/ci/buildbot_steps.yml +++ b/etc/ci/buildbot_steps.yml @@ -22,7 +22,6 @@ mac-rel-wpt2: - env PKG_CONFIG_PATH=/usr/local/opt/zlib/lib/pkgconfig ./mach build --release - ./mach test-wpt --release --processes 4 --total-chunks 6 --this-chunk 2 --log-raw test-wpt.log --log-errorsummary wpt-errorsummary.log --always-succeed - ./mach filter-intermittents wpt-errorsummary.log --log-intermittents intermittents.log --log-filteredsummary filtered-wpt-errorsummary.log --tracker-api default --reporter-api default - - env PKG_CONFIG_PATH=/usr/local/opt/zlib/lib/pkgconfig ./mach build-geckolib --release mac-rel-wpt3: - ./mach clean-nightlies --keep 3 --force @@ -47,7 +46,6 @@ mac-dev-unit: - env PKG_CONFIG_PATH=/usr/local/opt/zlib/lib/pkgconfig ./mach test-unit - python ./etc/memory_reports_over_time.py --test - ./mach package --dev - - ./mach build-geckolib - bash ./etc/ci/lockfile_changed.sh - bash ./etc/ci/manifest_changed.sh @@ -113,8 +111,6 @@ linux-dev: - python ./etc/memory_reports_over_time.py --test - ./mach package --dev - ./mach build --dev --no-default-features --features default-except-unstable - - ./mach build-geckolib - - ./mach test-stylo - bash ./etc/ci/lockfile_changed.sh - bash ./etc/ci/manifest_changed.sh - bash ./etc/ci/check_no_panic.sh @@ -145,8 +141,6 @@ linux-rel-css: - ./mach build --release --with-debug-assertions - ./mach test-wpt --release --processes 24 --total-chunks 2 --this-chunk 2 --log-raw test-wpt.log --log-errorsummary wpt-errorsummary.log --always-succeed - ./mach filter-intermittents wpt-errorsummary.log --log-intermittents intermittents.log --log-filteredsummary filtered-wpt-errorsummary.log --tracker-api default --reporter-api default - - ./mach build-geckolib --release - - ./mach test-stylo --release - bash ./etc/ci/lockfile_changed.sh - bash ./etc/ci/manifest_changed.sh - ./etc/ci/clean_build_artifacts.sh @@ -201,8 +195,6 @@ windows-msvc-dev: - mach.bat build --dev - mach.bat test-unit - mach.bat package --dev - - mach.bat build-geckolib - - mach.bat test-stylo windows-msvc-nightly: env: diff --git a/etc/ci/taskcluster-test.sh b/etc/ci/taskcluster-test.sh index 0ef6863004f..9a18b9a489a 100755 --- a/etc/ci/taskcluster-test.sh +++ b/etc/ci/taskcluster-test.sh @@ -15,8 +15,6 @@ env CC=gcc-5 CXX=g++-5 ./mach build --dev env ./mach test-unit env ./mach package --dev env ./mach build --dev --no-default-features --features default-except-unstable -./mach build-geckolib -./mach test-stylo bash ./etc/ci/lockfile_changed.sh bash ./etc/ci/manifest_changed.sh bash ./etc/ci/check_no_panic.sh diff --git a/etc/ci/upload_docs.sh b/etc/ci/upload_docs.sh index 5a8188df2de..f1cfa076d0c 100755 --- a/etc/ci/upload_docs.sh +++ b/etc/ci/upload_docs.sh @@ -23,11 +23,6 @@ env CC=gcc-5 CXX=g++-5 ./mach doc # when it encounters directories. cp -r etc/doc.servo.org/* target/doc/ -./mach cargo-geckolib doc -# Use recursive copy here to avoid `cp` returning an error code -# when it encounters directories. -cp -r target/geckolib/doc/* target/doc/geckolib/ - python components/style/properties/build.py servo html regular cd components/script diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 3a476640de1..04d5a22cd40 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -6,6 +6,7 @@ use cssparser::{ParseErrorKind, Parser, ParserInput, SourceLocation}; use cssparser::ToCss as ParserToCss; use env_logger::Builder; use malloc_size_of::MallocSizeOfOps; +use nsstring::nsCString; use selectors::{NthIndexCache, SelectorList}; use selectors::matching::{MatchingContext, MatchingMode, matches_selector}; use servo_arc::{Arc, ArcBorrow, RawOffsetArc}; @@ -92,7 +93,8 @@ use style::gecko_bindings::structs; use style::gecko_bindings::structs::{CallerType, CSSPseudoElementType, CompositeOperation}; use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets}; use style::gecko_bindings::structs::{RawServoStyleRule, ComputedStyleStrong, RustString}; -use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetParsingMode, nsAtom, nsCSSPropertyID}; +use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder}; +use style::gecko_bindings::structs::{SheetParsingMode, nsAtom, nsCSSPropertyID}; use style::gecko_bindings::structs::{nsCSSFontDesc, nsCSSCounterDesc}; use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair}; use style::gecko_bindings::structs::AtomArray; @@ -145,6 +147,7 @@ use style::stylesheets::{DocumentRule, FontFaceRule, FontFeatureValuesRule, Impo use style::stylesheets::{KeyframesRule, MediaRule, NamespaceRule, Origin, OriginSet, PageRule}; use style::stylesheets::{StyleRule, StylesheetContents, SupportsRule}; use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; +use style::stylesheets::import_rule::ImportSheet; use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue}; use style::stylesheets::supports_rule::parse_condition_or_declaration; use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist}; @@ -163,7 +166,7 @@ use style::values::specified::gecko::{IntersectionObserverRootMargin, PixelOrPer use style::values::specified::source_size_list::SourceSizeList; use style_traits::{CssWriter, ParsingMode, StyleParseErrorKind, ToCss}; use super::error_reporter::ErrorReporter; -use super::stylesheet_loader::StylesheetLoader; +use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader}; /* * For Gecko->Servo function calls, we need to redeclare the same signature that was declared in @@ -1122,6 +1125,15 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl ).into_strong() } +fn mode_to_origin(mode: SheetParsingMode) -> Origin { + match mode { + SheetParsingMode::eAuthorSheetFeatures => Origin::Author, + SheetParsingMode::eUserSheetFeatures => Origin::User, + SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, + SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent, + } +} + /// Note: The load_data corresponds to this sheet, and is passed as the parent /// load data for child sheet loads. It may be null for certain cases where we /// know we won't have child loads. @@ -1130,8 +1142,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( loader: *mut Loader, stylesheet: *mut ServoStyleSheet, load_data: *mut SheetLoadData, - data: *const u8, - data_len: usize, + bytes: *const nsACString, mode: SheetParsingMode, extra_data: *mut URLExtraData, line_number_offset: u32, @@ -1139,14 +1150,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( reusable_sheets: *mut LoaderReusableStyleSheets, ) -> RawServoStyleSheetContentsStrong { let global_style_data = &*GLOBAL_STYLE_DATA; - let input = unsafe { ::std::str::from_utf8_unchecked(::std::slice::from_raw_parts(data, data_len)) }; - - let origin = match mode { - SheetParsingMode::eAuthorSheetFeatures => Origin::Author, - SheetParsingMode::eUserSheetFeatures => Origin::User, - SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, - SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent, - }; + let input: &str = unsafe { (*bytes).as_str_unchecked() }; let reporter = ErrorReporter::new(stylesheet, loader, extra_data); let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) }; @@ -1164,13 +1168,45 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( Arc::new(StylesheetContents::from_str( - input, url_data.clone(), origin, + input, url_data.clone(), mode_to_origin(mode), &global_style_data.shared_lock, loader, &reporter, quirks_mode.into(), line_number_offset) ).into_strong() } #[no_mangle] +pub extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync( + load_data: *mut SheetLoadDataHolder, + extra_data: *mut URLExtraData, + bytes: *const nsACString, + mode: SheetParsingMode, + line_number_offset: u32, + quirks_mode: nsCompatibility, +) { + let (load_data, extra_data, bytes) = unsafe { + let mut b = nsCString::new(); + b.assign(&*bytes); + (RefPtr::new(load_data), RefPtr::new(extra_data), b) + }; + let async_parser = AsyncStylesheetParser::new( + load_data, + extra_data, + bytes, + mode_to_origin(mode), + quirks_mode.into(), + line_number_offset + ); + + if let Some(thread_pool) = STYLE_THREAD_POOL.style_thread_pool.as_ref() { + thread_pool.spawn(|| { + async_parser.parse(); + }); + } else { + async_parser.parse(); + } +} + +#[no_mangle] pub extern "C" fn Servo_StyleSet_AppendStyleSheet( raw_data: RawServoStyleSetBorrowed, sheet: *const ServoStyleSheet, @@ -2053,6 +2089,17 @@ pub extern "C" fn Servo_ImportRule_GetSheet( } #[no_mangle] +pub extern "C" fn Servo_ImportRule_SetSheet( + rule: RawServoImportRuleBorrowed, + sheet: *mut ServoStyleSheet, +) { + write_locked_arc(rule, |rule: &mut ImportRule| { + let sheet = unsafe { GeckoStyleSheet::new(sheet) }; + rule.stylesheet = ImportSheet::new(sheet); + }) +} + +#[no_mangle] pub extern "C" fn Servo_Keyframe_GetKeyText( keyframe: RawServoKeyframeBorrowed, result: *mut nsAString @@ -2709,7 +2756,7 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForAnonymousBox( let level = match origin { Origin::UserAgent => CascadeLevel::UANormal, Origin::User => CascadeLevel::UserNormal, - Origin::Author => CascadeLevel::AuthorNormal, + Origin::Author => CascadeLevel::SameTreeAuthorNormal, }; for rule in data.pages.iter() { declarations.push(ApplicableDeclarationBlock::from_declarations( @@ -3753,6 +3800,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue( ) { use style::properties::{PropertyDeclaration, LonghandId}; use style::properties::longhands; + use style::values::generics::font::FontStyle; use style::values::specified::BorderStyle; let long = get_longhand_from_id!(property); @@ -3773,7 +3821,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue( longhands::font_size::SpecifiedValue::from_html_size(value as u8) }, FontStyle => { - ToComputedValue::from_computed_value(&longhands::font_style::computed_value::T::from_gecko_keyword(value)) + let val = if value == structs::NS_FONT_STYLE_ITALIC { + FontStyle::Italic + } else { + debug_assert_eq!(value, structs::NS_FONT_STYLE_NORMAL); + FontStyle::Normal + }; + + ToComputedValue::from_computed_value(&val) }, FontWeight => longhands::font_weight::SpecifiedValue::from_gecko_keyword(value), ListStyleType => Box::new(longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value)), @@ -5360,9 +5415,9 @@ pub extern "C" fn Servo_ParseFontShorthandForMatching( stretch: nsCSSValueBorrowedMut, weight: nsCSSValueBorrowedMut ) -> bool { - use style::properties::longhands::{font_stretch, font_style}; use style::properties::shorthands::font; - use style::values::specified::font::{FontFamily, FontWeight}; + use style::values::generics::font::FontStyle as GenericFontStyle; + use style::values::specified::font::{FontFamily, FontWeight, FontStyle, SpecifiedFontStyle}; let string = unsafe { (*value).to_string() }; let mut input = ParserInput::new(&string); @@ -5387,18 +5442,26 @@ pub extern "C" fn Servo_ParseFontShorthandForMatching( FontFamily::Values(list) => family.set_move(list.0), FontFamily::System(_) => return false, } - style.set_from(match font.font_style { - font_style::SpecifiedValue::Keyword(ref kw) => kw, - font_style::SpecifiedValue::System(_) => return false, - }); - stretch.set_from(match font.font_stretch { - font_stretch::SpecifiedValue::Keyword(ref kw) => kw, - font_stretch::SpecifiedValue::System(_) => return false, - }); + + let specified_font_style = match font.font_style { + FontStyle::Specified(ref s) => s, + FontStyle::System(_) => return false, + }; + match *specified_font_style { + GenericFontStyle::Normal => style.set_normal(), + GenericFontStyle::Italic => style.set_enum(structs::NS_FONT_STYLE_ITALIC as i32), + GenericFontStyle::Oblique(ref angle) => { + style.set_font_style(SpecifiedFontStyle::compute_angle(angle).degrees()) + } + } + + if font.font_stretch.get_system().is_some() { + return false; + } + stretch.set_from(&font.font_stretch); + match font.font_weight { - FontWeight::Weight(w) => weight.set_from(w), - FontWeight::Normal => weight.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32), - FontWeight::Bold => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), + FontWeight::Absolute(w) => weight.set_font_weight(w.compute().0), // Resolve relative font weights against the initial of font-weight // (normal, which is equivalent to 400). FontWeight::Bolder => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 80c22e54707..d48a096df64 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -9,6 +9,7 @@ extern crate env_logger; extern crate libc; #[macro_use] extern crate log; extern crate malloc_size_of; +extern crate nsstring; extern crate selectors; extern crate servo_arc; extern crate smallvec; diff --git a/ports/geckolib/stylesheet_loader.rs b/ports/geckolib/stylesheet_loader.rs index 1dfe30e8bdb..0c320fee897 100644 --- a/ports/geckolib/stylesheet_loader.rs +++ b/ports/geckolib/stylesheet_loader.rs @@ -3,15 +3,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cssparser::SourceLocation; +use nsstring::nsCString; use servo_arc::Arc; +use style::context::QuirksMode; +use style::error_reporting::NullReporter; use style::gecko::data::GeckoStyleSheet; +use style::gecko::global_style_data::GLOBAL_STYLE_DATA; +use style::gecko_bindings::bindings; use style::gecko_bindings::bindings::Gecko_LoadStyleSheet; -use style::gecko_bindings::structs::{Loader, ServoStyleSheet, SheetLoadData, LoaderReusableStyleSheets}; +use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets}; +use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder}; +use style::gecko_bindings::structs::URLExtraData; use style::gecko_bindings::sugar::ownership::FFIArcHelpers; +use style::gecko_bindings::sugar::refptr::RefPtr; use style::media_queries::MediaList; use style::parser::ParserContext; use style::shared_lock::{Locked, SharedRwLock}; -use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader}; +use style::stylesheets::{ImportRule, Origin, StylesheetLoader as StyleStylesheetLoader}; +use style::stylesheets::StylesheetContents; use style::stylesheets::import_rule::ImportSheet; use style::values::CssUrl; @@ -41,15 +50,11 @@ impl StyleStylesheetLoader for StylesheetLoader { // so this raw pointer will still be valid. let child_sheet = unsafe { - let (spec_bytes, spec_len) = url.as_slice_components(); - let base_url_data = url.extra_data.get(); Gecko_LoadStyleSheet(self.0, self.1, self.2, self.3, - base_url_data, - spec_bytes, - spec_len as u32, + url.for_ffi(), media.into_strong()) }; @@ -60,3 +65,75 @@ impl StyleStylesheetLoader for StylesheetLoader { Arc::new(lock.wrap(ImportRule { url, source_location, stylesheet })) } } + +pub struct AsyncStylesheetParser { + load_data: RefPtr<SheetLoadDataHolder>, + extra_data: RefPtr<URLExtraData>, + bytes: nsCString, + origin: Origin, + quirks_mode: QuirksMode, + line_number_offset: u32, +} + +impl AsyncStylesheetParser { + pub fn new( + load_data: RefPtr<SheetLoadDataHolder>, + extra_data: RefPtr<URLExtraData>, + bytes: nsCString, + origin: Origin, + quirks_mode: QuirksMode, + line_number_offset: u32, + ) -> Self { + AsyncStylesheetParser { + load_data, + extra_data, + bytes, + origin, + quirks_mode, + line_number_offset, + } + } + + pub fn parse(self) { + let global_style_data = &*GLOBAL_STYLE_DATA; + let input: &str = unsafe { (*self.bytes).as_str_unchecked() }; + + // Note: Parallel CSS parsing doesn't report CSS errors. When errors + // are being logged, Gecko prevents the parallel parsing path from + // running. + let sheet = Arc::new(StylesheetContents::from_str( + input, self.extra_data.clone(), self.origin, + &global_style_data.shared_lock, Some(&self), &NullReporter, + self.quirks_mode.into(), self.line_number_offset) + ); + + unsafe { + bindings::Gecko_StyleSheet_FinishAsyncParse(self.load_data.get(), sheet.into_strong()); + } + } +} + +impl StyleStylesheetLoader for AsyncStylesheetParser { + fn request_stylesheet( + &self, + url: CssUrl, + source_location: SourceLocation, + _context: &ParserContext, + lock: &SharedRwLock, + media: Arc<Locked<MediaList>>, + ) -> Arc<Locked<ImportRule>> { + let stylesheet = ImportSheet::new_pending(self.origin, self.quirks_mode); + let rule = Arc::new(lock.wrap(ImportRule { url: url.clone(), source_location, stylesheet })); + + unsafe { + bindings::Gecko_LoadStyleSheetAsync( + self.load_data.get(), + url.for_ffi(), + media.into_strong(), + rule.clone().into_strong() + ); + } + + rule + } +} diff --git a/ports/geckolib/tests/build.rs b/ports/geckolib/tests/build.rs index ab21e2186cd..7feb9d10405 100644 --- a/ports/geckolib/tests/build.rs +++ b/ports/geckolib/tests/build.rs @@ -11,8 +11,11 @@ use std::io::{BufRead, BufReader, Write}; use std::path::Path; fn main() { + // https://github.com/rust-lang/cargo/issues/3544 + let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \ + TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap(); let root_path = Path::new("../../../"); - let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs"); + let bindings_file = Path::new(&style_out_dir).join("gecko/bindings.rs"); let glue_file = root_path.join("ports/geckolib/glue.rs"); println!("cargo:rerun-if-changed=build.rs"); @@ -70,9 +73,6 @@ fn main() { } } - // https://github.com/rust-lang/cargo/issues/3544 - let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \ - TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap(); File::create(out_dir.join("bindings.rs")) .unwrap() .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));", diff --git a/tests/unit/style/parsing/font.rs b/tests/unit/style/parsing/font.rs deleted file mode 100644 index b111ceae8bc..00000000000 --- a/tests/unit/style/parsing/font.rs +++ /dev/null @@ -1,17 +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 http://mozilla.org/MPL/2.0/. */ - -use parsing::parse; -use style::properties::longhands::font_weight; - -#[test] -fn font_weight_keyword_should_preserve_keyword() { - use style::properties::longhands::font_weight::SpecifiedValue; - - let result = parse(font_weight::parse, "normal").unwrap(); - assert_eq!(result, SpecifiedValue::Normal); - - let result = parse(font_weight::parse, "bold").unwrap(); - assert_eq!(result, SpecifiedValue::Bold); -} diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs index 1c1dfc3d185..d89e76378f7 100644 --- a/tests/unit/style/parsing/mod.rs +++ b/tests/unit/style/parsing/mod.rs @@ -109,7 +109,6 @@ mod border; mod box_; mod column; mod effects; -mod font; mod image; mod inherited_text; mod length; diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html.ini index 1d94b9c3350..ce924174648 100644 --- a/tests/wpt/metadata/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html.ini +++ b/tests/wpt/metadata/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html.ini @@ -1,36 +1,4 @@ [font-parse-numeric-stretch-style-weight.html] - [Valid value 850 for font property weight used for styling.] - expected: FAIL - - [Valid value 850.3 for font property weight used for styling.] - expected: FAIL - - [Valid value calc(100 + 300) for font property weight used for styling.] - expected: FAIL - - [Valid value calc(0.2 + 205.5) for font property weight used for styling.] - expected: FAIL - - [Valid value 51% for font property stretch used for styling.] - expected: FAIL - - [Valid value 199% for font property stretch used for styling.] - expected: FAIL - - [Valid value calc(10% + 20%) for font property stretch used for styling.] - expected: FAIL - - [Valid value oblique 50deg for font property style used for styling.] - expected: FAIL - - [Valid value oblique -90deg for font property style used for styling.] - expected: FAIL - - [Valid value oblique 90deg for font property style used for styling.] - expected: FAIL - - [Valid value oblique calc(30deg + 20deg) for font property style used for styling.] - expected: FAIL [Valid value 100 matches 100 for weight in @font-face.] expected: FAIL @@ -188,18 +156,6 @@ [Value italic 90deg must not be accepted as style in @font-face.] expected: FAIL - [Valid value calc(0 - 100) for font property weight used for styling.] - expected: FAIL - - [Valid value calc(200 + 801) for font property weight used for styling.] - expected: FAIL - - [Valid value 0% for font property stretch used for styling.] - expected: FAIL - - [Valid value oblique calc(90deg + 20deg) for font property style used for styling.] - expected: FAIL - [Valid value 500 400 matches 500 400 for weight in @font-face.] expected: FAIL diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-shorthand.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-shorthand.html.ini deleted file mode 100644 index 30c11241f69..00000000000 --- a/tests/wpt/metadata/css/css-fonts/variations/font-shorthand.html.ini +++ /dev/null @@ -1,46 +0,0 @@ -[font-shorthand.html] - [Font shorthand: Font weight specified as number] - expected: FAIL - - [Font shorthand: Font weight specified as calc()] - expected: FAIL - - [Font shorthand: Font weight specified as calc(), value smaller than 1] - expected: FAIL - - [Font shorthand: Font weight specified as calc(), value greater than 1000] - expected: FAIL - - [Font shorthand: 'oblique' with positive angle] - expected: FAIL - - [Font shorthand: 'oblique' with negative angle] - expected: FAIL - - [Font shorthand: 'oblique' followed by valid small weight] - expected: FAIL - - [Font shorthand: 'oblique' with positive angle followed by valid weight] - expected: FAIL - - [Font shorthand: 'oblique' with negative angle followed by valid weight] - expected: FAIL - - [Font shorthand: 'oblique' followed by valid calc() weight] - expected: FAIL - - [Font shorthand: 'oblique' with angle followed by valid calc() weight] - expected: FAIL - - [Font shorthand: 'oblique' followed by a to-be-clamped calc() weight] - expected: FAIL - - [Font shorthand: calc() weight folowed by 'oblique'] - expected: FAIL - - [Font shorthand: calc() weight folowed by 'oblique' and slant angle] - expected: FAIL - - [Font shorthand: To-be-clamped calc() weight folowed by 'oblique' and slant angle] - expected: FAIL - diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-stretch.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-stretch.html.ini index 934fe5409e8..3412ec0c36c 100644 --- a/tests/wpt/metadata/css/css-fonts/variations/font-stretch.html.ini +++ b/tests/wpt/metadata/css/css-fonts/variations/font-stretch.html.ini @@ -1,97 +1,5 @@ [font-stretch.html] - [@supports: 0% - zero is legal] - expected: FAIL - - [@getComputedStyle: 0% - zero is legal] - expected: FAIL - - [@supports: 1% - legal percentage] - expected: FAIL - - [@getComputedStyle: 1% - legal percentage] - expected: FAIL - - [@supports: 10% - legal percentage] - expected: FAIL - - [@getComputedStyle: 10% - legal percentage] - expected: FAIL - - [@supports: 100% - legal percentage] - expected: FAIL - - [@getComputedStyle: 100% - legal percentage] - expected: FAIL - - [@supports: 1000% - legal percentage] - expected: FAIL - - [@getComputedStyle: 1000% - legal percentage] - expected: FAIL - - [@supports: 1e9% - huge legal percentage] - expected: FAIL [@getComputedStyle: 1e9% - huge legal percentage] expected: FAIL - [@getComputedStyle: ultra-condensed - legal enum] - expected: FAIL - - [@getComputedStyle: extra-condensed - legal enum] - expected: FAIL - - [@getComputedStyle: condensed - legal enum] - expected: FAIL - - [@getComputedStyle: semi-condensed - legal enum] - expected: FAIL - - [@getComputedStyle: normal - legal enum] - expected: FAIL - - [@getComputedStyle: semi-expanded - legal enum] - expected: FAIL - - [@getComputedStyle: expanded - legal enum] - expected: FAIL - - [@getComputedStyle: extra-expanded - legal enum] - expected: FAIL - - [@getComputedStyle: ultra-expanded - legal enum] - expected: FAIL - - [@supports: calc(200.5%) - Simple calc value] - expected: FAIL - - [@getComputedStyle: calc(200.5%) - Simple calc value] - expected: FAIL - - [@supports: calc(50%*2 - 20%) - Valid calc expression] - expected: FAIL - - [@getComputedStyle: calc(50%*2 - 20%) - Valid calc expression] - expected: FAIL - - [@supports: calc(-100%) - Negative calc value (to be clamped)] - expected: FAIL - - [@getComputedStyle: calc(-100%) - Negative calc value (to be clamped)] - expected: FAIL - - [@supports: calc(50% - 50%*2) - Negative calc expression (to be clamped)] - expected: FAIL - - [@getComputedStyle: calc(50% - 50%*2) - Negative calc expression (to be clamped)] - expected: FAIL - - [Test font-stretch for overridden number condensed] - expected: FAIL - - [Test font-stretch for overridden enum name resolved to number condensed] - expected: FAIL - - [Test font-stretch for inherited named enum resolved to number condensed] - expected: FAIL - diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-style-interpolation.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-style-interpolation.html.ini index e37fe238ce4..fd9f8617078 100644 --- a/tests/wpt/metadata/css/css-fonts/variations/font-style-interpolation.html.ini +++ b/tests/wpt/metadata/css/css-fonts/variations/font-style-interpolation.html.ini @@ -3,6 +3,3 @@ [font-style animation] expected: TIMEOUT - [font-style transition] - expected: FAIL - diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-style-parsing.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-style-parsing.html.ini deleted file mode 100644 index 6653e80949f..00000000000 --- a/tests/wpt/metadata/css/css-fonts/variations/font-style-parsing.html.ini +++ /dev/null @@ -1,43 +0,0 @@ -[font-style-parsing.html] - [Font-style: 'oblique' followed by zero degrees is valid] - expected: FAIL - - [Font-style: 'oblique' followed by positive angle in degrees is valid] - expected: FAIL - - [Font-style: 'oblique' followed by positive angle in radians is valid] - expected: FAIL - - [Font-style: 'oblique' followed by positive angle in gradians is valid] - expected: FAIL - - [Font-style: 'oblique' followed by positive angle in turns is valid] - expected: FAIL - - [Font-style: 'oblique' followed by negative angle is valid] - expected: FAIL - - [Font-style: 'oblique' followed by fractional angle is valid] - expected: FAIL - - [Font-style: 'oblique' followed by maxumum 90 degree angle is valid] - expected: FAIL - - [Font-style: 'oblique' followed by minimum -90 degree angle is valid] - expected: FAIL - - [Font-style: 'oblique' followed by positive angle is valid] - expected: FAIL - - [Font-style: 'oblique' followed by calc is valid] - expected: FAIL - - [Font-style: 'oblique' followed by calc is valid even if it must be clamped (no computation)] - expected: FAIL - - [Font-style: 'oblique' followed by calc is valid even if it must be clamped (with computation)] - expected: FAIL - - [Font-style: 'oblique' followed by calc is valid even if it mixes units (with computation)] - expected: FAIL - diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-weight-lighter-bolder.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-weight-lighter-bolder.html.ini deleted file mode 100644 index 1ef0aa9b30c..00000000000 --- a/tests/wpt/metadata/css/css-fonts/variations/font-weight-lighter-bolder.html.ini +++ /dev/null @@ -1,40 +0,0 @@ -[font-weight-lighter-bolder.html] - [Test lighter font-weight for base weight 99] - expected: FAIL - - [Test bolder font-weight for base weight 99] - expected: FAIL - - [Test bolder font-weight for base weight 349] - expected: FAIL - - [Test lighter font-weight for base weight 550] - expected: FAIL - - [Test bolder font-weight for base weight 550] - expected: FAIL - - [Test lighter font-weight for base weight 749] - expected: FAIL - - [Test bolder font-weight for base weight 749] - expected: FAIL - - [Test lighter font-weight for base weight 750] - expected: FAIL - - [Test bolder font-weight for base weight 750] - expected: FAIL - - [Test lighter font-weight for base weight 899] - expected: FAIL - - [Test bolder font-weight for base weight 899] - expected: FAIL - - [Test lighter font-weight for base weight 901] - expected: FAIL - - [Test bolder font-weight for base weight 901] - expected: FAIL - diff --git a/tests/wpt/metadata/css/css-fonts/variations/font-weight-parsing.html.ini b/tests/wpt/metadata/css/css-fonts/variations/font-weight-parsing.html.ini deleted file mode 100644 index 05e9036381d..00000000000 --- a/tests/wpt/metadata/css/css-fonts/variations/font-weight-parsing.html.ini +++ /dev/null @@ -1,55 +0,0 @@ -[font-weight-parsing.html] - [@supports: Values that are not multiple of 100 should be parsed successfully] - expected: FAIL - - [@supports: Non-integer Values should be parsed successfully] - expected: FAIL - - [@supports: Minimum allowed value should be parsed successfully] - expected: FAIL - - [@supports: Maximum allowed value should be parsed successfully] - expected: FAIL - - [@supports: Simple calc value] - expected: FAIL - - [@supports: Negative simple calc value (to be clamped)] - expected: FAIL - - [@supports: Out-of-range simple calc value (to be clamped)] - expected: FAIL - - [@supports: Valid calc expression] - expected: FAIL - - [@supports: Valid calc expression with out-of-range value (to be clamped)] - expected: FAIL - - [Computed style: Values that are not multiple of 100 should be parsed successfully] - expected: FAIL - - [Computed style: Non-integer Values should be parsed successfully] - expected: FAIL - - [Computed style: Minimum allowed value should be parsed successfully] - expected: FAIL - - [Computed style: Maximum allowed value should be parsed successfully] - expected: FAIL - - [Computed style: Simple calc value] - expected: FAIL - - [Computed style: Negative simple calc value (to be clamped)] - expected: FAIL - - [Computed style: Out-of-range simple calc value (to be clamped)] - expected: FAIL - - [Computed style: Valid calc expression] - expected: FAIL - - [Computed style: Valid calc expression with out-of-range value (to be clamped)] - expected: FAIL - diff --git a/tests/wpt/metadata/css/css-variables/variable-presentation-attribute.html.ini b/tests/wpt/metadata/css/css-variables/variable-presentation-attribute.html.ini index da00995e02b..bbb64382d67 100644 --- a/tests/wpt/metadata/css/css-variables/variable-presentation-attribute.html.ini +++ b/tests/wpt/metadata/css/css-variables/variable-presentation-attribute.html.ini @@ -50,6 +50,9 @@ [Testing 'font-size-adjust'.] expected: FAIL + [Testing 'font-stretch'.] + expected: FAIL + [Testing 'glyph-orientation-horizontal'.] expected: FAIL |