Make font-stretch animatable.

This commit is contained in:
Mantaroh Yoshinaga 2017-05-19 09:02:27 +09:00
parent 0b3fd8de76
commit c71abc0c28
4 changed files with 78 additions and 9 deletions

View file

@ -127,6 +127,15 @@ class Keyword(object):
def maybe_cast(self, type_str): def maybe_cast(self, type_str):
return "as " + type_str if self.needs_cast() else "" return "as " + type_str if self.needs_cast() else ""
def casted_constant_name(self, value, cast_type):
if cast_type is None:
raise TypeError("We should specify the cast_type.")
if self.gecko_enum_prefix is None:
return cast_type.upper() + "_" + self.gecko_constant(value)
else:
return cast_type.upper() + "_" + self.gecko_constant(value).upper().replace("::", "_")
def arg_to_bool(arg): def arg_to_bool(arg):
if isinstance(arg, bool): if isinstance(arg, bool):

View file

@ -274,14 +274,25 @@ def set_gecko_property(ffi_name, expr):
} }
</%def> </%def>
<%def name="impl_keyword_clone(ident, gecko_ffi_name, keyword)"> <%def name="impl_keyword_clone(ident, gecko_ffi_name, keyword, cast_type='u8')">
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T as Keyword; use properties::longhands::${ident}::computed_value::T as Keyword;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts // FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
match ${get_gecko_property(gecko_ffi_name)} ${keyword.maybe_cast("u32")} {
// Some constant macros in the gecko are defined as negative integer(e.g. font-stretch).
// And they are convert to signed integer in Rust bindings. We need to cast then
// as signed type when we have both signed/unsigned integer in order to use them
// as match's arms.
// Also, to use same implementation here we use casted constant if we have only singed values.
% for value in keyword.values_for('gecko'): % for value in keyword.values_for('gecko'):
structs::${keyword.gecko_constant(value)} => Keyword::${to_rust_ident(value)}, const ${keyword.casted_constant_name(value, cast_type)} : ${cast_type} =
structs::${keyword.gecko_constant(value)} as ${cast_type};
% endfor
match ${get_gecko_property(gecko_ffi_name)} as ${cast_type} {
% for value in keyword.values_for('gecko'):
${keyword.casted_constant_name(value, cast_type)} => Keyword::${to_rust_ident(value)},
% endfor % endfor
% if keyword.gecko_inexhaustive: % if keyword.gecko_inexhaustive:
x => panic!("Found unexpected value in style struct for ${ident} property: {:?}", x), x => panic!("Found unexpected value in style struct for ${ident} property: {:?}", x),
@ -334,11 +345,11 @@ fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
} }
</%def> </%def>
<%def name="impl_keyword(ident, gecko_ffi_name, keyword, need_clone, **kwargs)"> <%def name="impl_keyword(ident, gecko_ffi_name, keyword, need_clone, cast_type='u8', **kwargs)">
<%call expr="impl_keyword_setter(ident, gecko_ffi_name, keyword, **kwargs)"></%call> <%call expr="impl_keyword_setter(ident, gecko_ffi_name, keyword, cast_type, **kwargs)"></%call>
<%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call> <%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
%if need_clone: %if need_clone:
<%call expr="impl_keyword_clone(ident, gecko_ffi_name, keyword)"></%call> <%call expr="impl_keyword_clone(ident, gecko_ffi_name, keyword, cast_type)"></%call>
% endif % endif
</%def> </%def>
@ -2010,6 +2021,7 @@ fn static_assert() {
"-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck " + "-moz-grid-group -moz-grid-line -moz-stack -moz-inline-stack -moz-deck " +
"-moz-popup -moz-groupbox", "-moz-popup -moz-groupbox",
gecko_enum_prefix="StyleDisplay", gecko_enum_prefix="StyleDisplay",
gecko_inexhaustive="True",
gecko_strip_moz_prefix=False) %> gecko_strip_moz_prefix=False) %>
pub fn set_display(&mut self, v: longhands::display::computed_value::T) { pub fn set_display(&mut self, v: longhands::display::computed_value::T) {

View file

@ -17,6 +17,7 @@ use properties::{CSSWideKeyword, PropertyDeclaration};
use properties::longhands; use properties::longhands;
use properties::longhands::background_size::computed_value::T as BackgroundSizeList; use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
use properties::longhands::font_weight::computed_value::T as FontWeight; use properties::longhands::font_weight::computed_value::T as FontWeight;
use properties::longhands::font_stretch::computed_value::T as FontStretch;
use properties::longhands::line_height::computed_value::T as LineHeight; use properties::longhands::line_height::computed_value::T as LineHeight;
use properties::longhands::text_shadow::computed_value::T as TextShadowList; use properties::longhands::text_shadow::computed_value::T as TextShadowList;
use properties::longhands::text_shadow::computed_value::TextShadow; use properties::longhands::text_shadow::computed_value::TextShadow;
@ -1360,6 +1361,54 @@ impl Animatable for FontWeight {
} }
} }
/// https://drafts.csswg.org/css-fonts/#font-stretch-prop
impl Animatable for FontStretch {
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
let from = f64::from(*self);
let to = f64::from(*other);
let interpolated_mapped_index = ((from * self_portion + to * other_portion) + 0.5).floor();
Ok(interpolated_mapped_index.into())
}
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
let from = f64::from(*self);
let to = f64::from(*other);
from.compute_distance(&to)
}
}
/// 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 {
ultra_condensed => 1.0,
extra_condensed => 2.0,
condensed => 3.0,
semi_condensed => 4.0,
normal => 5.0,
semi_expanded => 6.0,
expanded => 7.0,
extra_expanded => 8.0,
ultra_expanded => 9.0,
}
}
}
impl Into<FontStretch> for f64 {
fn into(self) -> FontStretch {
use properties::longhands::font_stretch::computed_value::T::*;
debug_assert!(self >= 1.0 && self <= 9.0);
static FONT_STRETCH_ENUM_MAP: [FontStretch; 9] =
[ ultra_condensed, extra_condensed, condensed, semi_condensed, normal,
semi_expanded, expanded, extra_expanded, ultra_expanded ];
FONT_STRETCH_ENUM_MAP[(self - 1.0) as usize]
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-simple-list /// https://drafts.csswg.org/css-transitions/#animtype-simple-list
impl<H: Animatable, V: Animatable> Animatable for generic_position::Position<H, V> { impl<H: Animatable, V: Animatable> Animatable for generic_position::Position<H, V> {
#[inline] #[inline]

View file

@ -1178,7 +1178,6 @@ ${helpers.single_keyword_system("font-variant-caps",
} }
</%helpers:longhand> </%helpers:longhand>
// FIXME: This prop should be animatable
${helpers.single_keyword_system("font-stretch", ${helpers.single_keyword_system("font-stretch",
"normal ultra-condensed extra-condensed condensed \ "normal ultra-condensed extra-condensed condensed \
semi-condensed semi-expanded expanded extra-expanded \ semi-condensed semi-expanded expanded extra-expanded \
@ -1187,14 +1186,14 @@ ${helpers.single_keyword_system("font-stretch",
gecko_constant_prefix="NS_FONT_STRETCH", gecko_constant_prefix="NS_FONT_STRETCH",
cast_type='i16', cast_type='i16',
spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch", spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch",
animation_value_type="none")} animation_value_type="ComputedValue")}
${helpers.single_keyword_system("font-kerning", ${helpers.single_keyword_system("font-kerning",
"auto none normal", "auto none normal",
products="gecko", products="gecko",
gecko_ffi_name="mFont.kerning", gecko_ffi_name="mFont.kerning",
gecko_constant_prefix="NS_FONT_KERNING", gecko_constant_prefix="NS_FONT_KERNING",
spec="https://drafts.csswg.org/css-fonts/#propdef-font-stretch", spec="https://drafts.csswg.org/css-fonts/#propdef-font-kerning",
animation_value_type="none")} animation_value_type="none")}
/// FIXME: Implement proper handling of each values. /// FIXME: Implement proper handling of each values.