mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Make nsStyleUnion sugar use traits
This commit is contained in:
parent
6e9a68a0db
commit
73d7db0d5e
4 changed files with 326 additions and 241 deletions
|
@ -7,120 +7,114 @@
|
|||
use app_units::Au;
|
||||
use cssparser::RGBA;
|
||||
use gecko_bindings::structs::nsStyleCoord;
|
||||
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataValues};
|
||||
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
|
||||
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);
|
||||
}
|
||||
|
||||
impl StyleCoordHelpers for nsStyleCoord {
|
||||
#[inline]
|
||||
fn copy_from(&mut self, other: &Self) {
|
||||
self.data().copy_from(&other.data())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
|
||||
val.to_gecko_style_coord(&mut self.data());
|
||||
val.to_gecko_style_coord(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait GeckoStyleCoordConvertible : Sized {
|
||||
fn to_gecko_style_coord(&self, coord: &mut CoordData);
|
||||
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self>;
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T);
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for LengthOrPercentage {
|
||||
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
let value = match *self {
|
||||
LengthOrPercentage::Length(au) => CoordDataValues::Coord(au.0),
|
||||
LengthOrPercentage::Percentage(p) => CoordDataValues::Percent(p),
|
||||
LengthOrPercentage::Calc(calc) => CoordDataValues::Calc(calc.into()),
|
||||
LengthOrPercentage::Length(au) => CoordDataValue::Coord(au.0),
|
||||
LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p),
|
||||
LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()),
|
||||
};
|
||||
coord.set_enum(value);
|
||||
coord.set_value(value);
|
||||
}
|
||||
|
||||
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())),
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
|
||||
CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
|
||||
CoordDataValue::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
|
||||
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
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()),
|
||||
LengthOrPercentageOrAuto::Length(au) => CoordDataValue::Coord(au.0),
|
||||
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p),
|
||||
LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto,
|
||||
LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()),
|
||||
};
|
||||
coord.set_enum(value);
|
||||
coord.set_value(value);
|
||||
}
|
||||
|
||||
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())),
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
|
||||
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
|
||||
CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto),
|
||||
CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
|
||||
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
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()),
|
||||
LengthOrPercentageOrNone::Length(au) => CoordDataValue::Coord(au.0),
|
||||
LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p),
|
||||
LengthOrPercentageOrNone::None => CoordDataValue::None,
|
||||
LengthOrPercentageOrNone::Calc(calc) => CoordDataValue::Calc(calc.into()),
|
||||
};
|
||||
coord.set_enum(value);
|
||||
coord.set_value(value);
|
||||
}
|
||||
|
||||
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())),
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
match coord.as_value() {
|
||||
CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
|
||||
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
|
||||
CoordDataValue::None => Some(LengthOrPercentageOrNone::None),
|
||||
CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
|
||||
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
|
||||
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
|
||||
if let Some(ref me) = *self {
|
||||
me.to_gecko_style_coord(coord);
|
||||
} else {
|
||||
coord.set_enum(CoordDataValues::None);
|
||||
coord.set_value(CoordDataValue::None);
|
||||
}
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
|
||||
fn from_gecko_style_coord<U: CoordData>(coord: &U) -> Option<Self> {
|
||||
Some(T::from_gecko_style_coord(coord))
|
||||
}
|
||||
}
|
||||
|
||||
impl GeckoStyleCoordConvertible for Angle {
|
||||
fn to_gecko_style_coord(&self, coord: &mut CoordData) {
|
||||
coord.set_enum(CoordDataValues::Radian(self.radians()))
|
||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
||||
coord.set_value(CoordDataValue::Radian(self.radians()))
|
||||
}
|
||||
|
||||
fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
|
||||
if let CoordDataValues::Radian(r) = coord.as_enum() {
|
||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
||||
if let CoordDataValue::Radian(r) = coord.as_value() {
|
||||
Some(Angle::from_radians(r))
|
||||
// XXXManishearth should this handle Degree too?
|
||||
} else {
|
||||
|
|
|
@ -26,7 +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_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
|
||||
use gecko_glue::ArcHelpers;
|
||||
use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba};
|
||||
use gecko_values::convert_rgba_to_nscolor;
|
||||
|
@ -329,11 +329,11 @@ def set_gecko_property(ffi_name, expr):
|
|||
<%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.${gecko_ffi_name}.data_at(${index}));
|
||||
v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${index}));
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
self.gecko.${gecko_ffi_name}.data_at(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index}));
|
||||
self.gecko.${gecko_ffi_name}.data_at_mut(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index}));
|
||||
}
|
||||
% if need_clone:
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -348,17 +348,17 @@ def set_gecko_property(ffi_name, expr):
|
|||
<%def name="impl_style_coord(ident, gecko_ffi_name, 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.${gecko_ffi_name}.data());
|
||||
v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name});
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
pub fn copy_${ident}_from(&mut self, other: &Self) {
|
||||
self.gecko.${gecko_ffi_name}.data().copy_from(&other.gecko.${gecko_ffi_name}.data());
|
||||
self.gecko.${gecko_ffi_name}.copy_from(&other.gecko.${gecko_ffi_name});
|
||||
}
|
||||
% 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())
|
||||
T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name})
|
||||
.expect("clone for ${ident} failed")
|
||||
}
|
||||
% endif
|
||||
|
@ -367,13 +367,15 @@ def set_gecko_property(ffi_name, expr):
|
|||
<%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}));
|
||||
v.0.width.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${x_index}));
|
||||
v.0.height.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${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}));
|
||||
self.gecko.${gecko_ffi_name}.data_at_mut(${x_index})
|
||||
.copy_from(&other.gecko.${gecko_ffi_name}.data_at(${x_index}));
|
||||
self.gecko.${gecko_ffi_name}.data_at_mut(${y_index})
|
||||
.copy_from(&other.gecko.${gecko_ffi_name}.data_at(${y_index}));
|
||||
}
|
||||
% if need_clone:
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -646,8 +648,8 @@ fn static_assert() {
|
|||
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.data().set_enum(CoordDataValues::Auto),
|
||||
T::Number(n) => self.gecko.mZIndex.data().set_enum(CoordDataValues::Integer(n)),
|
||||
T::Auto => self.gecko.mZIndex.set_value(CoordDataValue::Auto),
|
||||
T::Number(n) => self.gecko.mZIndex.set_value(CoordDataValue::Integer(n)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,9 +664,9 @@ fn static_assert() {
|
|||
|
||||
pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
|
||||
use properties::longhands::z_index::computed_value::T;
|
||||
return match self.gecko.mZIndex.data().as_enum() {
|
||||
CoordDataValues::Auto => T::Auto,
|
||||
CoordDataValues::Integer(n) => T::Number(n),
|
||||
return match self.gecko.mZIndex.as_value() {
|
||||
CoordDataValue::Auto => T::Auto,
|
||||
CoordDataValue::Integer(n) => T::Number(n),
|
||||
_ => {
|
||||
debug_assert!(false);
|
||||
T::Number(0)
|
||||
|
@ -824,8 +826,8 @@ fn static_assert() {
|
|||
match v {
|
||||
% for value in keyword.values_for('gecko'):
|
||||
T::${to_rust_ident(value)} =>
|
||||
self.gecko.mVerticalAlign.data().set_enum(
|
||||
CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)})),
|
||||
self.gecko.mVerticalAlign.set_value(
|
||||
CoordDataValue::Enumerated(structs::${keyword.gecko_constant(value)})),
|
||||
% endfor
|
||||
T::LengthOrPercentage(v) => self.gecko.mVerticalAlign.set(v),
|
||||
}
|
||||
|
@ -835,14 +837,13 @@ fn static_assert() {
|
|||
use properties::longhands::vertical_align::computed_value::T;
|
||||
use values::computed::LengthOrPercentage;
|
||||
|
||||
let data = self.gecko.mVerticalAlign.data();
|
||||
match data.as_enum() {
|
||||
match self.gecko.mVerticalAlign.as_value() {
|
||||
% for value in keyword.values_for('gecko'):
|
||||
CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)}) => T::${to_rust_ident(value)},
|
||||
CoordDataValue::Enumerated(structs::${keyword.gecko_constant(value)}) => T::${to_rust_ident(value)},
|
||||
% endfor
|
||||
CoordDataValues::Enumerated(_) => panic!("Unexpected enum variant for vertical-align"),
|
||||
CoordDataValue::Enumerated(_) => panic!("Unexpected enum variant for vertical-align"),
|
||||
_ => {
|
||||
let v = LengthOrPercentage::from_gecko_style_coord(&data)
|
||||
let v = LengthOrPercentage::from_gecko_style_coord(&self.gecko.mVerticalAlign)
|
||||
.expect("Expected length or percentage for vertical-align");
|
||||
T::LengthOrPercentage(v)
|
||||
}
|
||||
|
@ -1130,22 +1131,22 @@ fn static_assert() {
|
|||
use properties::longhands::line_height::computed_value::T;
|
||||
// FIXME: Align binary representations and ditch |match| for cast + static_asserts
|
||||
let en = match v {
|
||||
T::Normal => CoordDataValues::Normal,
|
||||
T::Length(val) => CoordDataValues::Coord(val.0),
|
||||
T::Number(val) => CoordDataValues::Factor(val),
|
||||
T::Normal => CoordDataValue::Normal,
|
||||
T::Length(val) => CoordDataValue::Coord(val.0),
|
||||
T::Number(val) => CoordDataValue::Factor(val),
|
||||
T::MozBlockHeight =>
|
||||
CoordDataValues::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
|
||||
CoordDataValue::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
|
||||
};
|
||||
self.gecko.mLineHeight.data().set_enum(en);
|
||||
self.gecko.mLineHeight.set_value(en);
|
||||
}
|
||||
|
||||
pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
|
||||
use properties::longhands::line_height::computed_value::T;
|
||||
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 =>
|
||||
return match self.gecko.mLineHeight.as_value() {
|
||||
CoordDataValue::Normal => T::Normal,
|
||||
CoordDataValue::Coord(coord) => T::Length(Au(coord)),
|
||||
CoordDataValue::Factor(n) => T::Number(n),
|
||||
CoordDataValue::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
|
||||
T::MozBlockHeight,
|
||||
_ => {
|
||||
debug_assert!(false);
|
||||
|
@ -1280,8 +1281,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.data().set_enum(CoordDataValues::Coord(au.0)),
|
||||
None => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Auto),
|
||||
Some(au) => self.gecko.mColumnWidth.set_value(CoordDataValue::Coord(au.0)),
|
||||
None => self.gecko.mColumnWidth.set_value(CoordDataValue::Auto),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,53 +4,131 @@
|
|||
|
||||
use bindings::{Gecko_ResetStyleCoord, Gecko_SetStyleCoordCalcValue, Gecko_AddRefCalcArbitraryThread};
|
||||
use std::mem::transmute;
|
||||
use std::marker::PhantomData;
|
||||
use structs::{nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord, nsStyleSides, nsStyleCorners};
|
||||
use structs::{nsStyleCoord_CalcValue, nscoord};
|
||||
|
||||
impl nsStyleCoord {
|
||||
impl CoordData for nsStyleCoord {
|
||||
#[inline]
|
||||
pub unsafe fn addref_if_calc(&mut self) {
|
||||
self.data().addref_if_calc();
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
self.mUnit
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data(&self) -> CoordData {
|
||||
CoordData {
|
||||
union: &self.mValue as *const _ as *mut _,
|
||||
unit: &self.mUnit as *const _ as *mut _,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
self.mValue
|
||||
}
|
||||
}
|
||||
|
||||
impl CoordDataMut for nsStyleCoord {
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
||||
(&mut self.mUnit, &mut self.mValue)
|
||||
}
|
||||
}
|
||||
|
||||
impl nsStyleSides {
|
||||
#[inline]
|
||||
pub fn data_at(&self, index: usize) -> CoordData {
|
||||
CoordData {
|
||||
union: &self.mValues[index] as *const _ as *mut _,
|
||||
unit: &self.mUnits[index] as *const _ as *mut _,
|
||||
_marker: PhantomData,
|
||||
pub fn data_at(&self, index: usize) -> SidesData {
|
||||
SidesData {
|
||||
sides: self,
|
||||
index: index,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn data_at_mut(&mut self, index: usize) -> SidesDataMut {
|
||||
SidesDataMut {
|
||||
sides: self,
|
||||
index: index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SidesData<'a> {
|
||||
sides: &'a nsStyleSides,
|
||||
index: usize,
|
||||
}
|
||||
pub struct SidesDataMut<'a> {
|
||||
sides: &'a mut nsStyleSides,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> CoordData for SidesData<'a> {
|
||||
#[inline]
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
self.sides.mUnits[self.index]
|
||||
}
|
||||
#[inline]
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
self.sides.mValues[self.index]
|
||||
}
|
||||
}
|
||||
impl<'a> CoordData for SidesDataMut<'a> {
|
||||
#[inline]
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
self.sides.mUnits[self.index]
|
||||
}
|
||||
#[inline]
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
self.sides.mValues[self.index]
|
||||
}
|
||||
}
|
||||
impl<'a> CoordDataMut for SidesDataMut<'a> {
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
||||
(&mut self.sides.mUnits[self.index], &mut self.sides.mValues[self.index])
|
||||
}
|
||||
}
|
||||
|
||||
impl nsStyleCorners {
|
||||
#[inline]
|
||||
pub fn data_at(&self, index: usize) -> CoordData {
|
||||
CoordData {
|
||||
union: &self.mValues[index] as *const _ as *mut _,
|
||||
unit: &self.mUnits[index] as *const _ as *mut _,
|
||||
_marker: PhantomData,
|
||||
pub fn data_at(&self, index: usize) -> CornersData {
|
||||
CornersData {
|
||||
corners: self,
|
||||
index: index,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn data_at_mut(&mut self, index: usize) -> CornersDataMut {
|
||||
CornersDataMut {
|
||||
corners: self,
|
||||
index: index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CornersData<'a> {
|
||||
corners: &'a nsStyleCorners,
|
||||
index: usize,
|
||||
}
|
||||
pub struct CornersDataMut<'a> {
|
||||
corners: &'a mut nsStyleCorners,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a> CoordData for CornersData<'a> {
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
self.corners.mUnits[self.index]
|
||||
}
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
self.corners.mValues[self.index]
|
||||
}
|
||||
}
|
||||
impl<'a> CoordData for CornersDataMut<'a> {
|
||||
fn unit(&self) -> nsStyleUnit {
|
||||
self.corners.mUnits[self.index]
|
||||
}
|
||||
fn union(&self) -> nsStyleUnion {
|
||||
self.corners.mValues[self.index]
|
||||
}
|
||||
}
|
||||
impl<'a> CoordDataMut for CornersDataMut<'a> {
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
||||
(&mut self.corners.mUnits[self.index], &mut self.corners.mValues[self.index])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
/// Enum representing the tagged union that is CoordData
|
||||
/// Enum representing the tagged union that is CoordData.
|
||||
/// In release mode this should never actually exist in the code,
|
||||
/// and will be optimized out by threading matches and inlining
|
||||
pub enum CoordDataValues {
|
||||
/// and will be optimized out by threading matches and inlining.
|
||||
pub enum CoordDataValue {
|
||||
Null,
|
||||
Normal,
|
||||
Auto,
|
||||
|
@ -68,40 +146,137 @@ pub enum CoordDataValues {
|
|||
Calc(nsStyleCoord_CalcValue),
|
||||
}
|
||||
|
||||
/// XXXManishearth should this be using Cell/UnsafeCell?
|
||||
pub struct CoordData<'a> {
|
||||
union: *mut nsStyleUnion,
|
||||
unit: *mut nsStyleUnit,
|
||||
_marker: PhantomData<&'a mut ()>,
|
||||
}
|
||||
|
||||
impl<'a> CoordData<'a> {
|
||||
pub trait CoordDataMut : CoordData {
|
||||
// This can't be two methods since we can't mutably borrow twice
|
||||
/// This is unsafe since it's possible to modify
|
||||
/// the unit without changing the union
|
||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion);
|
||||
|
||||
/// Clean up any resources used by the union
|
||||
/// Currently, this only happens if the nsStyleUnit
|
||||
/// is a Calc
|
||||
#[inline]
|
||||
pub fn reset(&mut self) {
|
||||
fn reset(&mut self) {
|
||||
unsafe {
|
||||
if *self.unit == nsStyleUnit::eStyleUnit_Calc {
|
||||
Gecko_ResetStyleCoord(self.unit, self.union);
|
||||
if self.unit() == nsStyleUnit::eStyleUnit_Calc {
|
||||
let (unit, union) = self.values_mut();
|
||||
Gecko_ResetStyleCoord(unit, union);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn copy_from(&mut self, other: &CoordData) {
|
||||
self.reset();
|
||||
self.unit = other.unit;
|
||||
self.union = other.union;
|
||||
self.addref_if_calc();
|
||||
fn copy_from<T: CoordData>(&mut self, other: &T) {
|
||||
unsafe {
|
||||
self.reset();
|
||||
{
|
||||
let (unit, union) = self.values_mut();
|
||||
*unit = other.unit();
|
||||
*union = other.union();
|
||||
}
|
||||
self.addref_if_calc();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_enum(&self) -> CoordDataValues {
|
||||
use self::CoordDataValues::*;
|
||||
fn set_value(&mut self, value: CoordDataValue) {
|
||||
use self::CoordDataValue::*;
|
||||
use structs::nsStyleUnit::*;
|
||||
self.reset();
|
||||
unsafe {
|
||||
let (unit, union) = self.values_mut();
|
||||
match value {
|
||||
Null => {
|
||||
*unit = eStyleUnit_Null;
|
||||
*union.mInt.as_mut() = 0;
|
||||
}
|
||||
Normal => {
|
||||
*unit = eStyleUnit_Normal;
|
||||
*union.mInt.as_mut() = 0;
|
||||
}
|
||||
Auto => {
|
||||
*unit = eStyleUnit_Auto;
|
||||
*union.mInt.as_mut() = 0;
|
||||
}
|
||||
None => {
|
||||
*unit = eStyleUnit_None;
|
||||
*union.mInt.as_mut() = 0;
|
||||
}
|
||||
Percent(f) => {
|
||||
*unit = eStyleUnit_Percent;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
Factor(f) => {
|
||||
*unit = eStyleUnit_Factor;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
Degree(f) => {
|
||||
*unit = eStyleUnit_Degree;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
Grad(f) => {
|
||||
*unit = eStyleUnit_Grad;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
Radian(f) => {
|
||||
*unit = eStyleUnit_Radian;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
Turn(f) => {
|
||||
*unit = eStyleUnit_Turn;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
FlexFraction(f) => {
|
||||
*unit = eStyleUnit_FlexFraction;
|
||||
*union.mFloat.as_mut() = f;
|
||||
}
|
||||
Coord(coord) => {
|
||||
*unit = eStyleUnit_Coord;
|
||||
*union.mInt.as_mut() = coord;
|
||||
}
|
||||
Integer(i) => {
|
||||
*unit = eStyleUnit_Integer;
|
||||
*union.mInt.as_mut() = i;
|
||||
}
|
||||
Enumerated(i) => {
|
||||
*unit = eStyleUnit_Enumerated;
|
||||
*union.mInt.as_mut() = i as i32;
|
||||
}
|
||||
Calc(calc) => {
|
||||
// Gecko_SetStyleCoordCalcValue changes the unit internally
|
||||
Gecko_SetStyleCoordCalcValue(unit, union, calc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
|
||||
debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
|
||||
transmute(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn addref_if_calc(&mut self) {
|
||||
unsafe {
|
||||
if self.unit() == nsStyleUnit::eStyleUnit_Calc {
|
||||
Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub trait CoordData {
|
||||
fn unit(&self) -> nsStyleUnit;
|
||||
fn union(&self) -> nsStyleUnion;
|
||||
|
||||
|
||||
#[inline(always)]
|
||||
fn as_value(&self) -> CoordDataValue {
|
||||
use self::CoordDataValue::*;
|
||||
use structs::nsStyleUnit::*;
|
||||
unsafe {
|
||||
match *self.unit {
|
||||
match self.unit() {
|
||||
eStyleUnit_Null => Null,
|
||||
eStyleUnit_Normal => Normal,
|
||||
eStyleUnit_Auto => Auto,
|
||||
|
@ -116,134 +291,43 @@ impl<'a> CoordData<'a> {
|
|||
eStyleUnit_Coord => Coord(self.get_integer()),
|
||||
eStyleUnit_Integer => Integer(self.get_integer()),
|
||||
eStyleUnit_Enumerated => Enumerated(self.get_integer() as u32),
|
||||
eStyleUnit_Calc => Calc(self.get_calc()),
|
||||
eStyleUnit_Calc => Calc(self.get_calc_value()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_enum(&mut self, value: CoordDataValues) {
|
||||
use self::CoordDataValues::*;
|
||||
#[inline]
|
||||
/// Pretend inner value is a float; obtain it.
|
||||
unsafe fn get_float(&self) -> f32 {
|
||||
use structs::nsStyleUnit::*;
|
||||
self.reset();
|
||||
unsafe {
|
||||
match value {
|
||||
Null => {
|
||||
*self.unit = eStyleUnit_Null;
|
||||
*(*self.union).mInt.as_mut() = 0;
|
||||
}
|
||||
Normal => {
|
||||
*self.unit = eStyleUnit_Normal;
|
||||
*(*self.union).mInt.as_mut() = 0;
|
||||
}
|
||||
Auto => {
|
||||
*self.unit = eStyleUnit_Auto;
|
||||
*(*self.union).mInt.as_mut() = 0;
|
||||
}
|
||||
None => {
|
||||
*self.unit = eStyleUnit_None;
|
||||
*(*self.union).mInt.as_mut() = 0;
|
||||
}
|
||||
Percent(f) => {
|
||||
*self.unit = eStyleUnit_Percent;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
Factor(f) => {
|
||||
*self.unit = eStyleUnit_Factor;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
Degree(f) => {
|
||||
*self.unit = eStyleUnit_Degree;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
Grad(f) => {
|
||||
*self.unit = eStyleUnit_Grad;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
Radian(f) => {
|
||||
*self.unit = eStyleUnit_Radian;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
Turn(f) => {
|
||||
*self.unit = eStyleUnit_Turn;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
FlexFraction(f) => {
|
||||
*self.unit = eStyleUnit_FlexFraction;
|
||||
*(*self.union).mFloat.as_mut() = f;
|
||||
}
|
||||
Coord(coord) => {
|
||||
*self.unit = eStyleUnit_Coord;
|
||||
*(*self.union).mInt.as_mut() = coord;
|
||||
}
|
||||
Integer(i) => {
|
||||
*self.unit = eStyleUnit_Integer;
|
||||
*(*self.union).mInt.as_mut() = i;
|
||||
}
|
||||
Enumerated(i) => {
|
||||
*self.unit = eStyleUnit_Enumerated;
|
||||
*(*self.union).mInt.as_mut() = i as i32;
|
||||
}
|
||||
Calc(calc) => {
|
||||
*self.unit = eStyleUnit_Calc;
|
||||
self.set_calc_value(calc);
|
||||
}
|
||||
}
|
||||
}
|
||||
debug_assert!(self.unit() == eStyleUnit_Percent || self.unit() == eStyleUnit_Factor
|
||||
|| self.unit() == eStyleUnit_Degree || self.unit() == eStyleUnit_Grad
|
||||
|| self.unit() == eStyleUnit_Radian || self.unit() == eStyleUnit_Turn
|
||||
|| self.unit() == eStyleUnit_FlexFraction);
|
||||
*self.union().mFloat.as_ref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend inner value is a float; obtain it
|
||||
/// While this should usually be called with the unit checked,
|
||||
/// it is not an intrinsically unsafe operation to call this function
|
||||
/// with the wrong unit
|
||||
pub fn get_float(&self) -> f32 {
|
||||
unsafe { *(*self.union).mFloat.as_ref() }
|
||||
/// Pretend inner value is an int; obtain it.
|
||||
unsafe fn get_integer(&self) -> i32 {
|
||||
use structs::nsStyleUnit::*;
|
||||
debug_assert!(self.unit() == eStyleUnit_Coord || self.unit() == eStyleUnit_Integer
|
||||
|| self.unit() == eStyleUnit_Enumerated);
|
||||
*self.union().mInt.as_ref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend inner value is an int; obtain it
|
||||
/// While this should usually be called with the unit checked,
|
||||
/// it is not an intrinsically unsafe operation to call this function
|
||||
/// with the wrong unit
|
||||
pub fn get_integer(&self) -> i32 {
|
||||
unsafe { *(*self.union).mInt.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Pretend inner value is a calc; obtain it
|
||||
/// Ensure that the unit is Calc before calling this
|
||||
pub unsafe fn get_calc(&self) -> nsStyleCoord_CalcValue {
|
||||
/// Pretend inner value is a calc; obtain it.
|
||||
/// Ensure that the unit is Calc before calling this.
|
||||
unsafe fn get_calc_value(&self) -> nsStyleCoord_CalcValue {
|
||||
debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
|
||||
(*self.as_calc())._base
|
||||
}
|
||||
|
||||
/// Set internal value to a calc() value
|
||||
/// reset() the union before calling this
|
||||
#[inline]
|
||||
pub fn set_calc_value(&mut self, v: nsStyleCoord_CalcValue) {
|
||||
unsafe {
|
||||
// Calc should have been cleaned up
|
||||
debug_assert!(*self.unit != nsStyleUnit::eStyleUnit_Calc);
|
||||
Gecko_SetStyleCoordCalcValue(self.unit, self.union, v);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn addref_if_calc(&mut self) {
|
||||
unsafe {
|
||||
if *self.unit == nsStyleUnit::eStyleUnit_Calc {
|
||||
Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
|
||||
transmute(*(*self.union).mPointer.as_mut() as *mut nsStyleCoord_Calc)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_calc(&self) -> &nsStyleCoord_Calc {
|
||||
transmute(*(*self.union).mPointer.as_ref() as *const nsStyleCoord_Calc)
|
||||
debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
|
||||
transmute(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,8 @@ COMPILATION_TARGETS = {
|
|||
"imgRequestProxy", "imgRequestProxyStatic", "CounterStyleManager",
|
||||
"ImageValue", "URLValue", "URLValueData", "nsIPrincipal",
|
||||
"nsDataHashtable", "imgIRequest"
|
||||
]
|
||||
],
|
||||
"unsafe_field_types": ["nsStyleUnion", "nsStyleUnit"],
|
||||
},
|
||||
# Generation of the ffi bindings.
|
||||
"bindings": {
|
||||
|
@ -130,7 +131,7 @@ COMPILATION_TARGETS = {
|
|||
],
|
||||
"void_types": [
|
||||
"nsINode", "nsIDocument", "nsIPrincipal", "nsIURI",
|
||||
]
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,6 +254,11 @@ def build(objdir, target_name, kind_name=None,
|
|||
flags.append("-match")
|
||||
flags.append(header.format(objdir))
|
||||
|
||||
if "unsafe_field_types" in current_target:
|
||||
for ty in current_target["unsafe_field_types"]:
|
||||
flags.append("-unsafe-field-type")
|
||||
flags.append(ty.format(objdir))
|
||||
|
||||
if "blacklist" in current_target:
|
||||
for ty in current_target["blacklist"]:
|
||||
flags.append("-blacklist-type")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue