mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Implement font-variant shorthand.
This commit is contained in:
parent
1eb9a0865a
commit
24919b3cf8
3 changed files with 100 additions and 23 deletions
|
@ -666,8 +666,6 @@ impl Debug for ${style_struct.gecko_struct_name} {
|
||||||
# Make a list of types we can't auto-generate.
|
# Make a list of types we can't auto-generate.
|
||||||
#
|
#
|
||||||
force_stub = [];
|
force_stub = [];
|
||||||
# These live in an nsFont member in Gecko. Should be straightforward to do manually.
|
|
||||||
force_stub += ["font-variant"]
|
|
||||||
# These have unusual representations in gecko.
|
# These have unusual representations in gecko.
|
||||||
force_stub += ["list-style-type"]
|
force_stub += ["list-style-type"]
|
||||||
|
|
||||||
|
|
|
@ -228,11 +228,6 @@ ${helpers.single_keyword("font-style",
|
||||||
animation_type="none",
|
animation_type="none",
|
||||||
needs_conversion=True)}
|
needs_conversion=True)}
|
||||||
|
|
||||||
${helpers.single_keyword("font-variant",
|
|
||||||
"normal small-caps",
|
|
||||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant",
|
|
||||||
animation_type="none")}
|
|
||||||
|
|
||||||
|
|
||||||
<% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS",
|
<% font_variant_caps_custom_consts= { "small-caps": "SMALLCAPS",
|
||||||
"all-small": "ALLSMALL",
|
"all-small": "ALLSMALL",
|
||||||
|
@ -241,10 +236,10 @@ ${helpers.single_keyword("font-variant",
|
||||||
"titling-caps": "TITLING" } %>
|
"titling-caps": "TITLING" } %>
|
||||||
|
|
||||||
${helpers.single_keyword("font-variant-caps",
|
${helpers.single_keyword("font-variant-caps",
|
||||||
"normal small-caps all-small petite-caps unicase titling-caps",
|
"normal small-caps",
|
||||||
|
extra_gecko_values="all-small petite-caps unicase titling-caps",
|
||||||
gecko_constant_prefix="NS_FONT_VARIANT_CAPS",
|
gecko_constant_prefix="NS_FONT_VARIANT_CAPS",
|
||||||
gecko_ffi_name="mFont.variantCaps",
|
gecko_ffi_name="mFont.variantCaps",
|
||||||
products="gecko",
|
|
||||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps",
|
spec="https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps",
|
||||||
custom_consts=font_variant_caps_custom_consts,
|
custom_consts=font_variant_caps_custom_consts,
|
||||||
animation_type="none")}
|
animation_type="none")}
|
||||||
|
|
|
@ -5,26 +5,36 @@
|
||||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||||
|
|
||||||
<%helpers:shorthand name="font"
|
<%helpers:shorthand name="font"
|
||||||
sub_properties="font-style font-variant font-weight font-stretch
|
sub_properties="font-style font-variant-caps font-weight font-stretch
|
||||||
font-size line-height font-family
|
font-size line-height font-family
|
||||||
${'font-size-adjust' if product == 'gecko' or data.testing else ''}
|
${'font-size-adjust' if product == 'gecko' or data.testing else ''}
|
||||||
${'font-kerning' if product == 'gecko' or data.testing else ''}
|
${'font-kerning' if product == 'gecko' or data.testing else ''}
|
||||||
${'font-variant-caps' if product == 'gecko' or data.testing else ''}
|
${'font-variant-alternates' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-east-asian' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-ligatures' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-numeric' if product == 'gecko' or data.testing else ''}
|
||||||
${'font-variant-position' if product == 'gecko' or data.testing else ''}
|
${'font-variant-position' if product == 'gecko' or data.testing else ''}
|
||||||
${'font-language-override' if product == 'gecko' or data.testing else ''}"
|
${'font-language-override' if product == 'gecko' or data.testing else ''}"
|
||||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
||||||
use properties::longhands::{font_style, font_variant, font_weight, font_stretch};
|
use properties::longhands::{font_style, font_variant_caps, font_weight, font_stretch};
|
||||||
use properties::longhands::{font_size, line_height};
|
use properties::longhands::{font_size, line_height};
|
||||||
|
<%
|
||||||
|
gecko_sub_properties = "kerning language_override size_adjust \
|
||||||
|
variant_alternates variant_east_asian \
|
||||||
|
variant_ligatures variant_numeric \
|
||||||
|
variant_position".split()
|
||||||
|
%>
|
||||||
% if product == "gecko" or data.testing:
|
% if product == "gecko" or data.testing:
|
||||||
use properties::longhands::{font_size_adjust, font_kerning, font_variant_caps, font_variant_position,
|
% for prop in gecko_sub_properties:
|
||||||
font_language_override};
|
use properties::longhands::font_${prop};
|
||||||
|
% endfor
|
||||||
% endif
|
% endif
|
||||||
use properties::longhands::font_family::SpecifiedValue as FontFamily;
|
use properties::longhands::font_family::SpecifiedValue as FontFamily;
|
||||||
|
|
||||||
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||||
let mut nb_normals = 0;
|
let mut nb_normals = 0;
|
||||||
let mut style = None;
|
let mut style = None;
|
||||||
let mut variant = None;
|
let mut variant_caps = None;
|
||||||
let mut weight = None;
|
let mut weight = None;
|
||||||
let mut stretch = None;
|
let mut stretch = None;
|
||||||
let size;
|
let size;
|
||||||
|
@ -48,9 +58,9 @@
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if variant.is_none() {
|
if variant_caps.is_none() {
|
||||||
if let Ok(value) = input.try(|input| font_variant::parse(context, input)) {
|
if let Ok(value) = input.try(|input| font_variant_caps::parse(context, input)) {
|
||||||
variant = Some(value);
|
variant_caps = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +77,8 @@
|
||||||
fn count<T>(opt: &Option<T>) -> u8 {
|
fn count<T>(opt: &Option<T>) -> u8 {
|
||||||
if opt.is_some() { 1 } else { 0 }
|
if opt.is_some() { 1 } else { 0 }
|
||||||
}
|
}
|
||||||
if size.is_none() || (count(&style) + count(&weight) + count(&variant) + count(&stretch) + nb_normals) > 4 {
|
if size.is_none() ||
|
||||||
|
(count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||||
|
@ -77,13 +88,13 @@
|
||||||
};
|
};
|
||||||
let family = FontFamily::parse(input)?;
|
let family = FontFamily::parse(input)?;
|
||||||
Ok(Longhands {
|
Ok(Longhands {
|
||||||
% for name in "style variant weight stretch size".split():
|
% for name in "style variant_caps weight stretch size".split():
|
||||||
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
||||||
% endfor
|
% endfor
|
||||||
line_height: unwrap_or_initial!(line_height),
|
line_height: unwrap_or_initial!(line_height),
|
||||||
font_family: family,
|
font_family: family,
|
||||||
% if product == "gecko" or data.testing:
|
% if product == "gecko" or data.testing:
|
||||||
% for name in "size_adjust kerning variant_caps variant_position language_override".split():
|
% for name in gecko_sub_properties:
|
||||||
font_${name}: font_${name}::get_initial_specified_value(),
|
font_${name}: font_${name}::get_initial_specified_value(),
|
||||||
% endfor
|
% endfor
|
||||||
% endif
|
% endif
|
||||||
|
@ -95,14 +106,14 @@
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
|
||||||
% if product == "gecko" or data.testing:
|
% if product == "gecko" or data.testing:
|
||||||
% for name in "size_adjust kerning variant_caps variant_position language_override".split():
|
% for name in gecko_sub_properties:
|
||||||
if self.font_${name} != &font_${name}::get_initial_specified_value() {
|
if self.font_${name} != &font_${name}::get_initial_specified_value() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% for name in "style variant weight stretch".split():
|
% for name in "style variant_caps weight stretch".split():
|
||||||
self.font_${name}.to_css(dest)?;
|
self.font_${name}.to_css(dest)?;
|
||||||
dest.write_str(" ")?;
|
dest.write_str(" ")?;
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -124,3 +135,76 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
||||||
|
<%helpers:shorthand name="font-variant"
|
||||||
|
sub_properties="font-variant-caps
|
||||||
|
${'font-variant-alternates' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-east-asian' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-ligatures' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-numeric' if product == 'gecko' or data.testing else ''}
|
||||||
|
${'font-variant-position' if product == 'gecko' or data.testing else ''}"
|
||||||
|
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-variant">
|
||||||
|
use properties::longhands::font_variant_caps;
|
||||||
|
<% gecko_sub_properties = "alternates east_asian ligatures numeric position".split() %>
|
||||||
|
% if product == "gecko" or data.testing:
|
||||||
|
% for prop in gecko_sub_properties:
|
||||||
|
use properties::longhands::font_variant_${prop};
|
||||||
|
% endfor
|
||||||
|
% endif
|
||||||
|
|
||||||
|
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||||
|
let mut nb_normals = 0;
|
||||||
|
let mut caps = None;
|
||||||
|
loop {
|
||||||
|
// Special-case 'normal' because it is valid in each of
|
||||||
|
// all sub properties.
|
||||||
|
// Leaves the values to None, 'normal' is the initial value for each of them.
|
||||||
|
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||||
|
nb_normals += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if caps.is_none() {
|
||||||
|
if let Ok(value) = input.try(|input| font_variant_caps::parse(context, input)) {
|
||||||
|
caps = Some(value);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn count<T>(opt: &Option<T>) -> u8 {
|
||||||
|
if opt.is_some() { 1 } else { 0 }
|
||||||
|
}
|
||||||
|
let count = count(&caps) + nb_normals;
|
||||||
|
if count == 0 || count > 1 {
|
||||||
|
return Err(())
|
||||||
|
}
|
||||||
|
Ok(Longhands {
|
||||||
|
font_variant_caps: unwrap_or_initial!(font_variant_caps, caps),
|
||||||
|
// FIXME: Bug 1356134 - parse all sub properties.
|
||||||
|
% if product == "gecko" or data.testing:
|
||||||
|
% for name in gecko_sub_properties:
|
||||||
|
font_variant_${name}: font_variant_${name}::get_initial_specified_value(),
|
||||||
|
% endfor
|
||||||
|
% endif
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
|
||||||
|
% if product == "gecko" or data.testing:
|
||||||
|
% for name in gecko_sub_properties:
|
||||||
|
// FIXME: Bug 1356134 - handle all sub properties.
|
||||||
|
if self.font_variant_${name} != &font_variant_${name}::get_initial_specified_value() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
% endif
|
||||||
|
|
||||||
|
self.font_variant_caps.to_css(dest)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue