mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Remove nsStyleCoord.
And move the useful bits of it somewhere else (ServoStyleConstInlines.h for the inline function definitions, and nsFrame.cpp for the static assertions). Differential Revision: https://phabricator.services.mozilla.com/D36120
This commit is contained in:
parent
8d127014c3
commit
31b166fb1b
4 changed files with 5 additions and 584 deletions
|
@ -10,49 +10,15 @@
|
||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
|
||||||
use crate::gecko_bindings::bindings;
|
use crate::gecko_bindings::bindings;
|
||||||
use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue, Matrix4x4Components};
|
use crate::gecko_bindings::structs::{self, Matrix4x4Components};
|
||||||
use crate::gecko_bindings::structs::{nsStyleImage, nsresult};
|
use crate::gecko_bindings::structs::{nsStyleImage, nsresult};
|
||||||
use crate::stylesheets::RulesMutateError;
|
use crate::stylesheets::RulesMutateError;
|
||||||
use crate::values::computed::transform::Matrix3D;
|
use crate::values::computed::transform::Matrix3D;
|
||||||
use crate::values::computed::url::ComputedImageUrl;
|
use crate::values::computed::url::ComputedImageUrl;
|
||||||
use crate::values::computed::{Gradient, Image, LengthPercentage};
|
use crate::values::computed::{Gradient, Image, TextAlign};
|
||||||
use crate::values::computed::{Length, Percentage, TextAlign};
|
|
||||||
use crate::values::generics::image::GenericImage;
|
use crate::values::generics::image::GenericImage;
|
||||||
use crate::values::generics::rect::Rect;
|
use crate::values::generics::rect::Rect;
|
||||||
use crate::Zero;
|
|
||||||
use app_units::Au;
|
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
|
||||||
|
|
||||||
impl From<LengthPercentage> for nsStyleCoord_CalcValue {
|
|
||||||
fn from(other: LengthPercentage) -> nsStyleCoord_CalcValue {
|
|
||||||
debug_assert!(
|
|
||||||
other.was_calc || !other.has_percentage || other.unclamped_length() == Length::zero()
|
|
||||||
);
|
|
||||||
nsStyleCoord_CalcValue {
|
|
||||||
mLength: other.unclamped_length().to_i32_au(),
|
|
||||||
mPercent: other.percentage(),
|
|
||||||
mHasPercent: other.has_percentage,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<nsStyleCoord_CalcValue> for LengthPercentage {
|
|
||||||
fn from(other: nsStyleCoord_CalcValue) -> LengthPercentage {
|
|
||||||
let percentage = if other.mHasPercent {
|
|
||||||
Some(Percentage(other.mPercent))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Self::with_clamping_mode(
|
|
||||||
Au(other.mLength).into(),
|
|
||||||
percentage,
|
|
||||||
AllowedNumericType::All,
|
|
||||||
/* was_calc = */ true,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl nsStyleImage {
|
impl nsStyleImage {
|
||||||
/// Set a given Servo `Image` value into this `nsStyleImage`.
|
/// Set a given Servo `Image` value into this `nsStyleImage`.
|
||||||
|
@ -296,31 +262,6 @@ impl From<RulesMutateError> for nsresult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Rect<T>
|
|
||||||
where
|
|
||||||
T: GeckoStyleCoordConvertible,
|
|
||||||
{
|
|
||||||
/// Convert this generic Rect to given Gecko fields.
|
|
||||||
pub fn to_gecko_rect(&self, sides: &mut crate::gecko_bindings::structs::nsStyleSides) {
|
|
||||||
self.0.to_gecko_style_coord(&mut sides.data_at_mut(0));
|
|
||||||
self.1.to_gecko_style_coord(&mut sides.data_at_mut(1));
|
|
||||||
self.2.to_gecko_style_coord(&mut sides.data_at_mut(2));
|
|
||||||
self.3.to_gecko_style_coord(&mut sides.data_at_mut(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert from given Gecko data to generic Rect.
|
|
||||||
pub fn from_gecko_rect(
|
|
||||||
sides: &crate::gecko_bindings::structs::nsStyleSides,
|
|
||||||
) -> Option<crate::values::generics::rect::Rect<T>> {
|
|
||||||
Some(Rect::new(
|
|
||||||
T::from_gecko_style_coord(&sides.data_at(0)).expect("coord[0] cound not convert"),
|
|
||||||
T::from_gecko_style_coord(&sides.data_at(1)).expect("coord[1] cound not convert"),
|
|
||||||
T::from_gecko_style_coord(&sides.data_at(2)).expect("coord[2] cound not convert"),
|
|
||||||
T::from_gecko_style_coord(&sides.data_at(3)).expect("coord[3] cound not convert"),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextAlign {
|
impl TextAlign {
|
||||||
/// Obtain a specified value from a Gecko keyword value
|
/// Obtain a specified value from a Gecko keyword value
|
||||||
///
|
///
|
||||||
|
|
|
@ -7,165 +7,15 @@
|
||||||
//! Different kind of helpers to interact with Gecko values.
|
//! Different kind of helpers to interact with Gecko values.
|
||||||
|
|
||||||
use crate::counter_style::{Symbol, Symbols};
|
use crate::counter_style::{Symbol, Symbols};
|
||||||
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
|
use crate::gecko_bindings::structs::CounterStylePtr;
|
||||||
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
|
use crate::values::generics::CounterStyleOrNone;
|
||||||
use crate::values::computed::{Length, LengthPercentage};
|
|
||||||
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
|
|
||||||
use crate::values::generics::length::LengthPercentageOrAuto;
|
|
||||||
use crate::values::generics::{CounterStyleOrNone, NonNegative};
|
|
||||||
use crate::values::Either;
|
use crate::values::Either;
|
||||||
use crate::{Atom, Zero};
|
use crate::Atom;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::RGBA;
|
use cssparser::RGBA;
|
||||||
use nsstring::{nsACString, nsCStr};
|
use nsstring::{nsACString, nsCStr};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
|
||||||
/// A trait that defines an interface to convert from and to `nsStyleCoord`s.
|
|
||||||
///
|
|
||||||
/// TODO(emilio): Almost everything that is in this file should be somehow
|
|
||||||
/// switched to cbindgen.
|
|
||||||
pub trait GeckoStyleCoordConvertible: Sized {
|
|
||||||
/// Convert this to a `nsStyleCoord`.
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T);
|
|
||||||
/// Given a `nsStyleCoord`, try to get a value of this type..
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl nsStyleCoord {
|
|
||||||
#[inline]
|
|
||||||
/// Set this `nsStyleCoord` value to `val`.
|
|
||||||
pub fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
|
|
||||||
val.to_gecko_style_coord(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Inner> GeckoStyleCoordConvertible for NonNegative<Inner>
|
|
||||||
where
|
|
||||||
Inner: GeckoStyleCoordConvertible,
|
|
||||||
{
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
self.0.to_gecko_style_coord(coord)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
Some(NonNegative(Inner::from_gecko_style_coord(coord)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GeckoStyleCoordConvertible for Number {
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
coord.set_value(CoordDataValue::Factor(*self));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
match coord.as_value() {
|
|
||||||
CoordDataValue::Factor(f) => Some(f),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GeckoStyleCoordConvertible for Percentage {
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
coord.set_value(CoordDataValue::Percent(self.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
match coord.as_value() {
|
|
||||||
CoordDataValue::Percent(p) => Some(Percentage(p)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GeckoStyleCoordConvertible for NumberOrPercentage {
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
match *self {
|
|
||||||
NumberOrPercentage::Number(ref n) => n.to_gecko_style_coord(coord),
|
|
||||||
NumberOrPercentage::Percentage(ref p) => p.to_gecko_style_coord(coord),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
match coord.as_value() {
|
|
||||||
CoordDataValue::Factor(f) => Some(NumberOrPercentage::Number(f)),
|
|
||||||
CoordDataValue::Percent(p) => Some(NumberOrPercentage::Percentage(Percentage(p))),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GeckoStyleCoordConvertible for LengthPercentage {
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
if self.was_calc {
|
|
||||||
return coord.set_value(CoordDataValue::Calc((*self).into()));
|
|
||||||
}
|
|
||||||
debug_assert!(!self.has_percentage || self.unclamped_length() == Length::zero());
|
|
||||||
if self.has_percentage {
|
|
||||||
return coord.set_value(CoordDataValue::Percent(self.percentage()));
|
|
||||||
}
|
|
||||||
coord.set_value(CoordDataValue::Coord(self.unclamped_length().to_i32_au()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
match coord.as_value() {
|
|
||||||
CoordDataValue::Coord(coord) => Some(LengthPercentage::new(Au(coord).into(), None)),
|
|
||||||
CoordDataValue::Percent(p) => {
|
|
||||||
Some(LengthPercentage::new(Au(0).into(), Some(Percentage(p))))
|
|
||||||
},
|
|
||||||
CoordDataValue::Calc(calc) => Some(calc.into()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GeckoStyleCoordConvertible for Length {
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
coord.set_value(CoordDataValue::Coord(self.to_i32_au()));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
match coord.as_value() {
|
|
||||||
CoordDataValue::Coord(coord) => Some(Au(coord).into()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<LengthPercentage> GeckoStyleCoordConvertible for LengthPercentageOrAuto<LengthPercentage>
|
|
||||||
where
|
|
||||||
LengthPercentage: GeckoStyleCoordConvertible,
|
|
||||||
{
|
|
||||||
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
|
|
||||||
match *self {
|
|
||||||
LengthPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto),
|
|
||||||
LengthPercentageOrAuto::LengthPercentage(ref lp) => lp.to_gecko_style_coord(coord),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
|
|
||||||
match coord.as_value() {
|
|
||||||
CoordDataValue::Auto => Some(LengthPercentageOrAuto::Auto),
|
|
||||||
_ => LengthPercentage::from_gecko_style_coord(coord)
|
|
||||||
.map(LengthPercentageOrAuto::LengthPercentage),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
|
|
||||||
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_value(CoordDataValue::None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_gecko_style_coord<U: CoordData>(coord: &U) -> Option<Self> {
|
|
||||||
Some(T::from_gecko_style_coord(coord))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert a given RGBA value to `nscolor`.
|
/// Convert a given RGBA value to `nscolor`.
|
||||||
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 {
|
||||||
((rgba.alpha as u32) << 24) |
|
((rgba.alpha as u32) << 24) |
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
mod ns_com_ptr;
|
mod ns_com_ptr;
|
||||||
mod ns_compatibility;
|
mod ns_compatibility;
|
||||||
mod ns_style_auto_array;
|
mod ns_style_auto_array;
|
||||||
pub mod ns_style_coord;
|
|
||||||
mod ns_t_array;
|
mod ns_t_array;
|
||||||
pub mod origin_flags;
|
pub mod origin_flags;
|
||||||
pub mod ownership;
|
pub mod ownership;
|
||||||
|
|
|
@ -1,369 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
//! Rust helpers for Gecko's `nsStyleCoord`.
|
|
||||||
|
|
||||||
use crate::gecko_bindings::bindings;
|
|
||||||
use crate::gecko_bindings::structs::nsStyleSides;
|
|
||||||
use crate::gecko_bindings::structs::{nsStyleCoord, nsStyleCoord_Calc, nsStyleCoord_CalcValue};
|
|
||||||
use crate::gecko_bindings::structs::{nsStyleUnion, nsStyleUnit, nscoord};
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
impl nsStyleCoord {
|
|
||||||
#[inline]
|
|
||||||
/// Get a `null` nsStyleCoord.
|
|
||||||
pub fn null() -> Self {
|
|
||||||
// Can't construct directly because it has private fields
|
|
||||||
let mut coord: Self = unsafe { mem::zeroed() };
|
|
||||||
coord.leaky_set_null();
|
|
||||||
coord
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl CoordData for nsStyleCoord {
|
|
||||||
#[inline]
|
|
||||||
fn unit(&self) -> nsStyleUnit {
|
|
||||||
unsafe { *self.get_mUnit() }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn union(&self) -> nsStyleUnion {
|
|
||||||
unsafe { *self.get_mValue() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl CoordDataMut for nsStyleCoord {
|
|
||||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
|
||||||
let unit = self.get_mUnit_mut() as *mut _;
|
|
||||||
let value = self.get_mValue_mut() as *mut _;
|
|
||||||
(&mut *unit, &mut *value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl nsStyleCoord_CalcValue {
|
|
||||||
/// Create an "empty" CalcValue (whose value is `0`).
|
|
||||||
pub fn new() -> Self {
|
|
||||||
nsStyleCoord_CalcValue {
|
|
||||||
mLength: 0,
|
|
||||||
mPercent: 0.0,
|
|
||||||
mHasPercent: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for nsStyleCoord_CalcValue {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.mLength == other.mLength &&
|
|
||||||
self.mPercent == other.mPercent &&
|
|
||||||
self.mHasPercent == other.mHasPercent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl nsStyleSides {
|
|
||||||
/// Immutably get the `nsStyleCoord`-like object representing the side at
|
|
||||||
/// index `index`.
|
|
||||||
#[inline]
|
|
||||||
pub fn data_at(&self, index: usize) -> SidesData {
|
|
||||||
SidesData {
|
|
||||||
sides: self,
|
|
||||||
index: index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mutably get the `nsStyleCoord`-like object representing the side at
|
|
||||||
/// index `index`.
|
|
||||||
#[inline]
|
|
||||||
pub fn data_at_mut(&mut self, index: usize) -> SidesDataMut {
|
|
||||||
SidesDataMut {
|
|
||||||
sides: self,
|
|
||||||
index: index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `nsStyleCoord`-like object on top of an immutable reference to
|
|
||||||
/// `nsStyleSides`.
|
|
||||||
pub struct SidesData<'a> {
|
|
||||||
sides: &'a nsStyleSides,
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `nsStyleCoord`-like object on top of an mutable reference to
|
|
||||||
/// `nsStyleSides`.
|
|
||||||
pub struct SidesDataMut<'a> {
|
|
||||||
sides: &'a mut nsStyleSides,
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'a> CoordData for SidesData<'a> {
|
|
||||||
#[inline]
|
|
||||||
fn unit(&self) -> nsStyleUnit {
|
|
||||||
unsafe { self.sides.get_mUnits()[self.index] }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn union(&self) -> nsStyleUnion {
|
|
||||||
unsafe { self.sides.get_mValues()[self.index] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe impl<'a> CoordData for SidesDataMut<'a> {
|
|
||||||
#[inline]
|
|
||||||
fn unit(&self) -> nsStyleUnit {
|
|
||||||
unsafe { self.sides.get_mUnits()[self.index] }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn union(&self) -> nsStyleUnion {
|
|
||||||
unsafe { self.sides.get_mValues()[self.index] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe impl<'a> CoordDataMut for SidesDataMut<'a> {
|
|
||||||
unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
|
|
||||||
let unit = &mut self.sides.get_mUnits_mut()[self.index] as *mut _;
|
|
||||||
let value = &mut self.sides.get_mValues_mut()[self.index] as *mut _;
|
|
||||||
(&mut *unit, &mut *value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
pub enum CoordDataValue {
|
|
||||||
/// eStyleUnit_Null
|
|
||||||
Null,
|
|
||||||
/// eStyleUnit_Normal
|
|
||||||
Normal,
|
|
||||||
/// eStyleUnit_Auto
|
|
||||||
Auto,
|
|
||||||
/// eStyleUnit_None
|
|
||||||
None,
|
|
||||||
/// eStyleUnit_Percent
|
|
||||||
Percent(f32),
|
|
||||||
/// eStyleUnit_Factor
|
|
||||||
Factor(f32),
|
|
||||||
/// eStyleUnit_Degree
|
|
||||||
Degree(f32),
|
|
||||||
/// eStyleUnit_FlexFraction
|
|
||||||
FlexFraction(f32),
|
|
||||||
/// eStyleUnit_Coord
|
|
||||||
Coord(nscoord),
|
|
||||||
/// eStyleUnit_Integer
|
|
||||||
Integer(i32),
|
|
||||||
/// eStyleUnit_Enumerated
|
|
||||||
Enumerated(u32),
|
|
||||||
/// eStyleUnit_Calc
|
|
||||||
Calc(nsStyleCoord_CalcValue),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A trait to abstract on top of a mutable `nsStyleCoord`-like object.
|
|
||||||
pub unsafe trait CoordDataMut: CoordData {
|
|
||||||
/// Get mutably the unit and the union.
|
|
||||||
///
|
|
||||||
/// This is unsafe since it's possible to modify the unit without changing
|
|
||||||
/// the union.
|
|
||||||
///
|
|
||||||
/// NB: This can't be two methods since we can't mutably borrow twice
|
|
||||||
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]
|
|
||||||
fn reset(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
if self.unit() == nsStyleUnit::eStyleUnit_Calc {
|
|
||||||
let (unit, union) = self.values_mut();
|
|
||||||
bindings::Gecko_ResetStyleCoord(unit, union);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Copies the unit and value from another `CoordData` type.
|
|
||||||
fn copy_from<T: CoordData>(&mut self, other: &T) {
|
|
||||||
unsafe {
|
|
||||||
self.reset();
|
|
||||||
self.copy_from_unchecked(other);
|
|
||||||
self.addref_if_calc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Moves the unit and value from another `CoordData` type.
|
|
||||||
fn move_from<T: CoordData>(&mut self, other: T) {
|
|
||||||
unsafe {
|
|
||||||
self.reset();
|
|
||||||
self.copy_from_unchecked(&other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Copies the unit and value from another `CoordData` type without checking
|
|
||||||
/// the type of the value (so refcounted values like calc may leak).
|
|
||||||
unsafe fn copy_from_unchecked<T: CoordData>(&mut self, other: &T) {
|
|
||||||
let (unit, union) = self.values_mut();
|
|
||||||
*unit = other.unit();
|
|
||||||
*union = other.union();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Useful for initializing uninits, given that `set_value` may segfault on
|
|
||||||
/// uninits.
|
|
||||||
fn leaky_set_null(&mut self) {
|
|
||||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
|
||||||
unsafe {
|
|
||||||
let (unit, union) = self.values_mut();
|
|
||||||
*unit = eStyleUnit_Null;
|
|
||||||
*union.mInt.as_mut() = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
/// Sets the inner value.
|
|
||||||
fn set_value(&mut self, value: CoordDataValue) {
|
|
||||||
use self::CoordDataValue::*;
|
|
||||||
use crate::gecko_bindings::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;
|
|
||||||
},
|
|
||||||
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
|
|
||||||
bindings::Gecko_SetStyleCoordCalcValue(unit, union, calc);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Gets the `Calc` value mutably, asserts in debug builds if the unit is
|
|
||||||
/// not `Calc`.
|
|
||||||
unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
|
|
||||||
debug_assert_eq!(self.unit(), nsStyleUnit::eStyleUnit_Calc);
|
|
||||||
&mut *(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Does what it promises, if the unit is `calc`, it bumps the reference
|
|
||||||
/// count _of the calc expression_.
|
|
||||||
fn addref_if_calc(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
if self.unit() == nsStyleUnit::eStyleUnit_Calc {
|
|
||||||
bindings::Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// A trait to abstract on top of a `nsStyleCoord`-like object.
|
|
||||||
pub unsafe trait CoordData {
|
|
||||||
/// Get the unit of this object.
|
|
||||||
fn unit(&self) -> nsStyleUnit;
|
|
||||||
/// Get the `nsStyleUnion` for this object.
|
|
||||||
fn union(&self) -> nsStyleUnion;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
/// Get the appropriate value for this object.
|
|
||||||
fn as_value(&self) -> CoordDataValue {
|
|
||||||
use self::CoordDataValue::*;
|
|
||||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
|
||||||
unsafe {
|
|
||||||
match self.unit() {
|
|
||||||
eStyleUnit_Null => Null,
|
|
||||||
eStyleUnit_Normal => Normal,
|
|
||||||
eStyleUnit_Auto => Auto,
|
|
||||||
eStyleUnit_None => None,
|
|
||||||
eStyleUnit_Percent => Percent(self.get_float()),
|
|
||||||
eStyleUnit_Factor => Factor(self.get_float()),
|
|
||||||
eStyleUnit_Degree => Degree(self.get_float()),
|
|
||||||
eStyleUnit_FlexFraction => FlexFraction(self.get_float()),
|
|
||||||
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_value()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Pretend inner value is a float; obtain it.
|
|
||||||
unsafe fn get_float(&self) -> f32 {
|
|
||||||
use crate::gecko_bindings::structs::nsStyleUnit::*;
|
|
||||||
debug_assert!(
|
|
||||||
self.unit() == eStyleUnit_Percent ||
|
|
||||||
self.unit() == eStyleUnit_Factor ||
|
|
||||||
self.unit() == eStyleUnit_Degree ||
|
|
||||||
self.unit() == eStyleUnit_FlexFraction
|
|
||||||
);
|
|
||||||
*self.union().mFloat.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Pretend inner value is an int; obtain it.
|
|
||||||
unsafe fn get_integer(&self) -> i32 {
|
|
||||||
use crate::gecko_bindings::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 a calc; obtain it.
|
|
||||||
/// Ensure that the unit is Calc before calling this.
|
|
||||||
unsafe fn get_calc_value(&self) -> nsStyleCoord_CalcValue {
|
|
||||||
debug_assert_eq!(self.unit(), nsStyleUnit::eStyleUnit_Calc);
|
|
||||||
(*self.as_calc())._base
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Pretend the inner value is a calc expression, and obtain it.
|
|
||||||
unsafe fn as_calc(&self) -> &nsStyleCoord_Calc {
|
|
||||||
debug_assert_eq!(self.unit(), nsStyleUnit::eStyleUnit_Calc);
|
|
||||||
&*(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue