--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -292,37 +292,16 @@ def set_gecko_property(ffi_name, expr):
% endfor
% if keyword.gecko_inexhaustive:
x => panic!("Found unexpected value in style struct for ${ident} property: {:?}", x),
% endif
}
}
</%def>
-<%def name="impl_bitflags_setter(ident, gecko_ffi_name, bit_map, gecko_bit_prefix, cast_type='u8')">
- #[allow(non_snake_case)]
- pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
- % for gecko_bit in bit_map.values():
- use gecko_bindings::structs::${gecko_bit_prefix}${gecko_bit};
- % endfor
-
- let mut bits: ${cast_type} = 0;
- // FIXME: if we ensure that the Servo bitflags storage is the same
- // as Gecko's one, we can just copy it.
- % for servo_bit, gecko_bit in bit_map.iteritems():
- if v.contains(longhands::${ident}::${servo_bit}) {
- bits |= ${gecko_bit_prefix}${gecko_bit} as ${cast_type};
- }
- % endfor
-
- self.gecko.${gecko_ffi_name} = bits as ${cast_type};
- }
-</%def>
-
-
/// Convert a Servo color into an nscolor; with currentColor as 0
///
/// Call sites will need to be updated after https://bugzilla.mozilla.org/show_bug.cgi?id=760345
fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
match color {
Color::RGBA(rgba) => {
convert_rgba_to_nscolor(&rgba)
},
@@ -1364,17 +1343,20 @@ fn static_assert() {
}
pub fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) {
self.gecko.mFont.weight = v as u16;
}
${impl_simple_copy('font_weight', 'mFont.weight')}
pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
- unsafe { longhands::font_weight::computed_value::T::from_gecko_weight(self.gecko.mFont.weight) }
+ debug_assert!(self.gecko.mFont.weight >= 100);
+ debug_assert!(self.gecko.mFont.weight <= 900);
+ debug_assert!(self.gecko.mFont.weight % 10 == 0);
+ unsafe { transmute(self.gecko.mFont.weight) }
}
pub fn set_font_synthesis(&mut self, v: longhands::font_synthesis::computed_value::T) {
use gecko_bindings::structs::{NS_FONT_SYNTHESIS_WEIGHT, NS_FONT_SYNTHESIS_STYLE};
self.gecko.mFont.synthesis = 0;
if v.weight {
self.gecko.mFont.synthesis |= NS_FONT_SYNTHESIS_WEIGHT as u8;
@@ -1398,17 +1380,20 @@ fn static_assert() {
pub fn copy_font_size_adjust_from(&mut self, other: &Self) {
self.gecko.mFont.sizeAdjust = other.gecko.mFont.sizeAdjust;
}
pub fn clone_font_size_adjust(&self) -> longhands::font_size_adjust::computed_value::T {
use properties::longhands::font_size_adjust::computed_value::T;
- T::from_gecko_adjust(self.gecko.mFont.sizeAdjust)
+ match self.gecko.mFont.sizeAdjust {
+ -1.0 => T::None,
+ _ => T::Number(self.gecko.mFont.sizeAdjust),
+ }
}
#[allow(non_snake_case)]
pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) {
let ptr = v.0.as_ptr();
forget(v);
unsafe {
Gecko_nsStyleFont_SetLang(&mut self.gecko, ptr);
@@ -1422,84 +1407,43 @@ fn static_assert() {
}
}
pub fn set_font_language_override(&mut self, v: longhands::font_language_override::computed_value::T) {
self.gecko.mFont.languageOverride = v.0;
}
${impl_simple_copy('font_language_override', 'mFont.languageOverride')}
- <% font_variant_alternates_map = { "HISTORICAL_FORMS": "HISTORICAL",
- "STYLISTIC": "STYLISTIC",
- "STYLESET": "STYLESET",
- "CHARACTER_VARIANT": "CHARACTER_VARIANT",
- "SWASH": "SWASH",
- "ORNAMENTS": "ORNAMENTS",
- "ANNOTATION": "ANNOTATION" } %>
- // FIXME: Set alternateValues as well.
- // self.gecko.mFont.alternateValues = xxx;
- ${impl_bitflags_setter('font_variant_alternates',
- 'mFont.variantAlternates',
- font_variant_alternates_map,
- 'NS_FONT_VARIANT_ALTERNATES_',
- cast_type='u16')}
+ pub fn set_font_variant_alternates(&mut self, v: longhands::font_variant_alternates::computed_value::T) {
+ self.gecko.mFont.variantAlternates = v.to_gecko_keyword()
+ }
+
#[allow(non_snake_case)]
pub fn copy_font_variant_alternates_from(&mut self, other: &Self) {
self.gecko.mFont.variantAlternates = other.gecko.mFont.variantAlternates;
// FIXME: Copy alternateValues as well.
// self.gecko.mFont.alternateValues = other.gecko.mFont.alternateValues;
}
- // servo_bit: gecko_bit
- <% font_variant_ligatures_map = { "NONE": "NONE",
- "COMMON_LIGATURES": "COMMON",
- "NO_COMMON_LIGATURES": "NO_COMMON",
- "DISCRETIONARY_LIGATURES": "DISCRETIONARY",
- "NO_DISCRETIONARY_LIGATURES": "NO_DISCRETIONARY",
- "HISTORICAL_LIGATURES": "HISTORICAL",
- "NO_HISTORICAL_LIGATURES": "NO_HISTORICAL",
- "CONTEXTUAL": "CONTEXTUAL",
- "NO_CONTEXTUAL": "NO_CONTEXTUAL" } %>
- ${impl_bitflags_setter('font_variant_ligatures',
- 'mFont.variantLigatures',
- font_variant_ligatures_map,
- 'NS_FONT_VARIANT_LIGATURES_',
- cast_type='u16')}
+ pub fn set_font_variant_ligatures(&mut self, v: longhands::font_variant_ligatures::computed_value::T) {
+ self.gecko.mFont.variantLigatures = v.to_gecko_keyword()
+ }
+
${impl_simple_copy('font_variant_ligatures', 'mFont.variantLigatures')}
- // servo_bit: gecko_bit
- <% font_variant_east_asian_map = { "JIS78": "JIS78",
- "JIS83": "JIS83",
- "JIS90": "JIS90",
- "JIS04": "JIS04",
- "SIMPLIFIED": "SIMPLIFIED",
- "TRADITIONAL": "TRADITIONAL",
- "FULL_WIDTH": "FULL_WIDTH",
- "PROPORTIONAL_WIDTH": "PROP_WIDTH",
- "RUBY": "RUBY" } %>
- ${impl_bitflags_setter('font_variant_east_asian',
- 'mFont.variantEastAsian',
- font_variant_east_asian_map,
- 'NS_FONT_VARIANT_EAST_ASIAN_',
- cast_type='u16')}
+ pub fn set_font_variant_east_asian(&mut self, v: longhands::font_variant_east_asian::computed_value::T) {
+ self.gecko.mFont.variantEastAsian = v.to_gecko_keyword()
+ }
+
${impl_simple_copy('font_variant_east_asian', 'mFont.variantEastAsian')}
- // servo_bit: gecko_bit
- <% font_variant_numeric_map = { "LINING_NUMS": "LINING",
- "OLDSTYLE_NUMS": "OLDSTYLE",
- "PROPORTIONAL_NUMS": "PROPORTIONAL",
- "TABULAR_NUMS": "TABULAR",
- "DIAGONAL_FRACTIONS": "DIAGONAL_FRACTIONS",
- "STACKED_FRACTIONS": "STACKED_FRACTIONS",
- "SLASHED_ZERO": "SLASHZERO",
- "ORDINAL": "ORDINAL" } %>
- ${impl_bitflags_setter('font_variant_numeric',
- 'mFont.variantNumeric',
- font_variant_numeric_map,
- 'NS_FONT_VARIANT_NUMERIC_')}
+ pub fn set_font_variant_numeric(&mut self, v: longhands::font_variant_numeric::computed_value::T) {
+ self.gecko.mFont.variantNumeric = v.to_gecko_keyword()
+ }
+
${impl_simple_copy('font_variant_numeric', 'mFont.variantNumeric')}
</%self:impl_trait>
<%def name="impl_copy_animation_or_transition_value(type, ident, gecko_ffi_name)">
#[allow(non_snake_case)]
pub fn copy_${type}_${ident}_from(&mut self, other: &Self) {
unsafe { self.gecko.m${type.capitalize()}s.ensure_len(other.gecko.m${type.capitalize()}s.len()) };
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -11,16 +11,62 @@
<%def name="nongecko_unreachable()">
%if product == "gecko":
${caller.body()}
%else:
unreachable!()
%endif
</%def>
+// Define ToComputedValue, ToCSS, and other boilerplate for a specified value
+// which is of the form `enum SpecifiedValue {Value(..), System(SystemFont)}`
+<%def name="simple_system_boilerplate(name)">
+ impl ToCss for SpecifiedValue {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ match *self {
+ SpecifiedValue::Value(v) => v.to_css(dest),
+ SpecifiedValue::System(_) => Ok(())
+ }
+ }
+ }
+
+
+ impl SpecifiedValue {
+ pub fn system_font(f: SystemFont) -> Self {
+ SpecifiedValue::System(f)
+ }
+ pub fn get_system(&self) -> Option<SystemFont> {
+ if let SpecifiedValue::System(s) = *self {
+ Some(s)
+ } else {
+ None
+ }
+ }
+ }
+
+ impl ToComputedValue for SpecifiedValue {
+ type ComputedValue = computed_value::T;
+
+ fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ match *self {
+ SpecifiedValue::Value(v) => v,
+ SpecifiedValue::System(_) => {
+ <%self:nongecko_unreachable>
+ context.style.cached_system_font.as_ref().unwrap().${name}
+ </%self:nongecko_unreachable>
+ }
+ }
+ }
+
+ fn from_computed_value(other: &computed_value::T) -> Self {
+ SpecifiedValue::Value(*other)
+ }
+ }
+</%def>
+
<%helpers:longhand name="font-family" animation_type="none" need_index="True"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-family">
use properties::longhands::system_font::SystemFont;
use self::computed_value::{FontFamily, FamilyName};
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
use values::computed::ComputedValueAsSpecified;
@@ -1031,39 +1077,56 @@
gecko_constant_prefix="NS_FONT_KERNING",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch",
animation_type="none")}
/// FIXME: Implement proper handling of each values.
/// https://github.com/servo/servo/issues/15957
<%helpers:longhand name="font-variant-alternates" products="gecko" animation_type="none"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-alternates">
+ use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
- use values::computed::ComputedValueAsSpecified;
- impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);
bitflags! {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub flags SpecifiedValue: u8 {
+ pub flags VariantAlternates: u8 {
const NORMAL = 0,
const HISTORICAL_FORMS = 0x01,
const STYLISTIC = 0x02,
const STYLESET = 0x04,
const CHARACTER_VARIANT = 0x08,
const SWASH = 0x10,
const ORNAMENTS = 0x20,
const ANNOTATION = 0x40,
}
}
- impl ToCss for SpecifiedValue {
+ #[derive(Debug, Clone, PartialEq)]
+ pub enum SpecifiedValue {
+ Value(VariantAlternates),
+ System(SystemFont)
+ }
+
+ <%self:simple_system_boilerplate name="font_variant_alternates"></%self:simple_system_boilerplate>
+
+ <% font_variant_alternates_map = { "HISTORICAL_FORMS": "HISTORICAL",
+ "STYLISTIC": "STYLISTIC",
+ "STYLESET": "STYLESET",
+ "CHARACTER_VARIANT": "CHARACTER_VARIANT",
+ "SWASH": "SWASH",
+ "ORNAMENTS": "ORNAMENTS",
+ "ANNOTATION": "ANNOTATION" } %>
+ ${helpers.gecko_bitflags_conversion(font_variant_alternates_map, 'NS_FONT_VARIANT_ALTERNATES_',
+ 'VariantAlternates', kw_type='u16')}
+
+ impl ToCss for VariantAlternates {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.is_empty() {
return dest.write_str("normal")
}
let mut has_any = false;
macro_rules! write_value {
@@ -1087,40 +1150,40 @@
write_value!(ANNOTATION => "annotation");
debug_assert!(has_any);
Ok(())
}
}
pub mod computed_value {
- pub type T = super::SpecifiedValue;
+ pub type T = super::VariantAlternates;
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T::empty()
}
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
- SpecifiedValue::empty()
+ SpecifiedValue::Value(VariantAlternates::empty())
}
/// normal |
/// [ stylistic(<feature-value-name>) ||
/// historical-forms ||
/// styleset(<feature-value-name> #) ||
/// character-variant(<feature-value-name> #) ||
/// swash(<feature-value-name>) ||
/// ornaments(<feature-value-name>) ||
/// annotation(<feature-value-name>) ]
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- let mut result = SpecifiedValue::empty();
+ let mut result = VariantAlternates::empty();
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
- return Ok(result)
+ return Ok(SpecifiedValue::Value(result))
}
while let Ok(ident) = input.try(|input| input.expect_ident()) {
let flag = match_ignore_ascii_case! { &ident,
"stylistic" => STYLISTIC,
"historical-forms" => HISTORICAL_FORMS,
"styleset" => STYLESET,
"character-variant" => CHARACTER_VARIANT,
@@ -1131,17 +1194,17 @@
};
if result.intersects(flag) {
return Err(())
}
result.insert(flag);
}
if !result.is_empty() {
- Ok(result)
+ Ok(SpecifiedValue::Value(result))
} else {
Err(())
}
}
</%helpers:longhand>
macro_rules! exclusive_value {
(($value:ident, $set:expr) => $ident:ident) => {
@@ -1150,41 +1213,64 @@ macro_rules! exclusive_value {
} else {
$ident
}
}
}
<%helpers:longhand name="font-variant-east-asian" products="gecko" animation_type="none"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian">
+ use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
- use values::computed::ComputedValueAsSpecified;
- impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);
bitflags! {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub flags SpecifiedValue: u16 {
+ pub flags VariantEastAsian: u16 {
const NORMAL = 0,
const JIS78 = 0x01,
const JIS83 = 0x02,
const JIS90 = 0x04,
const JIS04 = 0x08,
const SIMPLIFIED = 0x10,
const TRADITIONAL = 0x20,
const FULL_WIDTH = 0x40,
const PROPORTIONAL_WIDTH = 0x80,
const RUBY = 0x100,
}
}
- impl ToCss for SpecifiedValue {
+
+ #[derive(Debug, Clone, PartialEq)]
+ pub enum SpecifiedValue {
+ Value(VariantEastAsian),
+ System(SystemFont)
+ }
+
+ <%self:simple_system_boilerplate name="font_variant_east_asian"></%self:simple_system_boilerplate>
+
+ // servo_bit: gecko_bit
+ <% font_variant_east_asian_map = { "JIS78": "JIS78",
+ "JIS83": "JIS83",
+ "JIS90": "JIS90",
+ "JIS04": "JIS04",
+ "SIMPLIFIED": "SIMPLIFIED",
+ "TRADITIONAL": "TRADITIONAL",
+ "FULL_WIDTH": "FULL_WIDTH",
+ "PROPORTIONAL_WIDTH": "PROP_WIDTH",
+ "RUBY": "RUBY" } %>
+
+ ${helpers.gecko_bitflags_conversion(font_variant_east_asian_map, 'NS_FONT_VARIANT_EAST_ASIAN_',
+ 'VariantEastAsian', kw_type='u16')}
+
+
+ impl ToCss for VariantEastAsian {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.is_empty() {
return dest.write_str("normal")
}
let mut has_any = false;
macro_rules! write_value {
@@ -1210,37 +1296,37 @@ macro_rules! exclusive_value {
write_value!(RUBY => "ruby");
debug_assert!(has_any);
Ok(())
}
}
pub mod computed_value {
- pub type T = super::SpecifiedValue;
+ pub type T = super::VariantEastAsian;
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T::empty()
}
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
- SpecifiedValue::empty()
+ SpecifiedValue::Value(VariantEastAsian::empty())
}
/// normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]
/// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
/// <east-asian-width-values> = [ full-width | proportional-width ]
<% east_asian_variant_values = "JIS78 | JIS83 | JIS90 | JIS04 | SIMPLIFIED | TRADITIONAL" %>
<% east_asian_width_values = "FULL_WIDTH | PROPORTIONAL_WIDTH" %>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- let mut result = SpecifiedValue::empty();
+ let mut result = VariantEastAsian::empty();
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
- return Ok(result)
+ return Ok(SpecifiedValue::Value(result))
}
while let Ok(ident) = input.try(|input| input.expect_ident()) {
let flag = match_ignore_ascii_case! { &ident,
"jis78" =>
exclusive_value!((result, ${east_asian_variant_values}) => JIS78),
"jis83" =>
exclusive_value!((result, ${east_asian_variant_values}) => JIS83),
@@ -1259,50 +1345,72 @@ macro_rules! exclusive_value {
"ruby" =>
exclusive_value!((result, RUBY) => RUBY),
_ => return Err(()),
};
result.insert(flag);
}
if !result.is_empty() {
- Ok(result)
+ Ok(SpecifiedValue::Value(result))
} else {
Err(())
}
}
</%helpers:longhand>
<%helpers:longhand name="font-variant-ligatures" products="gecko" animation_type="none"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures">
+ use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
- use values::computed::ComputedValueAsSpecified;
- impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);
bitflags! {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub flags SpecifiedValue: u16 {
+ pub flags VariantLigatures: u16 {
const NORMAL = 0,
const NONE = 0x01,
const COMMON_LIGATURES = 0x02,
const NO_COMMON_LIGATURES = 0x04,
const DISCRETIONARY_LIGATURES = 0x08,
const NO_DISCRETIONARY_LIGATURES = 0x10,
const HISTORICAL_LIGATURES = 0x20,
const NO_HISTORICAL_LIGATURES = 0x40,
const CONTEXTUAL = 0x80,
const NO_CONTEXTUAL = 0x100,
}
}
- impl ToCss for SpecifiedValue {
+
+ #[derive(Debug, Clone, PartialEq)]
+ pub enum SpecifiedValue {
+ Value(VariantLigatures),
+ System(SystemFont)
+ }
+
+ <%self:simple_system_boilerplate name="font_variant_ligatures"></%self:simple_system_boilerplate>
+
+ // servo_bit: gecko_bit
+ <% font_variant_ligatures_map = { "NONE": "NONE",
+ "COMMON_LIGATURES": "COMMON",
+ "NO_COMMON_LIGATURES": "NO_COMMON",
+ "DISCRETIONARY_LIGATURES": "DISCRETIONARY",
+ "NO_DISCRETIONARY_LIGATURES": "NO_DISCRETIONARY",
+ "HISTORICAL_LIGATURES": "HISTORICAL",
+ "NO_HISTORICAL_LIGATURES": "NO_HISTORICAL",
+ "CONTEXTUAL": "CONTEXTUAL",
+ "NO_CONTEXTUAL": "NO_CONTEXTUAL" } %>
+
+ ${helpers.gecko_bitflags_conversion(font_variant_ligatures_map, 'NS_FONT_VARIANT_LIGATURES_',
+ 'VariantLigatures', kw_type='u16')}
+
+ impl ToCss for VariantLigatures {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.is_empty() {
return dest.write_str("normal")
}
if self.contains(NONE) {
return dest.write_str("none")
}
@@ -1330,48 +1438,48 @@ macro_rules! exclusive_value {
write_value!(NO_CONTEXTUAL => "no-contextual");
debug_assert!(has_any);
Ok(())
}
}
pub mod computed_value {
- pub type T = super::SpecifiedValue;
+ pub type T = super::VariantLigatures;
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T::empty()
}
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
- SpecifiedValue::empty()
+ SpecifiedValue::Value(VariantLigatures::empty())
}
/// normal | none |
/// [ <common-lig-values> ||
/// <discretionary-lig-values> ||
/// <historical-lig-values> ||
/// <contextual-alt-values> ]
/// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
/// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
/// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
/// <contextual-alt-values> = [ contextual | no-contextual ]
<% common_lig_values = "COMMON_LIGATURES | NO_COMMON_LIGATURES" %>
<% discretionary_lig_values = "DISCRETIONARY_LIGATURES | NO_DISCRETIONARY_LIGATURES" %>
<% historical_lig_values = "HISTORICAL_LIGATURES | NO_HISTORICAL_LIGATURES" %>
<% contextual_alt_values = "CONTEXTUAL | NO_CONTEXTUAL" %>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- let mut result = SpecifiedValue::empty();
+ let mut result = VariantLigatures::empty();
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
- return Ok(result)
+ return Ok(SpecifiedValue::Value(result))
}
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
- return Ok(NONE)
+ return Ok(SpecifiedValue::Value(NONE))
}
while let Ok(ident) = input.try(|input| input.expect_ident()) {
let flag = match_ignore_ascii_case! { &ident,
"common-ligatures" =>
exclusive_value!((result, ${common_lig_values}) => COMMON_LIGATURES),
"no-common-ligatures" =>
exclusive_value!((result, ${common_lig_values}) => NO_COMMON_LIGATURES),
@@ -1388,49 +1496,72 @@ macro_rules! exclusive_value {
"no-contextual" =>
exclusive_value!((result, ${contextual_alt_values}) => NO_CONTEXTUAL),
_ => return Err(()),
};
result.insert(flag);
}
if !result.is_empty() {
- Ok(result)
+ Ok(SpecifiedValue::Value(result))
} else {
Err(())
}
}
</%helpers:longhand>
<%helpers:longhand name="font-variant-numeric" products="gecko" animation_type="none"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric">
+ use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
- use values::computed::ComputedValueAsSpecified;
- impl ComputedValueAsSpecified for SpecifiedValue {}
no_viewport_percentage!(SpecifiedValue);
bitflags! {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub flags SpecifiedValue: u8 {
+ pub flags VariantNumeric: u8 {
const NORMAL = 0,
const LINING_NUMS = 0x01,
const OLDSTYLE_NUMS = 0x02,
const PROPORTIONAL_NUMS = 0x04,
const TABULAR_NUMS = 0x08,
const DIAGONAL_FRACTIONS = 0x10,
const STACKED_FRACTIONS = 0x20,
const SLASHED_ZERO = 0x40,
const ORDINAL = 0x80,
}
}
- impl ToCss for SpecifiedValue {
+
+
+ #[derive(Debug, Clone, PartialEq)]
+ pub enum SpecifiedValue {
+ Value(VariantNumeric),
+ System(SystemFont)
+ }
+
+ <%self:simple_system_boilerplate name="font_variant_numeric"></%self:simple_system_boilerplate>
+
+
+ // servo_bit: gecko_bit
+ <% font_variant_numeric_map = { "LINING_NUMS": "LINING",
+ "OLDSTYLE_NUMS": "OLDSTYLE",
+ "PROPORTIONAL_NUMS": "PROPORTIONAL",
+ "TABULAR_NUMS": "TABULAR",
+ "DIAGONAL_FRACTIONS": "DIAGONAL_FRACTIONS",
+ "STACKED_FRACTIONS": "STACKED_FRACTIONS",
+ "SLASHED_ZERO": "SLASHZERO",
+ "ORDINAL": "ORDINAL" } %>
+
+ ${helpers.gecko_bitflags_conversion(font_variant_numeric_map, 'NS_FONT_VARIANT_NUMERIC_',
+ 'VariantNumeric')}
+
+ impl ToCss for VariantNumeric {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.is_empty() {
return dest.write_str("normal")
}
let mut has_any = false;
macro_rules! write_value {
@@ -1455,44 +1586,44 @@ macro_rules! exclusive_value {
write_value!(ORDINAL => "ordinal");
debug_assert!(has_any);
Ok(())
}
}
pub mod computed_value {
- pub type T = super::SpecifiedValue;
+ pub type T = super::VariantNumeric;
}
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T::empty()
}
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
- SpecifiedValue::empty()
+ SpecifiedValue::Value(VariantNumeric::empty())
}
/// normal |
/// [ <numeric-figure-values> ||
/// <numeric-spacing-values> ||
/// <numeric-fraction-values> ||
/// ordinal ||
/// slashed-zero ]
/// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
/// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
/// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
<% numeric_figure_values = "LINING_NUMS | OLDSTYLE_NUMS" %>
<% numeric_spacing_values = "PROPORTIONAL_NUMS | TABULAR_NUMS" %>
<% numeric_fraction_values = "DIAGONAL_FRACTIONS | STACKED_FRACTIONS" %>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- let mut result = SpecifiedValue::empty();
+ let mut result = VariantNumeric::empty();
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
- return Ok(result)
+ return Ok(SpecifiedValue::Value(result))
}
while let Ok(ident) = input.try(|input| input.expect_ident()) {
let flag = match_ignore_ascii_case! { &ident,
"ordinal" =>
exclusive_value!((result, ORDINAL) => ORDINAL),
"slashed-zero" =>
exclusive_value!((result, SLASHED_ZERO) => SLASHED_ZERO),
@@ -1509,17 +1640,17 @@ macro_rules! exclusive_value {
"stacked-fractions" =>
exclusive_value!((result, ${numeric_fraction_values}) => STACKED_FRACTIONS ),
_ => return Err(()),
};
result.insert(flag);
}
if !result.is_empty() {
- Ok(result)
+ Ok(SpecifiedValue::Value(result))
} else {
Err(())
}
}
</%helpers:longhand>
${helpers.single_keyword_system("font-variant-position",
"normal sub super",
@@ -1636,36 +1767,52 @@ macro_rules! exclusive_value {
input.parse_comma_separated(|i| computed_value::FeatureTagValue::parse(context, i))
.map(computed_value::T::Tag)
}
}
</%helpers:longhand>
<%helpers:longhand name="font-language-override" products="gecko" animation_type="none" extra_prefixes="moz"
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-language-override">
+ use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
use byteorder::{BigEndian, ByteOrder};
use values::HasViewportPercentage;
no_viewport_percentage!(SpecifiedValue);
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Normal,
Override(String),
+ System(SystemFont)
}
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use cssparser;
match *self {
SpecifiedValue::Normal => dest.write_str("normal"),
SpecifiedValue::Override(ref lang) =>
cssparser::serialize_string(lang, dest),
+ SpecifiedValue::System(_) => Ok(())
+ }
+ }
+ }
+
+ impl SpecifiedValue {
+ pub fn system_font(f: SystemFont) -> Self {
+ SpecifiedValue::System(f)
+ }
+ pub fn get_system(&self) -> Option<SystemFont> {
+ if let SpecifiedValue::System(s) = *self {
+ Some(s)
+ } else {
+ None
}
}
}
pub mod computed_value {
use std::{fmt, str};
use style_traits::ToCss;
use byteorder::{BigEndian, ByteOrder};
@@ -1706,31 +1853,36 @@ macro_rules! exclusive_value {
pub fn get_initial_specified_value() -> SpecifiedValue {
SpecifiedValue::Normal
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value(&self, context: &Context) -> computed_value::T {
use std::ascii::AsciiExt;
match *self {
SpecifiedValue::Normal => computed_value::T(0),
SpecifiedValue::Override(ref lang) => {
if lang.is_empty() || lang.len() > 4 || !lang.is_ascii() {
return computed_value::T(0)
}
let mut computed_lang = lang.clone();
while computed_lang.len() < 4 {
computed_lang.push(' ');
}
let bytes = computed_lang.into_bytes();
computed_value::T(BigEndian::read_u32(&bytes))
}
+ SpecifiedValue::System(_) => {
+ <%self:nongecko_unreachable>
+ context.style.cached_system_font.as_ref().unwrap().font_language_override
+ </%self:nongecko_unreachable>
+ }
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
if computed.0 == 0 {
return SpecifiedValue::Normal
}
let mut buf = [0; 4];
@@ -1954,17 +2106,21 @@ macro_rules! exclusive_value {
use std::hash::{Hash, Hasher};
use values::computed::{ToComputedValue, Context};
<%
system_fonts = """caption icon menu message-box small-caption status-bar
-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
- font_kerning font_variant_position""".split()
+ font_kerning font_variant_position font_variant_alternates
+ font_variant_ligatures font_variant_east_asian
+ font_variant_numeric""".split()
+ kw_cast = """font_style font_variant_caps font_stretch
+ font_kerning font_variant_position""".split()
%>
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum SystemFont {
% for font in system_fonts:
${to_camel_case(font)},
% endfor
}
@@ -2020,19 +2176,23 @@ macro_rules! exclusive_value {
};
let ret = ComputedSystemFont {
font_family: longhands::font_family::computed_value::T(family),
font_size: Au(system.size),
font_weight: weight,
font_size_adjust: longhands::font_size_adjust::computed_value::T::from_gecko_adjust(system.sizeAdjust),
% for kwprop in kw_font_props:
${kwprop}: longhands::${kwprop}::computed_value::T::from_gecko_keyword(
- system.${to_camel_case_lower(kwprop.replace('font_', ''))} as u32
+ system.${to_camel_case_lower(kwprop.replace('font_', ''))}
+ % if kwprop in kw_cast:
+ as u32
+ % endif
),
% endfor
+ font_language_override: longhands::font_language_override::computed_value::T(system.languageOverride),
system_font: *self,
};
unsafe { bindings::Gecko_nsFont_Destroy(&mut system); }
ret
}
fn from_computed_value(_: &ComputedSystemFont) -> Self {
unreachable!()