mirror of
https://github.com/servo/servo.git
synced 2025-10-14 15:30:27 +01:00
248 lines
8 KiB
Rust
248 lines
8 KiB
Rust
/* 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 http://mozilla.org/MPL/2.0/. */
|
|
|
|
//! Little helpers for `nsCSSValue`.
|
|
|
|
use app_units::Au;
|
|
use gecko_bindings::bindings;
|
|
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit};
|
|
use gecko_bindings::structs::{nsCSSValue_Array, nscolor};
|
|
use gecko_string_cache::Atom;
|
|
use std::mem;
|
|
use std::ops::{Index, IndexMut};
|
|
use std::slice;
|
|
use values::computed::{Angle, LengthOrPercentage};
|
|
use values::specified::url::SpecifiedUrl;
|
|
|
|
impl nsCSSValue {
|
|
/// Create a CSSValue with null unit, useful to be used as a return value.
|
|
#[inline]
|
|
pub fn null() -> Self {
|
|
unsafe { mem::zeroed() }
|
|
}
|
|
|
|
/// Returns this nsCSSValue value as an integer, unchecked in release
|
|
/// builds.
|
|
pub fn integer_unchecked(&self) -> i32 {
|
|
debug_assert!(self.mUnit == nsCSSUnit::eCSSUnit_Integer ||
|
|
self.mUnit == nsCSSUnit::eCSSUnit_Enumerated ||
|
|
self.mUnit == nsCSSUnit::eCSSUnit_EnumColor);
|
|
unsafe { *self.mValue.mInt.as_ref() }
|
|
}
|
|
|
|
/// Checks if it is an integer and returns it if so
|
|
pub fn integer(&self) -> Option<i32> {
|
|
if self.mUnit == nsCSSUnit::eCSSUnit_Integer ||
|
|
self.mUnit == nsCSSUnit::eCSSUnit_Enumerated ||
|
|
self.mUnit == nsCSSUnit::eCSSUnit_EnumColor {
|
|
Some(unsafe { *self.mValue.mInt.as_ref() })
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// Checks if it is an RGBA color, returning it if so
|
|
/// Only use it with colors set by SetColorValue(),
|
|
/// which always sets RGBA colors
|
|
pub fn color_value(&self) -> Option<nscolor> {
|
|
if self.mUnit == nsCSSUnit::eCSSUnit_RGBAColor {
|
|
Some(unsafe { *self.mValue.mColor.as_ref() })
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// Returns this nsCSSValue value as a floating point value, unchecked in
|
|
/// release builds.
|
|
pub fn float_unchecked(&self) -> f32 {
|
|
debug_assert!(nsCSSUnit::eCSSUnit_Number as u32 <= self.mUnit as u32);
|
|
unsafe { *self.mValue.mFloat.as_ref() }
|
|
}
|
|
|
|
/// Returns this nsCSSValue as a nsCSSValue::Array, unchecked in release
|
|
/// builds.
|
|
pub unsafe fn array_unchecked(&self) -> &nsCSSValue_Array {
|
|
debug_assert!(nsCSSUnit::eCSSUnit_Array as u32 <= self.mUnit as u32 &&
|
|
self.mUnit as u32 <= nsCSSUnit::eCSSUnit_Calc_Divided as u32);
|
|
let array = *self.mValue.mArray.as_ref();
|
|
debug_assert!(!array.is_null());
|
|
&*array
|
|
}
|
|
|
|
/// Sets LengthOrPercentage value to this nsCSSValue.
|
|
pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) {
|
|
match lop {
|
|
LengthOrPercentage::Length(au) => {
|
|
bindings::Gecko_CSSValue_SetAbsoluteLength(self, au.0)
|
|
}
|
|
LengthOrPercentage::Percentage(pc) => {
|
|
bindings::Gecko_CSSValue_SetPercentage(self, pc)
|
|
}
|
|
LengthOrPercentage::Calc(calc) => {
|
|
bindings::Gecko_CSSValue_SetCalc(self, calc.into())
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Returns LengthOrPercentage value.
|
|
pub unsafe fn get_lop(&self) -> LengthOrPercentage {
|
|
match self.mUnit {
|
|
nsCSSUnit::eCSSUnit_Pixel => {
|
|
LengthOrPercentage::Length(Au(bindings::Gecko_CSSValue_GetAbsoluteLength(self)))
|
|
},
|
|
nsCSSUnit::eCSSUnit_Percent => {
|
|
LengthOrPercentage::Percentage(bindings::Gecko_CSSValue_GetPercentage(self))
|
|
},
|
|
nsCSSUnit::eCSSUnit_Calc => {
|
|
LengthOrPercentage::Calc(bindings::Gecko_CSSValue_GetCalc(self).into())
|
|
},
|
|
x => panic!("The unit should not be {:?}", x),
|
|
}
|
|
}
|
|
|
|
/// Set to a normal value
|
|
pub fn set_normal(&mut self) {
|
|
unsafe { bindings::Gecko_CSSValue_SetNormal(self) }
|
|
}
|
|
|
|
fn set_string_internal(&mut self, s: &str, unit: nsCSSUnit) {
|
|
unsafe { bindings::Gecko_CSSValue_SetString(self, s.as_ptr(), s.len() as u32, unit) }
|
|
}
|
|
|
|
fn set_string_from_atom_internal(&mut self, s: &Atom, unit: nsCSSUnit) {
|
|
unsafe { bindings::Gecko_CSSValue_SetStringFromAtom(self, s.as_ptr(), unit) }
|
|
}
|
|
|
|
/// Set to a string value
|
|
pub fn set_string(&mut self, s: &str) {
|
|
self.set_string_internal(s, nsCSSUnit::eCSSUnit_String)
|
|
}
|
|
|
|
/// Set to a string value from the given atom
|
|
pub fn set_string_from_atom(&mut self, s: &Atom) {
|
|
self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_String)
|
|
}
|
|
|
|
/// Set to a ident value from the given atom
|
|
pub fn set_ident_from_atom(&mut self, s: &Atom) {
|
|
self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_Ident)
|
|
}
|
|
|
|
/// Set to an identifier value
|
|
pub fn set_ident(&mut self, s: &str) {
|
|
self.set_string_internal(s, nsCSSUnit::eCSSUnit_Ident)
|
|
}
|
|
|
|
/// Set to a font format
|
|
pub fn set_font_format(&mut self, s: &str) {
|
|
self.set_string_internal(s, nsCSSUnit::eCSSUnit_Font_Format);
|
|
}
|
|
|
|
/// Set to a local font value
|
|
pub fn set_local_font(&mut self, s: &Atom) {
|
|
self.set_string_from_atom_internal(s, nsCSSUnit::eCSSUnit_Local_Font);
|
|
}
|
|
|
|
fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) {
|
|
unsafe { bindings::Gecko_CSSValue_SetInt(self, value, unit) }
|
|
}
|
|
|
|
/// Set to an integer value
|
|
pub fn set_integer(&mut self, value: i32) {
|
|
self.set_int_internal(value, nsCSSUnit::eCSSUnit_Integer)
|
|
}
|
|
|
|
/// Set to an enumerated value
|
|
pub fn set_enum<T: Into<i32>>(&mut self, value: T) {
|
|
self.set_int_internal(value.into(), nsCSSUnit::eCSSUnit_Enumerated);
|
|
}
|
|
|
|
/// Set to a url value
|
|
pub fn set_url(&mut self, url: &SpecifiedUrl) {
|
|
unsafe { bindings::Gecko_CSSValue_SetURL(self, url.for_ffi()) }
|
|
}
|
|
|
|
/// Set to an array of given length
|
|
pub fn set_array(&mut self, len: i32) -> &mut nsCSSValue_Array {
|
|
unsafe { bindings::Gecko_CSSValue_SetArray(self, len) }
|
|
unsafe { self.mValue.mArray.as_mut().as_mut() }.unwrap()
|
|
}
|
|
|
|
/// Generic set from any value that implements the ToNsCssValue trait.
|
|
pub fn set_from<T: ToNsCssValue>(&mut self, value: &T) {
|
|
value.convert(self)
|
|
}
|
|
|
|
/// Returns an `Angle` value from this `nsCSSValue`.
|
|
///
|
|
/// Panics if the unit is not `eCSSUnit_Degree` `eCSSUnit_Grad`, `eCSSUnit_Turn`
|
|
/// or `eCSSUnit_Radian`.
|
|
pub fn get_angle(&self) -> Angle {
|
|
unsafe {
|
|
Angle::from_gecko_values(self.float_unchecked(), self.mUnit)
|
|
}
|
|
}
|
|
|
|
/// Sets Angle value to this nsCSSValue.
|
|
pub fn set_angle(&mut self, angle: Angle) {
|
|
debug_assert_eq!(self.mUnit, nsCSSUnit::eCSSUnit_Null);
|
|
let (value, unit) = angle.to_gecko_values();
|
|
self.mUnit = unit;
|
|
unsafe {
|
|
*self.mValue.mFloat.as_mut() = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Drop for nsCSSValue {
|
|
fn drop(&mut self) {
|
|
unsafe { bindings::Gecko_CSSValue_Drop(self) };
|
|
}
|
|
}
|
|
|
|
impl nsCSSValue_Array {
|
|
/// Return the length of this `nsCSSValue::Array`
|
|
#[inline]
|
|
pub fn len(&self) -> usize {
|
|
self.mCount
|
|
}
|
|
|
|
#[inline]
|
|
fn buffer(&self) -> *const nsCSSValue {
|
|
self.mArray.as_ptr()
|
|
}
|
|
|
|
/// Get the array as a slice of nsCSSValues.
|
|
#[inline]
|
|
pub fn as_slice(&self) -> &[nsCSSValue] {
|
|
unsafe { slice::from_raw_parts(self.buffer(), self.len()) }
|
|
}
|
|
|
|
/// Get the array as a mutable slice of nsCSSValues.
|
|
#[inline]
|
|
pub fn as_mut_slice(&mut self) -> &mut [nsCSSValue] {
|
|
unsafe { slice::from_raw_parts_mut(self.buffer() as *mut _, self.len()) }
|
|
}
|
|
}
|
|
|
|
impl Index<usize> for nsCSSValue_Array {
|
|
type Output = nsCSSValue;
|
|
#[inline]
|
|
fn index(&self, i: usize) -> &nsCSSValue {
|
|
&self.as_slice()[i]
|
|
}
|
|
}
|
|
|
|
impl IndexMut<usize> for nsCSSValue_Array {
|
|
#[inline]
|
|
fn index_mut(&mut self, i: usize) -> &mut nsCSSValue {
|
|
&mut self.as_mut_slice()[i]
|
|
}
|
|
}
|
|
|
|
/// Generic conversion to nsCSSValue
|
|
pub trait ToNsCssValue {
|
|
/// Convert
|
|
fn convert(&self, nscssvalue: &mut nsCSSValue);
|
|
}
|