Introduce safer layer of sugar for nsStyleUnion

This commit is contained in:
Manish Goregaokar 2016-07-20 16:32:21 +05:30
parent cb05c969c8
commit 6e9a68a0db
No known key found for this signature in database
GPG key ID: 3BBF4D3E2EF79F98
4 changed files with 365 additions and 341 deletions

View file

@ -6,291 +6,123 @@
use app_units::Au;
use cssparser::RGBA;
use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit};
use gecko_bindings::structs::nsStyleCoord;
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataValues};
use std::cmp::max;
use values::computed::Angle;
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
pub trait StyleCoordHelpers {
fn copy_from(&mut self, other: &Self);
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T);
fn set_auto(&mut self);
fn is_auto(&self) -> bool;
fn set_normal(&mut self);
fn is_normal(&self) -> bool;
fn set_coord(&mut self, val: Au);
fn is_coord(&self) -> bool;
fn get_coord(&self) -> Au;
fn set_int(&mut self, val: i32);
fn is_int(&self) -> bool;
fn get_int(&self) -> i32;
fn set_enum(&mut self, val: i32);
fn is_enum(&self) -> bool;
fn get_enum(&self) -> i32;
fn set_percent(&mut self, val: f32);
fn is_percent(&self) -> bool;
fn get_percent(&self) -> f32;
fn set_factor(&mut self, val: f32);
fn is_factor(&self) -> bool;
fn get_factor(&self) -> f32;
}
impl StyleCoordHelpers for nsStyleCoord {
#[inline]
fn copy_from(&mut self, other: &Self) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = other.mUnit;
self.mValue = other.mValue;
unsafe { self.addref_if_calc(); }
self.data().copy_from(&other.data())
}
#[inline]
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
val.to_gecko_style_coord(&mut self.mUnit, &mut self.mValue);
}
#[inline]
fn set_auto(&mut self) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Auto;
unsafe { *self.mValue.mInt.as_mut() = 0; }
}
#[inline]
fn is_auto(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Auto
}
#[inline]
fn set_normal(&mut self) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Normal;
unsafe { *self.mValue.mInt.as_mut() = 0; }
}
#[inline]
fn is_normal(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Normal
}
#[inline]
fn set_coord(&mut self, val: Au) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Coord;
unsafe { *self.mValue.mInt.as_mut() = val.0; }
}
#[inline]
fn is_coord(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Coord
}
#[inline]
fn get_coord(&self) -> Au {
debug_assert!(self.is_coord());
Au(unsafe { *self.mValue.mInt.as_ref() })
}
#[inline]
fn set_int(&mut self, val: i32) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Integer;
unsafe { *self.mValue.mInt.as_mut() = val; }
}
#[inline]
fn is_int(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Integer
}
#[inline]
fn get_int(&self) -> i32 {
debug_assert!(self.is_int());
unsafe { *self.mValue.mInt.as_ref() }
}
#[inline]
fn set_enum(&mut self, val: i32) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Enumerated;
unsafe { *self.mValue.mInt.as_mut() = val; }
}
#[inline]
fn is_enum(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Enumerated
}
#[inline]
fn get_enum(&self) -> i32 {
debug_assert!(self.is_enum());
unsafe { *self.mValue.mInt.as_ref() }
}
#[inline]
fn set_percent(&mut self, val: f32) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Percent;
unsafe { *self.mValue.mFloat.as_mut() = val; }
}
#[inline]
fn is_percent(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Percent
}
#[inline]
fn get_percent(&self) -> f32 {
debug_assert!(self.is_percent());
unsafe { *self.mValue.mFloat.as_ref() }
}
#[inline]
fn set_factor(&mut self, val: f32) {
unsafe { self.mValue.reset(&mut self.mUnit) };
self.mUnit = nsStyleUnit::eStyleUnit_Factor;
unsafe { *self.mValue.mFloat.as_mut() = val; }
}
#[inline]
fn is_factor(&self) -> bool {
self.mUnit == nsStyleUnit::eStyleUnit_Factor
}
#[inline]
fn get_factor(&self) -> f32 {
debug_assert!(self.is_factor());
unsafe { *self.mValue.mFloat.as_ref() }
val.to_gecko_style_coord(&mut self.data());
}
}
pub trait GeckoStyleCoordConvertible : Sized {
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion);
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self>;
fn to_gecko_style_coord(&self, coord: &mut CoordData);
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self>;
}
impl GeckoStyleCoordConvertible for LengthOrPercentage {
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
unsafe { union.reset(unit) };
match *self {
LengthOrPercentage::Length(au) => {
*unit = nsStyleUnit::eStyleUnit_Coord;
unsafe { *union.mInt.as_mut() = au.0; }
},
LengthOrPercentage::Percentage(p) => {
*unit = nsStyleUnit::eStyleUnit_Percent;
unsafe { *union.mFloat.as_mut() = p; }
},
LengthOrPercentage::Calc(calc) => unsafe { union.set_calc_value(unit, calc.into()) },
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
let value = match *self {
LengthOrPercentage::Length(au) => CoordDataValues::Coord(au.0),
LengthOrPercentage::Percentage(p) => CoordDataValues::Percent(p),
LengthOrPercentage::Calc(calc) => CoordDataValues::Calc(calc.into()),
};
coord.set_enum(value);
}
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
match *unit {
nsStyleUnit::eStyleUnit_Coord
=> Some(LengthOrPercentage::Length(Au(unsafe { *union.mInt.as_ref() }))),
nsStyleUnit::eStyleUnit_Percent
=> Some(LengthOrPercentage::Percentage(unsafe { *union.mFloat.as_ref() })),
nsStyleUnit::eStyleUnit_Calc
=> Some(LengthOrPercentage::Calc(unsafe { union.get_calc().into() })),
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
match coord.as_enum() {
CoordDataValues::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
CoordDataValues::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
CoordDataValues::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
_ => None,
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
unsafe { union.reset(unit) };
match *self {
LengthOrPercentageOrAuto::Length(au) => {
*unit = nsStyleUnit::eStyleUnit_Coord;
unsafe { *union.mInt.as_mut() = au.0; }
},
LengthOrPercentageOrAuto::Percentage(p) => {
*unit = nsStyleUnit::eStyleUnit_Percent;
unsafe { *union.mFloat.as_mut() = p; }
},
LengthOrPercentageOrAuto::Auto => {
*unit = nsStyleUnit::eStyleUnit_Auto;
unsafe { *union.mInt.as_mut() = 0; }
},
LengthOrPercentageOrAuto::Calc(calc) => unsafe { union.set_calc_value(unit, calc.into()) },
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
let value = match *self {
LengthOrPercentageOrAuto::Length(au) => CoordDataValues::Coord(au.0),
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValues::Percent(p),
LengthOrPercentageOrAuto::Auto => CoordDataValues::Auto,
LengthOrPercentageOrAuto::Calc(calc) => CoordDataValues::Calc(calc.into()),
};
coord.set_enum(value);
}
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
match *unit {
nsStyleUnit::eStyleUnit_Auto
=> Some(LengthOrPercentageOrAuto::Auto),
nsStyleUnit::eStyleUnit_Coord
=> Some(LengthOrPercentageOrAuto::Length(Au(unsafe { *union.mInt.as_ref() }))),
nsStyleUnit::eStyleUnit_Percent
=> Some(LengthOrPercentageOrAuto::Percentage(unsafe { *union.mFloat.as_ref() })),
nsStyleUnit::eStyleUnit_Calc
=> Some(LengthOrPercentageOrAuto::Calc(unsafe { union.get_calc().into() })),
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
match coord.as_enum() {
CoordDataValues::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
CoordDataValues::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
CoordDataValues::Auto => Some(LengthOrPercentageOrAuto::Auto),
CoordDataValues::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
_ => None,
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
unsafe { union.reset(unit) };
match *self {
LengthOrPercentageOrNone::Length(au) => {
*unit = nsStyleUnit::eStyleUnit_Coord;
unsafe { *union.mInt.as_mut() = au.0; }
},
LengthOrPercentageOrNone::Percentage(p) => {
*unit = nsStyleUnit::eStyleUnit_Percent;
unsafe { *union.mFloat.as_mut() = p; }
},
LengthOrPercentageOrNone::None => {
*unit = nsStyleUnit::eStyleUnit_None;
unsafe { *union.mInt.as_mut() = 0; }
},
LengthOrPercentageOrNone::Calc(calc) => unsafe { union.set_calc_value(unit, calc.into()) },
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
let value = match *self {
LengthOrPercentageOrNone::Length(au) => CoordDataValues::Coord(au.0),
LengthOrPercentageOrNone::Percentage(p) => CoordDataValues::Percent(p),
LengthOrPercentageOrNone::None => CoordDataValues::None,
LengthOrPercentageOrNone::Calc(calc) => CoordDataValues::Calc(calc.into()),
};
coord.set_enum(value);
}
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
match *unit {
nsStyleUnit::eStyleUnit_None
=> Some(LengthOrPercentageOrNone::None),
nsStyleUnit::eStyleUnit_Coord
=> Some(LengthOrPercentageOrNone::Length(Au(unsafe { *union.mInt.as_ref() }))),
nsStyleUnit::eStyleUnit_Percent
=> Some(LengthOrPercentageOrNone::Percentage(unsafe { *union.mFloat.as_ref() })),
nsStyleUnit::eStyleUnit_Calc
=> Some(LengthOrPercentageOrNone::Calc(unsafe { union.get_calc().into() })),
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
match coord.as_enum() {
CoordDataValues::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
CoordDataValues::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
CoordDataValues::None => Some(LengthOrPercentageOrNone::None),
CoordDataValues::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
_ => None,
}
}
}
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) {
unsafe { union.reset(unit) };
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
if let Some(ref me) = *self {
me.to_gecko_style_coord(unit, union);
me.to_gecko_style_coord(coord);
} else {
*unit = nsStyleUnit::eStyleUnit_None;
unsafe { *union.mInt.as_mut() = 0; }
coord.set_enum(CoordDataValues::None);
}
}
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
Some(T::from_gecko_style_coord(unit, union))
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
Some(T::from_gecko_style_coord(coord))
}
}
impl GeckoStyleCoordConvertible for Angle {
fn to_gecko_style_coord(&self,
unit: &mut nsStyleUnit,
union: &mut nsStyleUnion) {
unsafe { union.reset(unit) };
*unit = nsStyleUnit::eStyleUnit_Radian;
unsafe { *union.mFloat.as_mut() = self.radians() };
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
coord.set_enum(CoordDataValues::Radian(self.radians()))
}
fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option<Self> {
if *unit == nsStyleUnit::eStyleUnit_Radian {
Some(Angle::from_radians(unsafe { *union.mFloat.as_ref() }))
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
if let CoordDataValues::Radian(r) = coord.as_enum() {
Some(Angle::from_radians(r))
// XXXManishearth should this handle Degree too?
} else {
None
}

View file

@ -26,6 +26,7 @@ use gecko_bindings::bindings::{Gecko_FontFamilyList_AppendGeneric, Gecko_FontFam
use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer};
use gecko_bindings::bindings;
use gecko_bindings::structs;
use gecko_bindings::sugar::ns_style_coord::CoordDataValues;
use gecko_glue::ArcHelpers;
use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba};
use gecko_values::convert_rgba_to_nscolor;
@ -325,67 +326,65 @@ def set_gecko_property(ffi_name, expr):
% endif
</%def>
<%def name="impl_split_style_coord(ident, unit_ffi_name, union_ffi_name, need_clone=False)">
<%def name="impl_split_style_coord(ident, gecko_ffi_name, index, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
v.to_gecko_style_coord(&mut self.gecko.${unit_ffi_name},
&mut self.gecko.${union_ffi_name});
v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${index}));
}
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
unsafe { self.gecko.${union_ffi_name}.reset(&mut self.gecko.${unit_ffi_name}) };
self.gecko.${unit_ffi_name} = other.gecko.${unit_ffi_name};
self.gecko.${union_ffi_name} = other.gecko.${union_ffi_name};
unsafe { self.gecko.${union_ffi_name}.addref_if_calc(&self.gecko.${unit_ffi_name}) };
self.gecko.${gecko_ffi_name}.data_at(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index}));
}
% if need_clone:
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
T::from_gecko_style_coord(&self.gecko.${unit_ffi_name},
&self.gecko.${union_ffi_name})
T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data_at(${index}))
.expect("clone for ${ident} failed")
}
% endif
</%def>
<%def name="impl_style_coord(ident, gecko_ffi_name, need_clone=False)">
${impl_split_style_coord(ident,
"%s.mUnit" % gecko_ffi_name,
"%s.mValue" % gecko_ffi_name,
need_clone=need_clone)}
</%def>
<%def name="impl_corner_style_coord(ident, x_unit_ffi_name, x_union_ffi_name, \
y_unit_ffi_name, y_union_ffi_name, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
v.0.width.to_gecko_style_coord(&mut self.gecko.${x_unit_ffi_name},
&mut self.gecko.${x_union_ffi_name});
v.0.height.to_gecko_style_coord(&mut self.gecko.${y_unit_ffi_name},
&mut self.gecko.${y_union_ffi_name});
v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data());
}
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
unsafe { self.gecko.${x_union_ffi_name}.reset(&mut self.gecko.${x_unit_ffi_name}) };
unsafe { self.gecko.${y_union_ffi_name}.reset(&mut self.gecko.${y_unit_ffi_name}) };
self.gecko.${x_unit_ffi_name} = other.gecko.${x_unit_ffi_name};
self.gecko.${x_union_ffi_name} = other.gecko.${x_union_ffi_name};
self.gecko.${y_unit_ffi_name} = other.gecko.${y_unit_ffi_name};
self.gecko.${y_union_ffi_name} = other.gecko.${y_union_ffi_name};
unsafe { self.gecko.${x_union_ffi_name}.addref_if_calc(&self.gecko.${x_unit_ffi_name}) };
unsafe { self.gecko.${y_union_ffi_name}.addref_if_calc(&self.gecko.${y_unit_ffi_name}) };
self.gecko.${gecko_ffi_name}.data().copy_from(&other.gecko.${gecko_ffi_name}.data());
}
% if need_clone:
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data())
.expect("clone for ${ident} failed")
}
% endif
</%def>
<%def name="impl_corner_style_coord(ident, gecko_ffi_name, x_index, y_index, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
v.0.width.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${x_index}));
v.0.width.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${y_index}));
}
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
self.gecko.${gecko_ffi_name}.data_at(${x_index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${x_index}));
self.gecko.${gecko_ffi_name}.data_at(${x_index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${y_index}));
}
% if need_clone:
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
use euclid::Size2D;
let width = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${x_unit_ffi_name},
&self.gecko.${x_union_ffi_name})
let width = GeckoStyleCoordConvertible::from_gecko_style_coord(
&self.gecko.${gecko_ffi_name}.data_at(${x_index}))
.expect("Failed to clone ${ident}");
let height = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${y_unit_ffi_name},
&self.gecko.${y_union_ffi_name})
let height = GeckoStyleCoordConvertible::from_gecko_style_coord(
&self.gecko.${gecko_ffi_name}.data_at(${y_index}))
.expect("Failed to clone ${ident}");
T(Size2D::new(width, height))
}
@ -602,10 +601,9 @@ fn static_assert() {
% for corner in CORNERS:
<% impl_corner_style_coord("border_%s_radius" % corner.ident,
"mBorderRadius.mUnits[%s]" % corner.x_index,
"mBorderRadius.mValues[%s]" % corner.x_index,
"mBorderRadius.mUnits[%s]" % corner.y_index,
"mBorderRadius.mValues[%s]" % corner.y_index,
"mBorderRadius",
corner.x_index,
corner.y_index,
need_clone=True) %>
% endfor
</%self:impl_trait>
@ -616,8 +614,8 @@ fn static_assert() {
% for side in SIDES:
<% impl_split_style_coord("margin_%s" % side.ident,
"mMargin.mUnits[%s]" % side.index,
"mMargin.mValues[%s]" % side.index,
"mMargin",
side.index,
need_clone=True) %>
% endfor
</%self:impl_trait>
@ -628,8 +626,8 @@ fn static_assert() {
% for side in SIDES:
<% impl_split_style_coord("padding_%s" % side.ident,
"mPadding.mUnits[%s]" % side.index,
"mPadding.mValues[%s]" % side.index,
"mPadding",
side.index,
need_clone=True) %>
% endfor
</%self:impl_trait>
@ -640,16 +638,16 @@ fn static_assert() {
% for side in SIDES:
<% impl_split_style_coord("%s" % side.ident,
"mOffset.mUnits[%s]" % side.index,
"mOffset.mValues[%s]" % side.index,
"mOffset",
side.index,
need_clone=True) %>
% endfor
pub fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
use properties::longhands::z_index::computed_value::T;
match v {
T::Auto => self.gecko.mZIndex.set_auto(),
T::Number(n) => self.gecko.mZIndex.set_int(n),
T::Auto => self.gecko.mZIndex.data().set_enum(CoordDataValues::Auto),
T::Number(n) => self.gecko.mZIndex.data().set_enum(CoordDataValues::Integer(n)),
}
}
@ -664,13 +662,14 @@ fn static_assert() {
pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
use properties::longhands::z_index::computed_value::T;
if self.gecko.mZIndex.is_auto() {
return T::Auto;
return match self.gecko.mZIndex.data().as_enum() {
CoordDataValues::Auto => T::Auto,
CoordDataValues::Integer(n) => T::Number(n),
_ => {
debug_assert!(false);
T::Number(0)
}
}
debug_assert!(self.gecko.mZIndex.is_int());
T::Number(self.gecko.mZIndex.get_int())
}
pub fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) {
@ -702,10 +701,9 @@ fn static_assert() {
% for corner in CORNERS:
<% impl_corner_style_coord("_moz_outline_radius_%s" % corner.ident.replace("_", ""),
"mOutlineRadius.mUnits[%s]" % corner.x_index,
"mOutlineRadius.mValues[%s]" % corner.x_index,
"mOutlineRadius.mUnits[%s]" % corner.y_index,
"mOutlineRadius.mValues[%s]" % corner.y_index) %>
"mOutlineRadius",
corner.x_index,
corner.y_index) %>
% endfor
pub fn outline_has_nonzero_width(&self) -> bool {
@ -826,7 +824,8 @@ fn static_assert() {
match v {
% for value in keyword.values_for('gecko'):
T::${to_rust_ident(value)} =>
self.gecko.mVerticalAlign.set_enum(structs::${keyword.gecko_constant(value)} as i32),
self.gecko.mVerticalAlign.data().set_enum(
CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)})),
% endfor
T::LengthOrPercentage(v) => self.gecko.mVerticalAlign.set(v),
}
@ -836,19 +835,17 @@ fn static_assert() {
use properties::longhands::vertical_align::computed_value::T;
use values::computed::LengthOrPercentage;
if self.gecko.mVerticalAlign.is_enum() {
match self.gecko.mVerticalAlign.get_enum() as u32 {
% for value in keyword.values_for('gecko'):
structs::${keyword.gecko_constant(value)}
=> T::${to_rust_ident(value)},
% endfor
_ => panic!("Unexpected enum variant for vertical-align"),
}
} else {
let v = LengthOrPercentage::from_gecko_style_coord(&self.gecko.mVerticalAlign.mUnit,
&self.gecko.mVerticalAlign.mValue)
.expect("Expected length or percentage for vertical-align");
T::LengthOrPercentage(v)
let data = self.gecko.mVerticalAlign.data();
match data.as_enum() {
% for value in keyword.values_for('gecko'):
CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)}) => T::${to_rust_ident(value)},
% endfor
CoordDataValues::Enumerated(_) => panic!("Unexpected enum variant for vertical-align"),
_ => {
let v = LengthOrPercentage::from_gecko_style_coord(&data)
.expect("Expected length or percentage for vertical-align");
T::LengthOrPercentage(v)
}
}
}
@ -1132,29 +1129,29 @@ fn static_assert() {
pub fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
use properties::longhands::line_height::computed_value::T;
// FIXME: Align binary representations and ditch |match| for cast + static_asserts
match v {
T::Normal => self.gecko.mLineHeight.set_normal(),
T::Length(val) => self.gecko.mLineHeight.set_coord(val),
T::Number(val) => self.gecko.mLineHeight.set_factor(val),
let en = match v {
T::Normal => CoordDataValues::Normal,
T::Length(val) => CoordDataValues::Coord(val.0),
T::Number(val) => CoordDataValues::Factor(val),
T::MozBlockHeight =>
self.gecko.mLineHeight.set_enum(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT as i32),
}
CoordDataValues::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
};
self.gecko.mLineHeight.data().set_enum(en);
}
pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
use properties::longhands::line_height::computed_value::T;
if self.gecko.mLineHeight.is_normal() {
return T::Normal;
return match self.gecko.mLineHeight.data().as_enum() {
CoordDataValues::Normal => T::Normal,
CoordDataValues::Coord(coord) => T::Length(Au(coord)),
CoordDataValues::Factor(n) => T::Number(n),
CoordDataValues::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
T::MozBlockHeight,
_ => {
debug_assert!(false);
T::MozBlockHeight
}
}
if self.gecko.mLineHeight.is_coord() {
return T::Length(self.gecko.mLineHeight.get_coord());
}
if self.gecko.mLineHeight.is_factor() {
return T::Number(self.gecko.mLineHeight.get_factor());
}
debug_assert!(self.gecko.mLineHeight.get_enum() == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT as i32);
T::MozBlockHeight
}
<%call expr="impl_coord_copy('line_height', 'mLineHeight')"></%call>
@ -1283,8 +1280,8 @@ fn static_assert() {
pub fn set_column_width(&mut self, v: longhands::column_width::computed_value::T) {
match v.0 {
Some(au) => self.gecko.mColumnWidth.set_coord(au),
None => self.gecko.mColumnWidth.set_auto(),
Some(au) => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Coord(au.0)),
None => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Auto),
}
}