use std::collections::BTreeMap;
use std::fmt;
use crate::css::CssPropertyValue;
pub trait FormatAsCssValue {
fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result;
}
pub const EM_HEIGHT: f32 = 16.0;
pub const PT_TO_PX: f32 = 96.0 / 72.0;
const COMBINED_CSS_PROPERTIES_KEY_MAP: [(CombinedCssPropertyType, &'static str);10] = [
(CombinedCssPropertyType::BorderRadius, "border-radius"),
(CombinedCssPropertyType::Overflow, "overflow"),
(CombinedCssPropertyType::Padding, "padding"),
(CombinedCssPropertyType::Margin, "margin"),
(CombinedCssPropertyType::Border, "border"),
(CombinedCssPropertyType::BorderLeft, "border-left"),
(CombinedCssPropertyType::BorderRight, "border-right"),
(CombinedCssPropertyType::BorderTop, "border-top"),
(CombinedCssPropertyType::BorderBottom, "border-bottom"),
(CombinedCssPropertyType::BoxShadow, "box-shadow"),
];
const CSS_PROPERTY_KEY_MAP: [(CssPropertyType, &'static str);66] = [
(CssPropertyType::Display, "display"),
(CssPropertyType::Float, "float"),
(CssPropertyType::BoxSizing, "box-sizing"),
(CssPropertyType::TextColor, "color"),
(CssPropertyType::FontSize, "font-size"),
(CssPropertyType::FontFamily, "font-family"),
(CssPropertyType::TextAlign, "text-align"),
(CssPropertyType::LetterSpacing, "letter-spacing"),
(CssPropertyType::LineHeight, "line-height"),
(CssPropertyType::WordSpacing, "word-spacing"),
(CssPropertyType::TabWidth, "tab-width"),
(CssPropertyType::Cursor, "cursor"),
(CssPropertyType::Width, "width"),
(CssPropertyType::Height, "height"),
(CssPropertyType::MinWidth, "min-width"),
(CssPropertyType::MinHeight, "min-height"),
(CssPropertyType::MaxWidth, "max-width"),
(CssPropertyType::MaxHeight, "max-height"),
(CssPropertyType::Position, "position"),
(CssPropertyType::Top, "top"),
(CssPropertyType::Right, "right"),
(CssPropertyType::Left, "left"),
(CssPropertyType::Bottom, "bottom"),
(CssPropertyType::FlexWrap, "flex-wrap"),
(CssPropertyType::FlexDirection, "flex-direction"),
(CssPropertyType::FlexGrow, "flex-grow"),
(CssPropertyType::FlexShrink, "flex-shrink"),
(CssPropertyType::JustifyContent, "justify-content"),
(CssPropertyType::AlignItems, "align-items"),
(CssPropertyType::AlignContent, "align-content"),
(CssPropertyType::OverflowX, "overflow-x"),
(CssPropertyType::OverflowY, "overflow-y"),
(CssPropertyType::PaddingTop, "padding-top"),
(CssPropertyType::PaddingLeft, "padding-left"),
(CssPropertyType::PaddingRight, "padding-right"),
(CssPropertyType::PaddingBottom, "padding-bottom"),
(CssPropertyType::MarginTop, "margin-top"),
(CssPropertyType::MarginLeft, "margin-left"),
(CssPropertyType::MarginRight, "margin-right"),
(CssPropertyType::MarginBottom, "margin-bottom"),
(CssPropertyType::Background, "background"),
(CssPropertyType::BackgroundImage, "background-image"),
(CssPropertyType::BackgroundColor, "background-color"),
(CssPropertyType::BackgroundPosition, "background-position"),
(CssPropertyType::BackgroundSize, "background-size"),
(CssPropertyType::BackgroundRepeat, "background-repeat"),
(CssPropertyType::BorderTopLeftRadius, "border-top-left-radius"),
(CssPropertyType::BorderTopRightRadius, "border-top-right-radius"),
(CssPropertyType::BorderBottomLeftRadius, "border-bottom-left-radius"),
(CssPropertyType::BorderBottomRightRadius, "border-bottom-right-radius"),
(CssPropertyType::BorderTopColor, "border-top-color"),
(CssPropertyType::BorderRightColor, "border-right-color"),
(CssPropertyType::BorderLeftColor, "border-left-color"),
(CssPropertyType::BorderBottomColor, "border-bottom-color"),
(CssPropertyType::BorderTopStyle, "border-top-style"),
(CssPropertyType::BorderRightStyle, "border-right-style"),
(CssPropertyType::BorderLeftStyle, "border-left-style"),
(CssPropertyType::BorderBottomStyle, "border-bottom-style"),
(CssPropertyType::BorderTopWidth, "border-top-width"),
(CssPropertyType::BorderRightWidth, "border-right-width"),
(CssPropertyType::BorderLeftWidth, "border-left-width"),
(CssPropertyType::BorderBottomWidth, "border-bottom-width"),
(CssPropertyType::BoxShadowTop, "box-shadow-top"),
(CssPropertyType::BoxShadowRight, "box-shadow-right"),
(CssPropertyType::BoxShadowLeft, "box-shadow-left"),
(CssPropertyType::BoxShadowBottom, "box-shadow-bottom"),
];
#[derive(Copy, Clone, PartialEq, PartialOrd)]
pub struct LayoutRect { pub origin: LayoutPoint, pub size: LayoutSize }
impl fmt::Debug for LayoutRect {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}
}
impl fmt::Display for LayoutRect {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} @ {}", self.size, self.origin)
}
}
impl LayoutRect {
#[inline(always)]
pub fn new(origin: LayoutPoint, size: LayoutSize) -> Self { Self { origin, size } }
#[inline(always)]
pub fn zero() -> Self { Self::new(LayoutPoint::zero(), LayoutSize::zero()) }
#[inline(always)]
pub fn max_x(&self) -> f32 { self.origin.x + self.size.width }
#[inline(always)]
pub fn min_x(&self) -> f32 { self.origin.x }
#[inline(always)]
pub fn max_y(&self) -> f32 { self.origin.y + self.size.height }
#[inline(always)]
pub fn min_y(&self) -> f32 { self.origin.y }
#[inline(always)]
pub fn contains(&self, other: &LayoutPoint) -> bool {
self.min_x() <= other.x && other.x < self.max_x() &&
self.min_y() <= other.y && other.y < self.max_y()
}
#[inline]
pub fn union<I: Iterator<Item=Self>>(mut rects: I) -> Option<Self> {
let first = rects.next()?;
let mut max_width = first.size.width;
let mut max_height = first.size.height;
let mut min_x = first.origin.x;
let mut min_y = first.origin.y;
while let Some(Self { origin: LayoutPoint { x, y }, size: LayoutSize { width, height } }) = rects.next() {
let cur_lower_right_x = x + width;
let cur_lower_right_y = y + height;
max_width = max_width.max(cur_lower_right_x - min_x);
max_height = max_height.max(cur_lower_right_y - min_y);
min_x = min_x.min(x);
min_y = min_y.min(y);
}
Some(Self {
origin: LayoutPoint { x: min_x, y: min_y },
size: LayoutSize { width: max_width, height: max_height },
})
}
#[inline]
pub fn get_scroll_rect<I: Iterator<Item=Self>>(&self, children: I) -> Option<Self> {
let children_union = Self::union(children)?;
Self::union([*self, children_union].iter().map(|r| *r))
}
#[inline(always)]
pub fn contains_rect(&self, b: &LayoutRect) -> bool {
let a = self;
let a_x = a.origin.x;
let a_y = a.origin.y;
let a_width = a.size.width;
let a_height = a.size.height;
let b_x = b.origin.x;
let b_y = b.origin.y;
let b_width = b.size.width;
let b_height = b.size.height;
b_x >= a_x &&
b_y >= a_y &&
b_x + b_width <= a_x + a_width &&
b_y + b_height <= a_y + a_height
}
}
#[derive(Copy, Clone, PartialEq, PartialOrd)]
pub struct LayoutSize { pub width: f32, pub height: f32 }
impl fmt::Debug for LayoutSize {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}
}
impl fmt::Display for LayoutSize {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}x{}", self.width, self.height)
}
}
impl LayoutSize {
#[inline(always)]
pub const fn new(width: f32, height: f32) -> Self { Self { width, height } }
#[inline(always)]
pub const fn zero() -> Self { Self::new(0.0, 0.0) }
}
#[derive(Copy, Clone, PartialEq, PartialOrd)]
pub struct LayoutPoint { pub x: f32, pub y: f32 }
impl fmt::Debug for LayoutPoint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)
}
}
impl fmt::Display for LayoutPoint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
impl LayoutPoint {
#[inline(always)]
pub const fn new(x: f32, y: f32) -> Self { Self { x, y } }
#[inline(always)]
pub const fn zero() -> Self { Self::new(0.0, 0.0) }
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub struct PixelSize { pub width: PixelValue, pub height: PixelValue }
impl PixelSize {
pub const fn new(width: PixelValue, height: PixelValue) -> Self {
Self {
width,
height,
}
}
pub const fn zero() -> Self {
Self::new(PixelValue::const_px(0), PixelValue::const_px(0))
}
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub struct LayoutSideOffsets {
pub top: FloatValue,
pub right: FloatValue,
pub bottom: FloatValue,
pub left: FloatValue,
}
#[derive(Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub struct ColorU { pub r: u8, pub g: u8, pub b: u8, pub a: u8 }
impl Default for ColorU { fn default() -> Self { ColorU::BLACK } }
impl fmt::Debug for ColorU {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "rgba({}, {}, {}, {})", self.r, self.g, self.b, self.a as f32 / 255.0)
}
}
impl fmt::Display for ColorU {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "rgba({}, {}, {}, {})", self.r, self.g, self.b, self.a as f32 / 255.0)
}
}
impl ColorU {
pub const RED: ColorU = ColorU { r: 255, g: 0, b: 0, a: 255 };
pub const WHITE: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 };
pub const BLACK: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 };
pub const TRANSPARENT: ColorU = ColorU { r: 0, g: 0, b: 0, a: 0 };
pub fn write_hash(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "#{:x}{:x}{:x}{:x}", self.r, self.g, self.b, self.a)
}
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct ColorF { pub r: f32, pub g: f32, pub b: f32, pub a: f32 }
impl Default for ColorF { fn default() -> Self { ColorF::BLACK } }
impl fmt::Display for ColorF {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "rgba({}, {}, {}, {})", self.r * 255.0, self.g * 255.0, self.b * 255.0, self.a)
}
}
impl ColorF {
pub const WHITE: ColorF = ColorF { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
pub const BLACK: ColorF = ColorF { r: 0.0, g: 0.0, b: 0.0, a: 1.0 };
pub const TRANSPARENT: ColorF = ColorF { r: 0.0, g: 0.0, b: 0.0, a: 0.0 };
}
impl From<ColorU> for ColorF {
fn from(input: ColorU) -> ColorF {
ColorF {
r: (input.r as f32) / 255.0,
g: (input.g as f32) / 255.0,
b: (input.b as f32) / 255.0,
a: (input.a as f32) / 255.0,
}
}
}
impl From<ColorF> for ColorU {
fn from(input: ColorF) -> ColorU {
ColorU {
r: (input.r.min(1.0) * 255.0) as u8,
g: (input.g.min(1.0) * 255.0) as u8,
b: (input.b.min(1.0) * 255.0) as u8,
a: (input.a.min(1.0) * 255.0) as u8,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub enum BorderDetails {
Normal(NormalBorder),
NinePatch(NinePatchBorder),
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub struct NormalBorder {
pub left: BorderSide,
pub right: BorderSide,
pub top: BorderSide,
pub bottom: BorderSide,
pub radius: Option<(
StyleBorderTopLeftRadius,
StyleBorderTopRightRadius,
StyleBorderBottomLeftRadius,
StyleBorderBottomRightRadius,
)>,
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub struct BorderSide {
pub color: ColorU,
pub style: BorderStyle,
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub enum BoxShadowClipMode {
Outset,
Inset,
}
impl fmt::Display for BoxShadowClipMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::BoxShadowClipMode::*;
match self {
Outset => write!(f, "outset"),
Inset => write!(f, "inset"),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub enum ExtendMode {
Clamp,
Repeat,
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub enum BorderStyle {
None,
Solid,
Double,
Dotted,
Dashed,
Hidden,
Groove,
Ridge,
Inset,
Outset,
}
impl fmt::Display for BorderStyle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::BorderStyle::*;
match self {
None => write!(f, "none"),
Solid => write!(f, "solid"),
Double => write!(f, "double"),
Dotted => write!(f, "dotted"),
Dashed => write!(f, "dashed"),
Hidden => write!(f, "hidden"),
Groove => write!(f, "groove"),
Ridge => write!(f, "ridge"),
Inset => write!(f, "inset"),
Outset => write!(f, "outset"),
}
}
}
impl BorderStyle {
pub fn normalize_border(self) -> Option<BorderStyleNoNone> {
match self {
BorderStyle::None => None,
BorderStyle::Solid => Some(BorderStyleNoNone::Solid),
BorderStyle::Double => Some(BorderStyleNoNone::Double),
BorderStyle::Dotted => Some(BorderStyleNoNone::Dotted),
BorderStyle::Dashed => Some(BorderStyleNoNone::Dashed),
BorderStyle::Hidden => Some(BorderStyleNoNone::Hidden),
BorderStyle::Groove => Some(BorderStyleNoNone::Groove),
BorderStyle::Ridge => Some(BorderStyleNoNone::Ridge),
BorderStyle::Inset => Some(BorderStyleNoNone::Inset),
BorderStyle::Outset => Some(BorderStyleNoNone::Outset),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub enum BorderStyleNoNone {
Solid,
Double,
Dotted,
Dashed,
Hidden,
Groove,
Ridge,
Inset,
Outset,
}
impl Default for BorderStyle {
fn default() -> Self {
BorderStyle::Solid
}
}
#[derive(Debug, Copy, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
pub struct NinePatchBorder {
}
macro_rules! derive_debug_zero {($struct:ident) => (
impl fmt::Debug for $struct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
)}
macro_rules! derive_display_zero {($struct:ident) => (
impl fmt::Display for $struct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
)}
macro_rules! impl_pixel_value {($struct:ident) => (
derive_debug_zero!($struct);
derive_display_zero!($struct);
impl $struct {
#[inline]
pub fn px(value: f32) -> Self {
$struct(PixelValue::px(value))
}
#[inline]
pub fn em(value: f32) -> Self {
$struct(PixelValue::em(value))
}
#[inline]
pub fn pt(value: f32) -> Self {
$struct(PixelValue::pt(value))
}
}
impl FormatAsCssValue for $struct {
fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.format_as_css_value(f)
}
}
)}
macro_rules! impl_percentage_value{($struct:ident) => (
impl ::std::fmt::Display for $struct {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}%", self.0.get())
}
}
impl ::std::fmt::Debug for $struct {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}%", self.0.get())
}
}
impl FormatAsCssValue for $struct {
fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}%", self.0.get())
}
}
)}
macro_rules! impl_float_value{($struct:ident) => (
impl ::std::fmt::Display for $struct {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", self.0.get())
}
}
impl ::std::fmt::Debug for $struct {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{}", self.0.get())
}
}
impl FormatAsCssValue for $struct {
fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.get())
}
}
)}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CombinedCssPropertyType {
BorderRadius,
Overflow,
Margin,
Border,
BorderLeft,
BorderRight,
BorderTop,
BorderBottom,
Padding,
BoxShadow,
}
impl fmt::Display for CombinedCssPropertyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let key = COMBINED_CSS_PROPERTIES_KEY_MAP.iter().find(|(v, _)| *v == *self).and_then(|(k, _)| Some(k)).unwrap();
write!(f, "{}", key)
}
}
impl CombinedCssPropertyType {
pub fn from_str(input: &str, map: &CssKeyMap) -> Option<Self> {
let input = input.trim();
map.shorthands.get(input).map(|x| *x)
}
pub fn to_str(&self, map: &CssKeyMap) -> &'static str {
map.shorthands.iter().find(|(_, v)| *v == self).map(|(k, _)| k).unwrap()
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CssKeyMap {
pub non_shorthands: BTreeMap<&'static str, CssPropertyType>,
pub shorthands: BTreeMap<&'static str, CombinedCssPropertyType>,
}
pub fn get_css_key_map() -> CssKeyMap {
CssKeyMap {
non_shorthands: CSS_PROPERTY_KEY_MAP.iter().map(|(v, k)| (*k, *v)).collect(),
shorthands: COMBINED_CSS_PROPERTIES_KEY_MAP.iter().map(|(v, k)| (*k, *v)).collect(),
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CssPropertyType {
TextColor,
FontSize,
FontFamily,
TextAlign,
LetterSpacing,
LineHeight,
WordSpacing,
TabWidth,
Cursor,
Display,
Float,
BoxSizing,
Width,
Height,
MinWidth,
MinHeight,
MaxWidth,
MaxHeight,
Position,
Top,
Right,
Left,
Bottom,
FlexWrap,
FlexDirection,
FlexGrow,
FlexShrink,
JustifyContent,
AlignItems,
AlignContent,
OverflowX,
OverflowY,
PaddingTop,
PaddingLeft,
PaddingRight,
PaddingBottom,
MarginTop,
MarginLeft,
MarginRight,
MarginBottom,
Background,
BackgroundImage, BackgroundColor, BackgroundPosition,
BackgroundSize,
BackgroundRepeat,
BorderTopLeftRadius,
BorderTopRightRadius,
BorderBottomLeftRadius,
BorderBottomRightRadius,
BorderTopColor,
BorderRightColor,
BorderLeftColor,
BorderBottomColor,
BorderTopStyle,
BorderRightStyle,
BorderLeftStyle,
BorderBottomStyle,
BorderTopWidth,
BorderRightWidth,
BorderLeftWidth,
BorderBottomWidth,
BoxShadowLeft,
BoxShadowRight,
BoxShadowTop,
BoxShadowBottom,
}
impl CssPropertyType {
pub fn from_str(input: &str, map: &CssKeyMap) -> Option<Self> {
let input = input.trim();
map.non_shorthands.get(input).and_then(|x| Some(*x))
}
pub fn to_str(&self, map: &CssKeyMap) -> &'static str {
map.non_shorthands.iter().find(|(_, v)| *v == self).and_then(|(k, _)| Some(k)).unwrap()
}
pub fn is_inheritable(&self) -> bool {
use self::CssPropertyType::*;
match self {
| TextColor
| FontFamily
| FontSize
| LineHeight
| TextAlign => true,
_ => false,
}
}
pub fn can_trigger_relayout(&self) -> bool {
use self::CssPropertyType::*;
match self {
| TextColor
| Cursor
| Background
| BackgroundPosition
| BackgroundSize
| BackgroundRepeat
| BackgroundImage
| BorderTopLeftRadius
| BorderTopRightRadius
| BorderBottomLeftRadius
| BorderBottomRightRadius
| BorderTopColor
| BorderRightColor
| BorderLeftColor
| BorderBottomColor
| BorderTopStyle
| BorderRightStyle
| BorderLeftStyle
| BorderBottomStyle
| BoxShadowLeft
| BoxShadowRight
| BoxShadowTop
| BoxShadowBottom
=> false,
_ => true,
}
}
}
impl fmt::Display for CssPropertyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let key = CSS_PROPERTY_KEY_MAP.iter().find(|(v, _)| *v == *self).and_then(|(k, _)| Some(k)).unwrap();
write!(f, "{}", key)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum CssProperty {
TextColor(CssPropertyValue<StyleTextColor>),
FontSize(CssPropertyValue<StyleFontSize>),
FontFamily(CssPropertyValue<StyleFontFamily>),
TextAlign(CssPropertyValue<StyleTextAlignmentHorz>),
LetterSpacing(CssPropertyValue<StyleLetterSpacing>),
LineHeight(CssPropertyValue<StyleLineHeight>),
WordSpacing(CssPropertyValue<StyleWordSpacing>),
TabWidth(CssPropertyValue<StyleTabWidth>),
Cursor(CssPropertyValue<StyleCursor>),
Display(CssPropertyValue<LayoutDisplay>),
Float(CssPropertyValue<LayoutFloat>),
BoxSizing(CssPropertyValue<LayoutBoxSizing>),
Width(CssPropertyValue<LayoutWidth>),
Height(CssPropertyValue<LayoutHeight>),
MinWidth(CssPropertyValue<LayoutMinWidth>),
MinHeight(CssPropertyValue<LayoutMinHeight>),
MaxWidth(CssPropertyValue<LayoutMaxWidth>),
MaxHeight(CssPropertyValue<LayoutMaxHeight>),
Position(CssPropertyValue<LayoutPosition>),
Top(CssPropertyValue<LayoutTop>),
Right(CssPropertyValue<LayoutRight>),
Left(CssPropertyValue<LayoutLeft>),
Bottom(CssPropertyValue<LayoutBottom>),
FlexWrap(CssPropertyValue<LayoutWrap>),
FlexDirection(CssPropertyValue<LayoutDirection>),
FlexGrow(CssPropertyValue<LayoutFlexGrow>),
FlexShrink(CssPropertyValue<LayoutFlexShrink>),
JustifyContent(CssPropertyValue<LayoutJustifyContent>),
AlignItems(CssPropertyValue<LayoutAlignItems>),
AlignContent(CssPropertyValue<LayoutAlignContent>),
BackgroundContent(CssPropertyValue<StyleBackgroundContent>),
BackgroundPosition(CssPropertyValue<StyleBackgroundPosition>),
BackgroundSize(CssPropertyValue<StyleBackgroundSize>),
BackgroundRepeat(CssPropertyValue<StyleBackgroundRepeat>),
OverflowX(CssPropertyValue<Overflow>),
OverflowY(CssPropertyValue<Overflow>),
PaddingTop(CssPropertyValue<LayoutPaddingTop>),
PaddingLeft(CssPropertyValue<LayoutPaddingLeft>),
PaddingRight(CssPropertyValue<LayoutPaddingRight>),
PaddingBottom(CssPropertyValue<LayoutPaddingBottom>),
MarginTop(CssPropertyValue<LayoutMarginTop>),
MarginLeft(CssPropertyValue<LayoutMarginLeft>),
MarginRight(CssPropertyValue<LayoutMarginRight>),
MarginBottom(CssPropertyValue<LayoutMarginBottom>),
BorderTopLeftRadius(CssPropertyValue<StyleBorderTopLeftRadius>),
BorderTopRightRadius(CssPropertyValue<StyleBorderTopRightRadius>),
BorderBottomLeftRadius(CssPropertyValue<StyleBorderBottomLeftRadius>),
BorderBottomRightRadius(CssPropertyValue<StyleBorderBottomRightRadius>),
BorderTopColor(CssPropertyValue<StyleBorderTopColor>),
BorderRightColor(CssPropertyValue<StyleBorderRightColor>),
BorderLeftColor(CssPropertyValue<StyleBorderLeftColor>),
BorderBottomColor(CssPropertyValue<StyleBorderBottomColor>),
BorderTopStyle(CssPropertyValue<StyleBorderTopStyle>),
BorderRightStyle(CssPropertyValue<StyleBorderRightStyle>),
BorderLeftStyle(CssPropertyValue<StyleBorderLeftStyle>),
BorderBottomStyle(CssPropertyValue<StyleBorderBottomStyle>),
BorderTopWidth(CssPropertyValue<StyleBorderTopWidth>),
BorderRightWidth(CssPropertyValue<StyleBorderRightWidth>),
BorderLeftWidth(CssPropertyValue<StyleBorderLeftWidth>),
BorderBottomWidth(CssPropertyValue<StyleBorderBottomWidth>),
BoxShadowLeft(CssPropertyValue<BoxShadowPreDisplayItem>),
BoxShadowRight(CssPropertyValue<BoxShadowPreDisplayItem>),
BoxShadowTop(CssPropertyValue<BoxShadowPreDisplayItem>),
BoxShadowBottom(CssPropertyValue<BoxShadowPreDisplayItem>),
}
macro_rules! css_property_from_type {($prop_type:expr, $content_type:ident) => ({
match $prop_type {
CssPropertyType::TextColor => CssProperty::TextColor(CssPropertyValue::$content_type),
CssPropertyType::FontSize => CssProperty::FontSize(CssPropertyValue::$content_type),
CssPropertyType::FontFamily => CssProperty::FontFamily(CssPropertyValue::$content_type),
CssPropertyType::TextAlign => CssProperty::TextAlign(CssPropertyValue::$content_type),
CssPropertyType::LetterSpacing => CssProperty::LetterSpacing(CssPropertyValue::$content_type),
CssPropertyType::LineHeight => CssProperty::LineHeight(CssPropertyValue::$content_type),
CssPropertyType::WordSpacing => CssProperty::WordSpacing(CssPropertyValue::$content_type),
CssPropertyType::TabWidth => CssProperty::TabWidth(CssPropertyValue::$content_type),
CssPropertyType::Cursor => CssProperty::Cursor(CssPropertyValue::$content_type),
CssPropertyType::Display => CssProperty::Display(CssPropertyValue::$content_type),
CssPropertyType::Float => CssProperty::Float(CssPropertyValue::$content_type),
CssPropertyType::BoxSizing => CssProperty::BoxSizing(CssPropertyValue::$content_type),
CssPropertyType::Width => CssProperty::Width(CssPropertyValue::$content_type),
CssPropertyType::Height => CssProperty::Height(CssPropertyValue::$content_type),
CssPropertyType::MinWidth => CssProperty::MinWidth(CssPropertyValue::$content_type),
CssPropertyType::MinHeight => CssProperty::MinHeight(CssPropertyValue::$content_type),
CssPropertyType::MaxWidth => CssProperty::MaxWidth(CssPropertyValue::$content_type),
CssPropertyType::MaxHeight => CssProperty::MaxHeight(CssPropertyValue::$content_type),
CssPropertyType::Position => CssProperty::Position(CssPropertyValue::$content_type),
CssPropertyType::Top => CssProperty::Top(CssPropertyValue::$content_type),
CssPropertyType::Right => CssProperty::Right(CssPropertyValue::$content_type),
CssPropertyType::Left => CssProperty::Left(CssPropertyValue::$content_type),
CssPropertyType::Bottom => CssProperty::Bottom(CssPropertyValue::$content_type),
CssPropertyType::FlexWrap => CssProperty::FlexWrap(CssPropertyValue::$content_type),
CssPropertyType::FlexDirection => CssProperty::FlexDirection(CssPropertyValue::$content_type),
CssPropertyType::FlexGrow => CssProperty::FlexGrow(CssPropertyValue::$content_type),
CssPropertyType::FlexShrink => CssProperty::FlexShrink(CssPropertyValue::$content_type),
CssPropertyType::JustifyContent => CssProperty::JustifyContent(CssPropertyValue::$content_type),
CssPropertyType::AlignItems => CssProperty::AlignItems(CssPropertyValue::$content_type),
CssPropertyType::AlignContent => CssProperty::AlignContent(CssPropertyValue::$content_type),
CssPropertyType::OverflowX => CssProperty::OverflowX(CssPropertyValue::$content_type),
CssPropertyType::OverflowY => CssProperty::OverflowY(CssPropertyValue::$content_type),
CssPropertyType::PaddingTop => CssProperty::PaddingTop(CssPropertyValue::$content_type),
CssPropertyType::PaddingLeft => CssProperty::PaddingLeft(CssPropertyValue::$content_type),
CssPropertyType::PaddingRight => CssProperty::PaddingRight(CssPropertyValue::$content_type),
CssPropertyType::PaddingBottom => CssProperty::PaddingBottom(CssPropertyValue::$content_type),
CssPropertyType::MarginTop => CssProperty::MarginTop(CssPropertyValue::$content_type),
CssPropertyType::MarginLeft => CssProperty::MarginLeft(CssPropertyValue::$content_type),
CssPropertyType::MarginRight => CssProperty::MarginRight(CssPropertyValue::$content_type),
CssPropertyType::MarginBottom => CssProperty::MarginBottom(CssPropertyValue::$content_type),
CssPropertyType::Background => CssProperty::BackgroundContent(CssPropertyValue::$content_type),
CssPropertyType::BackgroundImage => CssProperty::BackgroundContent(CssPropertyValue::$content_type), CssPropertyType::BackgroundColor => CssProperty::BackgroundContent(CssPropertyValue::$content_type), CssPropertyType::BackgroundPosition => CssProperty::BackgroundPosition(CssPropertyValue::$content_type),
CssPropertyType::BackgroundSize => CssProperty::BackgroundSize(CssPropertyValue::$content_type),
CssPropertyType::BackgroundRepeat => CssProperty::BackgroundRepeat(CssPropertyValue::$content_type),
CssPropertyType::BorderTopLeftRadius => CssProperty::BorderTopLeftRadius(CssPropertyValue::$content_type),
CssPropertyType::BorderTopRightRadius => CssProperty::BorderTopRightRadius(CssPropertyValue::$content_type),
CssPropertyType::BorderBottomLeftRadius => CssProperty::BorderBottomLeftRadius(CssPropertyValue::$content_type),
CssPropertyType::BorderBottomRightRadius => CssProperty::BorderBottomRightRadius(CssPropertyValue::$content_type),
CssPropertyType::BorderTopColor => CssProperty::BorderTopColor(CssPropertyValue::$content_type),
CssPropertyType::BorderRightColor => CssProperty::BorderRightColor(CssPropertyValue::$content_type),
CssPropertyType::BorderLeftColor => CssProperty::BorderLeftColor(CssPropertyValue::$content_type),
CssPropertyType::BorderBottomColor => CssProperty::BorderBottomColor(CssPropertyValue::$content_type),
CssPropertyType::BorderTopStyle => CssProperty::BorderTopStyle(CssPropertyValue::$content_type),
CssPropertyType::BorderRightStyle => CssProperty::BorderRightStyle(CssPropertyValue::$content_type),
CssPropertyType::BorderLeftStyle => CssProperty::BorderLeftStyle(CssPropertyValue::$content_type),
CssPropertyType::BorderBottomStyle => CssProperty::BorderBottomStyle(CssPropertyValue::$content_type),
CssPropertyType::BorderTopWidth => CssProperty::BorderTopWidth(CssPropertyValue::$content_type),
CssPropertyType::BorderRightWidth => CssProperty::BorderRightWidth(CssPropertyValue::$content_type),
CssPropertyType::BorderLeftWidth => CssProperty::BorderLeftWidth(CssPropertyValue::$content_type),
CssPropertyType::BorderBottomWidth => CssProperty::BorderBottomWidth(CssPropertyValue::$content_type),
CssPropertyType::BoxShadowLeft => CssProperty::BoxShadowLeft(CssPropertyValue::$content_type),
CssPropertyType::BoxShadowRight => CssProperty::BoxShadowRight(CssPropertyValue::$content_type),
CssPropertyType::BoxShadowTop => CssProperty::BoxShadowTop(CssPropertyValue::$content_type),
CssPropertyType::BoxShadowBottom => CssProperty::BoxShadowBottom(CssPropertyValue::$content_type),
}
})}
impl CssProperty {
pub fn get_type(&self) -> CssPropertyType {
match &self {
CssProperty::TextColor(_) => CssPropertyType::TextColor,
CssProperty::FontSize(_) => CssPropertyType::FontSize,
CssProperty::FontFamily(_) => CssPropertyType::FontFamily,
CssProperty::TextAlign(_) => CssPropertyType::TextAlign,
CssProperty::LetterSpacing(_) => CssPropertyType::LetterSpacing,
CssProperty::LineHeight(_) => CssPropertyType::LineHeight,
CssProperty::WordSpacing(_) => CssPropertyType::WordSpacing,
CssProperty::TabWidth(_) => CssPropertyType::TabWidth,
CssProperty::Cursor(_) => CssPropertyType::Cursor,
CssProperty::Display(_) => CssPropertyType::Display,
CssProperty::Float(_) => CssPropertyType::Float,
CssProperty::BoxSizing(_) => CssPropertyType::BoxSizing,
CssProperty::Width(_) => CssPropertyType::Width,
CssProperty::Height(_) => CssPropertyType::Height,
CssProperty::MinWidth(_) => CssPropertyType::MinWidth,
CssProperty::MinHeight(_) => CssPropertyType::MinHeight,
CssProperty::MaxWidth(_) => CssPropertyType::MaxWidth,
CssProperty::MaxHeight(_) => CssPropertyType::MaxHeight,
CssProperty::Position(_) => CssPropertyType::Position,
CssProperty::Top(_) => CssPropertyType::Top,
CssProperty::Right(_) => CssPropertyType::Right,
CssProperty::Left(_) => CssPropertyType::Left,
CssProperty::Bottom(_) => CssPropertyType::Bottom,
CssProperty::FlexWrap(_) => CssPropertyType::FlexWrap,
CssProperty::FlexDirection(_) => CssPropertyType::FlexDirection,
CssProperty::FlexGrow(_) => CssPropertyType::FlexGrow,
CssProperty::FlexShrink(_) => CssPropertyType::FlexShrink,
CssProperty::JustifyContent(_) => CssPropertyType::JustifyContent,
CssProperty::AlignItems(_) => CssPropertyType::AlignItems,
CssProperty::AlignContent(_) => CssPropertyType::AlignContent,
CssProperty::BackgroundContent(_) => CssPropertyType::BackgroundImage, CssProperty::BackgroundPosition(_) => CssPropertyType::BackgroundPosition,
CssProperty::BackgroundSize(_) => CssPropertyType::BackgroundSize,
CssProperty::BackgroundRepeat(_) => CssPropertyType::BackgroundRepeat,
CssProperty::OverflowX(_) => CssPropertyType::OverflowX,
CssProperty::OverflowY(_) => CssPropertyType::OverflowY,
CssProperty::PaddingTop(_) => CssPropertyType::PaddingTop,
CssProperty::PaddingLeft(_) => CssPropertyType::PaddingLeft,
CssProperty::PaddingRight(_) => CssPropertyType::PaddingRight,
CssProperty::PaddingBottom(_) => CssPropertyType::PaddingBottom,
CssProperty::MarginTop(_) => CssPropertyType::MarginTop,
CssProperty::MarginLeft(_) => CssPropertyType::MarginLeft,
CssProperty::MarginRight(_) => CssPropertyType::MarginRight,
CssProperty::MarginBottom(_) => CssPropertyType::MarginBottom,
CssProperty::BorderTopLeftRadius(_) => CssPropertyType::BorderTopLeftRadius,
CssProperty::BorderTopRightRadius(_) => CssPropertyType::BorderTopRightRadius,
CssProperty::BorderBottomLeftRadius(_) => CssPropertyType::BorderBottomLeftRadius,
CssProperty::BorderBottomRightRadius(_) => CssPropertyType::BorderBottomRightRadius,
CssProperty::BorderTopColor(_) => CssPropertyType::BorderTopColor,
CssProperty::BorderRightColor(_) => CssPropertyType::BorderRightColor,
CssProperty::BorderLeftColor(_) => CssPropertyType::BorderLeftColor,
CssProperty::BorderBottomColor(_) => CssPropertyType::BorderBottomColor,
CssProperty::BorderTopStyle(_) => CssPropertyType::BorderTopStyle,
CssProperty::BorderRightStyle(_) => CssPropertyType::BorderRightStyle,
CssProperty::BorderLeftStyle(_) => CssPropertyType::BorderLeftStyle,
CssProperty::BorderBottomStyle(_) => CssPropertyType::BorderBottomStyle,
CssProperty::BorderTopWidth(_) => CssPropertyType::BorderTopWidth,
CssProperty::BorderRightWidth(_) => CssPropertyType::BorderRightWidth,
CssProperty::BorderLeftWidth(_) => CssPropertyType::BorderLeftWidth,
CssProperty::BorderBottomWidth(_) => CssPropertyType::BorderBottomWidth,
CssProperty::BoxShadowLeft(_) => CssPropertyType::BoxShadowLeft,
CssProperty::BoxShadowRight(_) => CssPropertyType::BoxShadowRight,
CssProperty::BoxShadowTop(_) => CssPropertyType::BoxShadowTop,
CssProperty::BoxShadowBottom(_) => CssPropertyType::BoxShadowBottom,
}
}
pub fn none(prop_type: CssPropertyType) -> Self {
css_property_from_type!(prop_type, None)
}
pub fn auto(prop_type: CssPropertyType) -> Self {
css_property_from_type!(prop_type, Auto)
}
pub fn initial(prop_type: CssPropertyType) -> Self {
css_property_from_type!(prop_type, Initial)
}
pub fn inherit(prop_type: CssPropertyType) -> Self {
css_property_from_type!(prop_type, Inherit)
}
pub const fn text_color(input: StyleTextColor) -> Self { CssProperty::TextColor(CssPropertyValue::Exact(input)) }
pub const fn font_size(input: StyleFontSize) -> Self { CssProperty::FontSize(CssPropertyValue::Exact(input)) }
pub const fn font_family(input: StyleFontFamily) -> Self { CssProperty::FontFamily(CssPropertyValue::Exact(input)) }
pub const fn text_align(input: StyleTextAlignmentHorz) -> Self { CssProperty::TextAlign(CssPropertyValue::Exact(input)) }
pub const fn letter_spacing(input: StyleLetterSpacing) -> Self { CssProperty::LetterSpacing(CssPropertyValue::Exact(input)) }
pub const fn line_height(input: StyleLineHeight) -> Self { CssProperty::LineHeight(CssPropertyValue::Exact(input)) }
pub const fn word_spacing(input: StyleWordSpacing) -> Self { CssProperty::WordSpacing(CssPropertyValue::Exact(input)) }
pub const fn tab_width(input: StyleTabWidth) -> Self { CssProperty::TabWidth(CssPropertyValue::Exact(input)) }
pub const fn cursor(input: StyleCursor) -> Self { CssProperty::Cursor(CssPropertyValue::Exact(input)) }
pub const fn display(input: LayoutDisplay) -> Self { CssProperty::Display(CssPropertyValue::Exact(input)) }
pub const fn float(input: LayoutFloat) -> Self { CssProperty::Float(CssPropertyValue::Exact(input)) }
pub const fn box_sizing(input: LayoutBoxSizing) -> Self { CssProperty::BoxSizing(CssPropertyValue::Exact(input)) }
pub const fn width(input: LayoutWidth) -> Self { CssProperty::Width(CssPropertyValue::Exact(input)) }
pub const fn height(input: LayoutHeight) -> Self { CssProperty::Height(CssPropertyValue::Exact(input)) }
pub const fn min_width(input: LayoutMinWidth) -> Self { CssProperty::MinWidth(CssPropertyValue::Exact(input)) }
pub const fn min_height(input: LayoutMinHeight) -> Self { CssProperty::MinHeight(CssPropertyValue::Exact(input)) }
pub const fn max_width(input: LayoutMaxWidth) -> Self { CssProperty::MaxWidth(CssPropertyValue::Exact(input)) }
pub const fn max_height(input: LayoutMaxHeight) -> Self { CssProperty::MaxHeight(CssPropertyValue::Exact(input)) }
pub const fn position(input: LayoutPosition) -> Self { CssProperty::Position(CssPropertyValue::Exact(input)) }
pub const fn top(input: LayoutTop) -> Self { CssProperty::Top(CssPropertyValue::Exact(input)) }
pub const fn right(input: LayoutRight) -> Self { CssProperty::Right(CssPropertyValue::Exact(input)) }
pub const fn left(input: LayoutLeft) -> Self { CssProperty::Left(CssPropertyValue::Exact(input)) }
pub const fn bottom(input: LayoutBottom) -> Self { CssProperty::Bottom(CssPropertyValue::Exact(input)) }
pub const fn flex_wrap(input: LayoutWrap) -> Self { CssProperty::FlexWrap(CssPropertyValue::Exact(input)) }
pub const fn flex_direction(input: LayoutDirection) -> Self { CssProperty::FlexDirection(CssPropertyValue::Exact(input)) }
pub const fn flex_grow(input: LayoutFlexGrow) -> Self { CssProperty::FlexGrow(CssPropertyValue::Exact(input)) }
pub const fn flex_shrink(input: LayoutFlexShrink) -> Self { CssProperty::FlexShrink(CssPropertyValue::Exact(input)) }
pub const fn justify_content(input: LayoutJustifyContent) -> Self { CssProperty::JustifyContent(CssPropertyValue::Exact(input)) }
pub const fn align_items(input: LayoutAlignItems) -> Self { CssProperty::AlignItems(CssPropertyValue::Exact(input)) }
pub const fn align_content(input: LayoutAlignContent) -> Self { CssProperty::AlignContent(CssPropertyValue::Exact(input)) }
pub const fn background_content(input: StyleBackgroundContent) -> Self { CssProperty::BackgroundContent(CssPropertyValue::Exact(input)) }
pub const fn background_position(input: StyleBackgroundPosition) -> Self { CssProperty::BackgroundPosition(CssPropertyValue::Exact(input)) }
pub const fn background_size(input: StyleBackgroundSize) -> Self { CssProperty::BackgroundSize(CssPropertyValue::Exact(input)) }
pub const fn background_repeat(input: StyleBackgroundRepeat) -> Self { CssProperty::BackgroundRepeat(CssPropertyValue::Exact(input)) }
pub const fn overflow_x(input: Overflow) -> Self { CssProperty::OverflowX(CssPropertyValue::Exact(input)) }
pub const fn overflow_y(input: Overflow) -> Self { CssProperty::OverflowY(CssPropertyValue::Exact(input)) }
pub const fn padding_top(input: LayoutPaddingTop) -> Self { CssProperty::PaddingTop(CssPropertyValue::Exact(input)) }
pub const fn padding_left(input: LayoutPaddingLeft) -> Self { CssProperty::PaddingLeft(CssPropertyValue::Exact(input)) }
pub const fn padding_right(input: LayoutPaddingRight) -> Self { CssProperty::PaddingRight(CssPropertyValue::Exact(input)) }
pub const fn padding_bottom(input: LayoutPaddingBottom) -> Self { CssProperty::PaddingBottom(CssPropertyValue::Exact(input)) }
pub const fn margin_top(input: LayoutMarginTop) -> Self { CssProperty::MarginTop(CssPropertyValue::Exact(input)) }
pub const fn margin_left(input: LayoutMarginLeft) -> Self { CssProperty::MarginLeft(CssPropertyValue::Exact(input)) }
pub const fn margin_right(input: LayoutMarginRight) -> Self { CssProperty::MarginRight(CssPropertyValue::Exact(input)) }
pub const fn margin_bottom(input: LayoutMarginBottom) -> Self { CssProperty::MarginBottom(CssPropertyValue::Exact(input)) }
pub const fn border_top_left_radius(input: StyleBorderTopLeftRadius) -> Self { CssProperty::BorderTopLeftRadius(CssPropertyValue::Exact(input)) }
pub const fn border_top_right_radius(input: StyleBorderTopRightRadius) -> Self { CssProperty::BorderTopRightRadius(CssPropertyValue::Exact(input)) }
pub const fn border_bottom_left_radius(input: StyleBorderBottomLeftRadius) -> Self { CssProperty::BorderBottomLeftRadius(CssPropertyValue::Exact(input)) }
pub const fn border_bottom_right_radius(input: StyleBorderBottomRightRadius) -> Self { CssProperty::BorderBottomRightRadius(CssPropertyValue::Exact(input)) }
pub const fn border_top_color(input: StyleBorderTopColor) -> Self { CssProperty::BorderTopColor(CssPropertyValue::Exact(input)) }
pub const fn border_right_color(input: StyleBorderRightColor) -> Self { CssProperty::BorderRightColor(CssPropertyValue::Exact(input)) }
pub const fn border_left_color(input: StyleBorderLeftColor) -> Self { CssProperty::BorderLeftColor(CssPropertyValue::Exact(input)) }
pub const fn border_bottom_color(input: StyleBorderBottomColor) -> Self { CssProperty::BorderBottomColor(CssPropertyValue::Exact(input)) }
pub const fn border_top_style(input: StyleBorderTopStyle) -> Self { CssProperty::BorderTopStyle(CssPropertyValue::Exact(input)) }
pub const fn border_right_style(input: StyleBorderRightStyle) -> Self { CssProperty::BorderRightStyle(CssPropertyValue::Exact(input)) }
pub const fn border_left_style(input: StyleBorderLeftStyle) -> Self { CssProperty::BorderLeftStyle(CssPropertyValue::Exact(input)) }
pub const fn border_bottom_style(input: StyleBorderBottomStyle) -> Self { CssProperty::BorderBottomStyle(CssPropertyValue::Exact(input)) }
pub const fn border_top_width(input: StyleBorderTopWidth) -> Self { CssProperty::BorderTopWidth(CssPropertyValue::Exact(input)) }
pub const fn border_right_width(input: StyleBorderRightWidth) -> Self { CssProperty::BorderRightWidth(CssPropertyValue::Exact(input)) }
pub const fn border_left_width(input: StyleBorderLeftWidth) -> Self { CssProperty::BorderLeftWidth(CssPropertyValue::Exact(input)) }
pub const fn border_bottom_width(input: StyleBorderBottomWidth) -> Self { CssProperty::BorderBottomWidth(CssPropertyValue::Exact(input)) }
pub const fn box_shadow_left(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowLeft(CssPropertyValue::Exact(input)) }
pub const fn box_shadow_right(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowRight(CssPropertyValue::Exact(input)) }
pub const fn box_shadow_top(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowTop(CssPropertyValue::Exact(input)) }
pub const fn box_shadow_bottom(input: BoxShadowPreDisplayItem) -> Self { CssProperty::BoxShadowBottom(CssPropertyValue::Exact(input)) }
}
macro_rules! impl_from_css_prop {
($a:ident, $b:ident::$enum_type:ident) => {
impl From<$a> for $b {
fn from(e: $a) -> Self {
$b::$enum_type(CssPropertyValue::from(e))
}
}
};
}
impl_from_css_prop!(StyleTextColor, CssProperty::TextColor);
impl_from_css_prop!(StyleFontSize, CssProperty::FontSize);
impl_from_css_prop!(StyleFontFamily, CssProperty::FontFamily);
impl_from_css_prop!(StyleTextAlignmentHorz, CssProperty::TextAlign);
impl_from_css_prop!(StyleLetterSpacing, CssProperty::LetterSpacing);
impl_from_css_prop!(StyleLineHeight, CssProperty::LineHeight);
impl_from_css_prop!(StyleWordSpacing, CssProperty::WordSpacing);
impl_from_css_prop!(StyleTabWidth, CssProperty::TabWidth);
impl_from_css_prop!(StyleCursor, CssProperty::Cursor);
impl_from_css_prop!(LayoutDisplay, CssProperty::Display);
impl_from_css_prop!(LayoutFloat, CssProperty::Float);
impl_from_css_prop!(LayoutBoxSizing, CssProperty::BoxSizing);
impl_from_css_prop!(LayoutWidth, CssProperty::Width);
impl_from_css_prop!(LayoutHeight, CssProperty::Height);
impl_from_css_prop!(LayoutMinWidth, CssProperty::MinWidth);
impl_from_css_prop!(LayoutMinHeight, CssProperty::MinHeight);
impl_from_css_prop!(LayoutMaxWidth, CssProperty::MaxWidth);
impl_from_css_prop!(LayoutMaxHeight, CssProperty::MaxHeight);
impl_from_css_prop!(LayoutPosition, CssProperty::Position);
impl_from_css_prop!(LayoutTop, CssProperty::Top);
impl_from_css_prop!(LayoutRight, CssProperty::Right);
impl_from_css_prop!(LayoutLeft, CssProperty::Left);
impl_from_css_prop!(LayoutBottom, CssProperty::Bottom);
impl_from_css_prop!(LayoutWrap, CssProperty::FlexWrap);
impl_from_css_prop!(LayoutDirection, CssProperty::FlexDirection);
impl_from_css_prop!(LayoutFlexGrow, CssProperty::FlexGrow);
impl_from_css_prop!(LayoutFlexShrink, CssProperty::FlexShrink);
impl_from_css_prop!(LayoutJustifyContent, CssProperty::JustifyContent);
impl_from_css_prop!(LayoutAlignItems, CssProperty::AlignItems);
impl_from_css_prop!(LayoutAlignContent, CssProperty::AlignContent);
impl_from_css_prop!(StyleBackgroundContent, CssProperty::BackgroundContent);
impl_from_css_prop!(StyleBackgroundPosition, CssProperty::BackgroundPosition);
impl_from_css_prop!(StyleBackgroundSize, CssProperty::BackgroundSize);
impl_from_css_prop!(StyleBackgroundRepeat, CssProperty::BackgroundRepeat);
impl_from_css_prop!(LayoutPaddingTop, CssProperty::PaddingTop);
impl_from_css_prop!(LayoutPaddingLeft, CssProperty::PaddingLeft);
impl_from_css_prop!(LayoutPaddingRight, CssProperty::PaddingRight);
impl_from_css_prop!(LayoutPaddingBottom, CssProperty::PaddingBottom);
impl_from_css_prop!(LayoutMarginTop, CssProperty::MarginTop);
impl_from_css_prop!(LayoutMarginLeft, CssProperty::MarginLeft);
impl_from_css_prop!(LayoutMarginRight, CssProperty::MarginRight);
impl_from_css_prop!(LayoutMarginBottom, CssProperty::MarginBottom);
impl_from_css_prop!(StyleBorderTopLeftRadius, CssProperty::BorderTopLeftRadius);
impl_from_css_prop!(StyleBorderTopRightRadius, CssProperty::BorderTopRightRadius);
impl_from_css_prop!(StyleBorderBottomLeftRadius, CssProperty::BorderBottomLeftRadius);
impl_from_css_prop!(StyleBorderBottomRightRadius, CssProperty::BorderBottomRightRadius);
impl_from_css_prop!(StyleBorderTopColor, CssProperty::BorderTopColor);
impl_from_css_prop!(StyleBorderRightColor, CssProperty::BorderRightColor);
impl_from_css_prop!(StyleBorderLeftColor, CssProperty::BorderLeftColor);
impl_from_css_prop!(StyleBorderBottomColor, CssProperty::BorderBottomColor);
impl_from_css_prop!(StyleBorderTopStyle, CssProperty::BorderTopStyle);
impl_from_css_prop!(StyleBorderRightStyle, CssProperty::BorderRightStyle);
impl_from_css_prop!(StyleBorderLeftStyle, CssProperty::BorderLeftStyle);
impl_from_css_prop!(StyleBorderBottomStyle, CssProperty::BorderBottomStyle);
impl_from_css_prop!(StyleBorderTopWidth, CssProperty::BorderTopWidth);
impl_from_css_prop!(StyleBorderRightWidth, CssProperty::BorderRightWidth);
impl_from_css_prop!(StyleBorderLeftWidth, CssProperty::BorderLeftWidth);
impl_from_css_prop!(StyleBorderBottomWidth, CssProperty::BorderBottomWidth);
const FP_PRECISION_MULTIPLIER: f32 = 1000.0;
const FP_PRECISION_MULTIPLIER_CONST: isize = FP_PRECISION_MULTIPLIER as isize;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PixelValueNoPercent(pub PixelValue);
impl fmt::Display for PixelValueNoPercent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl PixelValueNoPercent {
pub fn to_pixels(&self) -> f32 {
self.0.to_pixels(0.0)
}
}
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PixelValue {
pub metric: SizeMetric,
pub number: FloatValue,
}
impl fmt::Debug for PixelValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.number, self.metric)
}
}
impl fmt::Display for PixelValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.number, self.metric)
}
}
impl FormatAsCssValue for PixelValue {
fn format_as_css_value(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.number, self.metric)
}
}
impl fmt::Display for SizeMetric {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SizeMetric::*;
match self {
Px => write!(f, "px"),
Pt => write!(f, "pt"),
Em => write!(f, "pt"),
Percent => write!(f, "%"),
}
}
}
impl PixelValue {
#[inline]
pub const fn zero() -> Self {
const ZERO_PX: PixelValue = PixelValue::const_px(0);
ZERO_PX
}
#[inline]
pub const fn const_px(value: isize) -> Self {
Self::const_from_metric(SizeMetric::Px, value)
}
#[inline]
pub const fn const_em(value: isize) -> Self {
Self::const_from_metric(SizeMetric::Em, value)
}
#[inline]
pub const fn const_pt(value: isize) -> Self {
Self::const_from_metric(SizeMetric::Pt, value)
}
#[inline]
pub const fn const_percent(value: isize) -> Self {
Self::const_from_metric(SizeMetric::Percent, value)
}
#[inline]
pub const fn const_from_metric(metric: SizeMetric, value: isize) -> Self {
Self {
metric: metric,
number: FloatValue::const_new(value),
}
}
#[inline]
pub fn px(value: f32) -> Self {
Self::from_metric(SizeMetric::Px, value)
}
#[inline]
pub fn em(value: f32) -> Self {
Self::from_metric(SizeMetric::Em, value)
}
#[inline]
pub fn pt(value: f32) -> Self {
Self::from_metric(SizeMetric::Pt, value)
}
#[inline]
pub fn percent(value: f32) -> Self {
Self::from_metric(SizeMetric::Percent, value)
}
#[inline]
pub fn from_metric(metric: SizeMetric, value: f32) -> Self {
Self {
metric: metric,
number: FloatValue::new(value),
}
}
#[inline]
pub fn to_pixels(&self, percent_resolve: f32) -> f32 {
match self.metric {
SizeMetric::Px => self.number.get(),
SizeMetric::Pt => self.number.get() * PT_TO_PX,
SizeMetric::Em => self.number.get() * EM_HEIGHT,
SizeMetric::Percent => self.number.get() / 100.0 * percent_resolve,
}
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PercentageValue {
number: FloatValue,
}
impl fmt::Display for PercentageValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}%", self.get())
}
}
impl PercentageValue {
pub const fn const_new(value: isize) -> Self {
Self { number: FloatValue::const_new(value) }
}
pub fn new(value: f32) -> Self {
Self { number: value.into() }
}
pub fn get(&self) -> f32 {
self.number.get()
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FloatValue {
pub number: isize,
}
impl fmt::Display for FloatValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.get())
}
}
impl Default for FloatValue {
fn default() -> Self {
const DEFAULT_FLV: FloatValue = FloatValue::const_new(0);
DEFAULT_FLV
}
}
impl FloatValue {
pub const fn const_new(value: isize) -> Self {
Self { number: value * FP_PRECISION_MULTIPLIER_CONST }
}
pub fn new(value: f32) -> Self {
Self { number: (value * FP_PRECISION_MULTIPLIER) as isize }
}
pub fn get(&self) -> f32 {
self.number as f32 / FP_PRECISION_MULTIPLIER
}
}
impl From<f32> for FloatValue {
fn from(val: f32) -> Self {
Self::new(val)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SizeMetric {
Px,
Pt,
Em,
Percent,
}
impl Default for SizeMetric {
fn default() -> Self { SizeMetric::Px }
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StyleBackgroundSize {
ExactSize(PixelValue, PixelValue),
Contain,
Cover,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBackgroundPosition {
pub horizontal: BackgroundPositionHorizontal,
pub vertical: BackgroundPositionVertical,
}
impl Default for StyleBackgroundPosition {
fn default() -> Self {
StyleBackgroundPosition {
horizontal: BackgroundPositionHorizontal::Left,
vertical: BackgroundPositionVertical::Top,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BackgroundPositionHorizontal {
Left,
Center,
Right,
Exact(PixelValue),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BackgroundPositionVertical {
Top,
Center,
Bottom,
Exact(PixelValue),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StyleBackgroundRepeat {
NoRepeat,
Repeat,
RepeatX,
RepeatY,
}
impl Default for StyleBackgroundRepeat {
fn default() -> Self {
StyleBackgroundRepeat::Repeat
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleTextColor(pub ColorU);
derive_debug_zero!(StyleTextColor);
derive_display_zero!(StyleTextColor);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderTopLeftRadius(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderBottomLeftRadius(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderTopRightRadius(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderBottomRightRadius(pub PixelValue);
impl_pixel_value!(StyleBorderTopLeftRadius);
impl_pixel_value!(StyleBorderBottomLeftRadius);
impl_pixel_value!(StyleBorderTopRightRadius);
impl_pixel_value!(StyleBorderBottomRightRadius);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderTopWidth(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderLeftWidth(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderRightWidth(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderBottomWidth(pub PixelValue);
impl_pixel_value!(StyleBorderTopWidth);
impl_pixel_value!(StyleBorderLeftWidth);
impl_pixel_value!(StyleBorderRightWidth);
impl_pixel_value!(StyleBorderBottomWidth);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderTopStyle(pub BorderStyle);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderLeftStyle(pub BorderStyle);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderRightStyle(pub BorderStyle);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderBottomStyle(pub BorderStyle);
derive_debug_zero!(StyleBorderTopStyle);
derive_debug_zero!(StyleBorderLeftStyle);
derive_debug_zero!(StyleBorderBottomStyle);
derive_debug_zero!(StyleBorderRightStyle);
derive_display_zero!(StyleBorderTopStyle);
derive_display_zero!(StyleBorderLeftStyle);
derive_display_zero!(StyleBorderBottomStyle);
derive_display_zero!(StyleBorderRightStyle);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderTopColor(pub ColorU);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderLeftColor(pub ColorU);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderRightColor(pub ColorU);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderBottomColor(pub ColorU);
derive_debug_zero!(StyleBorderTopColor);
derive_debug_zero!(StyleBorderLeftColor);
derive_debug_zero!(StyleBorderRightColor);
derive_debug_zero!(StyleBorderBottomColor);
derive_display_zero!(StyleBorderTopColor);
derive_display_zero!(StyleBorderLeftColor);
derive_display_zero!(StyleBorderRightColor);
derive_display_zero!(StyleBorderBottomColor);
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleBorderSide {
pub border_width: PixelValue,
pub border_style: BorderStyle,
pub border_color: ColorU,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BoxShadowPreDisplayItem {
pub offset: [PixelValueNoPercent;2],
pub color: ColorU,
pub blur_radius: PixelValueNoPercent,
pub spread_radius: PixelValueNoPercent,
pub clip_mode: BoxShadowClipMode,
}
impl fmt::Display for BoxShadowPreDisplayItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.clip_mode == BoxShadowClipMode::Inset {
write!(f, "{} ", self.clip_mode)?;
}
write!(f, "{} {} {} {} {}",
self.offset[0], self.offset[1],
self.blur_radius, self.spread_radius, self.color,
)
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StyleBackgroundContent {
LinearGradient(LinearGradient),
RadialGradient(RadialGradient),
Image(CssImageId),
Color(ColorU),
}
impl fmt::Debug for StyleBackgroundContent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::StyleBackgroundContent::*;
match self {
LinearGradient(l) => write!(f, "{}", l),
RadialGradient(r) => write!(f, "{}", r),
Image(id) => write!(f, "image({})", id),
Color(c) => write!(f, "{}", c),
}
}
}
impl StyleBackgroundContent {
pub fn get_css_image_id(&self) -> Option<&CssImageId> {
match self {
StyleBackgroundContent::Image(i) => Some(i),
_ => None,
}
}
}
impl<'a> From<CssImageId> for StyleBackgroundContent {
fn from(id: CssImageId) -> Self {
StyleBackgroundContent::Image(id)
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LinearGradient {
pub direction: Direction,
pub extend_mode: ExtendMode,
pub stops: Vec<GradientStopPre>,
}
impl fmt::Display for LinearGradient {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let prefix = match self.extend_mode {
ExtendMode::Clamp => "linear-gradient",
ExtendMode::Repeat => "repeating-linear-gradient",
};
write!(f, "{}({}", prefix, self.direction)?;
for s in &self.stops {
write!(f, ", {}", s)?;
}
write!(f, ")")
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RadialGradient {
pub shape: Shape,
pub extend_mode: ExtendMode,
pub stops: Vec<GradientStopPre>,
}
impl fmt::Display for RadialGradient {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let prefix = match self.extend_mode {
ExtendMode::Clamp => "radial-gradient",
ExtendMode::Repeat => "repeating-radial-gradient",
};
write!(f, "{}({}", prefix, self.shape)?;
for s in &self.stops {
write!(f, ", {}", s)?;
}
write!(f, ")")
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Direction {
Angle(FloatValue),
FromTo(DirectionCorner, DirectionCorner),
}
impl fmt::Display for Direction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Direction::*;
match self {
Angle(d) => write!(f, "{}deg", d.get()),
FromTo(_, t) => write!(f, "to {}", t),
}
}
}
impl Direction {
pub fn to_points(&self, rect: &LayoutRect)
-> (LayoutPoint, LayoutPoint)
{
match self {
Direction::Angle(deg) => {
let deg = deg.get(); let deg = -deg; let width_half = rect.size.width as usize / 2;
let height_half = rect.size.height as usize / 2;
let hypotenuse_len = (((width_half * width_half) + (height_half * height_half)) as f64).sqrt();
let angle_to_top_left = (height_half as f64 / width_half as f64).atan().to_degrees();
let ending_point_degrees = if deg < 90.0 {
90.0 - angle_to_top_left
} else if deg < 180.0 {
90.0 + angle_to_top_left
} else if deg < 270.0 {
270.0 - angle_to_top_left
} else {
270.0 + angle_to_top_left
};
let degree_diff_to_corner = ending_point_degrees - deg as f64;
let searched_len = (hypotenuse_len * degree_diff_to_corner.to_radians().cos()).abs();
let dx = deg.to_radians().sin() * searched_len as f32;
let dy = deg.to_radians().cos() * searched_len as f32;
let start_point_location = LayoutPoint { x: width_half as f32 + dx, y: height_half as f32 + dy };
let end_point_location = LayoutPoint { x: width_half as f32 - dx, y: height_half as f32 - dy };
(start_point_location, end_point_location)
},
Direction::FromTo(from, to) => {
(from.to_point(rect), to.to_point(rect))
}
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Shape {
Ellipse,
Circle,
}
impl fmt::Display for Shape {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Shape::*;
match self {
Ellipse => write!(f, "ellipse"),
Circle => write!(f, "circle"),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StyleCursor {
Alias,
AllScroll,
Cell,
ColResize,
ContextMenu,
Copy,
Crosshair,
Default,
EResize,
EwResize,
Grab,
Grabbing,
Help,
Move,
NResize,
NsResize,
NeswResize,
NwseResize,
Pointer,
Progress,
RowResize,
SResize,
SeResize,
Text,
Unset,
VerticalText,
WResize,
Wait,
ZoomIn,
ZoomOut,
}
impl Default for StyleCursor {
fn default() -> StyleCursor {
StyleCursor::Default
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DirectionCorner {
Right,
Left,
Top,
Bottom,
TopRight,
TopLeft,
BottomRight,
BottomLeft,
}
impl fmt::Display for DirectionCorner {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::DirectionCorner::*;
match self {
Right => write!(f, "right"),
Left => write!(f, "left"),
Top => write!(f, "top"),
Bottom => write!(f, "bottom"),
TopRight => write!(f, "top right"),
TopLeft => write!(f, "top left"),
BottomRight => write!(f, "bottom right"),
BottomLeft => write!(f, "bottom left"),
}
}
}
impl DirectionCorner {
pub fn opposite(&self) -> Self {
use self::DirectionCorner::*;
match *self {
Right => Left,
Left => Right,
Top => Bottom,
Bottom => Top,
TopRight => BottomLeft,
BottomLeft => TopRight,
TopLeft => BottomRight,
BottomRight => TopLeft,
}
}
pub fn combine(&self, other: &Self) -> Option<Self> {
use self::DirectionCorner::*;
match (*self, *other) {
(Right, Top) | (Top, Right) => Some(TopRight),
(Left, Top) | (Top, Left) => Some(TopLeft),
(Right, Bottom) | (Bottom, Right) => Some(BottomRight),
(Left, Bottom) | (Bottom, Left) => Some(BottomLeft),
_ => { None }
}
}
pub fn to_point(&self, rect: &LayoutRect) -> LayoutPoint
{
use self::DirectionCorner::*;
match *self {
Right => LayoutPoint { x: rect.size.width, y: rect.size.height / 2.0 },
Left => LayoutPoint { x: 0.0, y: rect.size.height / 2.0 },
Top => LayoutPoint { x: rect.size.width / 2.0, y: 0.0 },
Bottom => LayoutPoint { x: rect.size.width / 2.0, y: rect.size.height },
TopRight => LayoutPoint { x: rect.size.width, y: 0.0 },
TopLeft => LayoutPoint { x: 0.0, y: 0.0 },
BottomRight => LayoutPoint { x: rect.size.width, y: rect.size.height },
BottomLeft => LayoutPoint { x: 0.0, y: rect.size.height },
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum GradientType {
LinearGradient,
RepeatingLinearGradient,
RadialGradient,
RepeatingRadialGradient,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CssImageId(pub String);
impl fmt::Display for CssImageId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GradientStopPre {
pub offset: Option<PercentageValue>,
pub color: ColorU,
}
impl fmt::Display for GradientStopPre {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.color.write_hash(f)?;
if let Some(offset) = self.offset {
write!(f, " {}", offset)?;
}
Ok(())
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutWidth(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMinWidth(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMaxWidth(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutHeight(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMinHeight(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMaxHeight(pub PixelValue);
impl_pixel_value!(LayoutWidth);
impl_pixel_value!(LayoutHeight);
impl_pixel_value!(LayoutMinHeight);
impl_pixel_value!(LayoutMinWidth);
impl_pixel_value!(LayoutMaxWidth);
impl_pixel_value!(LayoutMaxHeight);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutTop(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutLeft(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutRight(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutBottom(pub PixelValue);
impl_pixel_value!(LayoutTop);
impl_pixel_value!(LayoutBottom);
impl_pixel_value!(LayoutRight);
impl_pixel_value!(LayoutLeft);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutPaddingTop(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutPaddingLeft(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutPaddingRight(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutPaddingBottom(pub PixelValue);
impl_pixel_value!(LayoutPaddingTop);
impl_pixel_value!(LayoutPaddingBottom);
impl_pixel_value!(LayoutPaddingRight);
impl_pixel_value!(LayoutPaddingLeft);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMarginTop(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMarginLeft(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMarginRight(pub PixelValue);
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutMarginBottom(pub PixelValue);
impl_pixel_value!(LayoutMarginTop);
impl_pixel_value!(LayoutMarginBottom);
impl_pixel_value!(LayoutMarginRight);
impl_pixel_value!(LayoutMarginLeft);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutFlexGrow(pub FloatValue);
impl Default for LayoutFlexGrow {
fn default() -> Self {
LayoutFlexGrow(FloatValue::const_new(0))
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LayoutFlexShrink(pub FloatValue);
impl Default for LayoutFlexShrink {
fn default() -> Self {
LayoutFlexShrink(FloatValue::const_new(0))
}
}
impl_float_value!(LayoutFlexGrow);
impl_float_value!(LayoutFlexShrink);
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutDirection {
Row,
RowReverse,
Column,
ColumnReverse,
}
impl Default for LayoutDirection {
fn default() -> Self {
LayoutDirection::Row
}
}
impl LayoutDirection {
pub fn get_axis(&self) -> LayoutAxis {
use self::{LayoutAxis::*, LayoutDirection::*};
match self {
Row | RowReverse => Horizontal,
Column | ColumnReverse => Vertical,
}
}
pub fn is_reverse(&self) -> bool {
*self == LayoutDirection::RowReverse || *self == LayoutDirection::ColumnReverse
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutBoxSizing {
ContentBox,
BorderBox,
}
impl Default for LayoutBoxSizing {
fn default() -> Self {
LayoutBoxSizing::ContentBox
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleLineHeight(pub PercentageValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleTabWidth(pub PercentageValue);
impl_percentage_value!(StyleTabWidth);
impl_percentage_value!(StyleLineHeight);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleLetterSpacing(pub PixelValue);
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleWordSpacing(pub PixelValue);
impl_pixel_value!(StyleLetterSpacing);
impl_pixel_value!(StyleWordSpacing);
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutAxis {
Horizontal,
Vertical,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutDisplay {
Flex,
Block,
InlineBlock,
}
impl Default for LayoutDisplay {
fn default() -> Self {
LayoutDisplay::Block
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutFloat {
Left,
Right,
}
impl Default for LayoutFloat {
fn default() -> Self {
LayoutFloat::Left
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutPosition {
Static,
Relative,
Absolute,
Fixed,
}
impl Default for LayoutPosition {
fn default() -> Self {
LayoutPosition::Static
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutWrap {
Wrap,
NoWrap,
}
impl Default for LayoutWrap {
fn default() -> Self {
LayoutWrap::Wrap
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutJustifyContent {
Start,
End,
Center,
SpaceBetween,
SpaceAround,
SpaceEvenly,
}
impl Default for LayoutJustifyContent {
fn default() -> Self {
LayoutJustifyContent::Start
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutAlignItems {
Stretch,
Center,
Start,
End,
}
impl Default for LayoutAlignItems {
fn default() -> Self {
LayoutAlignItems::Start
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LayoutAlignContent {
Stretch,
Center,
Start,
End,
SpaceBetween,
SpaceAround,
}
impl Default for LayoutAlignContent {
fn default() -> Self {
LayoutAlignContent::Stretch
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Overflow {
Scroll,
Auto,
Hidden,
Visible,
}
impl Default for Overflow {
fn default() -> Self {
Overflow::Auto
}
}
impl Overflow {
pub fn needs_scrollbar(&self, currently_overflowing: bool) -> bool {
use self::Overflow::*;
match self {
Scroll => true,
Auto => currently_overflowing,
Hidden | Visible => false,
}
}
pub fn is_overflow_visible(&self) -> bool {
*self == Overflow::Visible
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StyleTextAlignmentHorz {
Left,
Center,
Right,
}
impl Default for StyleTextAlignmentHorz {
fn default() -> Self {
StyleTextAlignmentHorz::Left
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum StyleTextAlignmentVert {
Top,
Center,
Bottom,
}
impl Default for StyleTextAlignmentVert {
fn default() -> Self {
StyleTextAlignmentVert::Top
}
}
#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RectStyle {
pub background: Option<CssPropertyValue<StyleBackgroundContent>>,
pub background_position: Option<CssPropertyValue<StyleBackgroundPosition>>,
pub background_size: Option<CssPropertyValue<StyleBackgroundSize>>,
pub background_repeat: Option<CssPropertyValue<StyleBackgroundRepeat>>,
pub font_size: Option<CssPropertyValue<StyleFontSize>>,
pub font_family: Option<CssPropertyValue<StyleFontFamily>>,
pub text_color: Option<CssPropertyValue<StyleTextColor>>,
pub text_align: Option<CssPropertyValue<StyleTextAlignmentHorz>>,
pub line_height: Option<CssPropertyValue<StyleLineHeight>>,
pub letter_spacing: Option<CssPropertyValue<StyleLetterSpacing>>,
pub word_spacing: Option<CssPropertyValue<StyleWordSpacing>>,
pub tab_width: Option<CssPropertyValue<StyleTabWidth>>,
pub cursor: Option<CssPropertyValue<StyleCursor>>,
pub box_shadow_left: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
pub box_shadow_right: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
pub box_shadow_top: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
pub box_shadow_bottom: Option<CssPropertyValue<BoxShadowPreDisplayItem>>,
pub border_top_color: Option<CssPropertyValue<StyleBorderTopColor>>,
pub border_left_color: Option<CssPropertyValue<StyleBorderLeftColor>>,
pub border_right_color: Option<CssPropertyValue<StyleBorderRightColor>>,
pub border_bottom_color: Option<CssPropertyValue<StyleBorderBottomColor>>,
pub border_top_style: Option<CssPropertyValue<StyleBorderTopStyle>>,
pub border_left_style: Option<CssPropertyValue<StyleBorderLeftStyle>>,
pub border_right_style: Option<CssPropertyValue<StyleBorderRightStyle>>,
pub border_bottom_style: Option<CssPropertyValue<StyleBorderBottomStyle>>,
pub border_top_left_radius: Option<CssPropertyValue<StyleBorderTopLeftRadius>>,
pub border_top_right_radius: Option<CssPropertyValue<StyleBorderTopRightRadius>>,
pub border_bottom_left_radius: Option<CssPropertyValue<StyleBorderBottomLeftRadius>>,
pub border_bottom_right_radius: Option<CssPropertyValue<StyleBorderBottomRightRadius>>,
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RectLayout {
pub display: Option<CssPropertyValue<LayoutDisplay>>,
pub float: Option<CssPropertyValue<LayoutFloat>>,
pub box_sizing: Option<CssPropertyValue<LayoutBoxSizing>>,
pub width: Option<CssPropertyValue<LayoutWidth>>,
pub height: Option<CssPropertyValue<LayoutHeight>>,
pub min_width: Option<CssPropertyValue<LayoutMinWidth>>,
pub min_height: Option<CssPropertyValue<LayoutMinHeight>>,
pub max_width: Option<CssPropertyValue<LayoutMaxWidth>>,
pub max_height: Option<CssPropertyValue<LayoutMaxHeight>>,
pub position: Option<CssPropertyValue<LayoutPosition>>,
pub top: Option<CssPropertyValue<LayoutTop>>,
pub bottom: Option<CssPropertyValue<LayoutBottom>>,
pub right: Option<CssPropertyValue<LayoutRight>>,
pub left: Option<CssPropertyValue<LayoutLeft>>,
pub padding_top: Option<CssPropertyValue<LayoutPaddingTop>>,
pub padding_bottom: Option<CssPropertyValue<LayoutPaddingBottom>>,
pub padding_left: Option<CssPropertyValue<LayoutPaddingLeft>>,
pub padding_right: Option<CssPropertyValue<LayoutPaddingRight>>,
pub margin_top: Option<CssPropertyValue<LayoutMarginTop>>,
pub margin_bottom: Option<CssPropertyValue<LayoutMarginBottom>>,
pub margin_left: Option<CssPropertyValue<LayoutMarginLeft>>,
pub margin_right: Option<CssPropertyValue<LayoutMarginRight>>,
pub border_top_width: Option<CssPropertyValue<StyleBorderTopWidth>>,
pub border_left_width: Option<CssPropertyValue<StyleBorderLeftWidth>>,
pub border_right_width: Option<CssPropertyValue<StyleBorderRightWidth>>,
pub border_bottom_width: Option<CssPropertyValue<StyleBorderBottomWidth>>,
pub overflow_x: Option<CssPropertyValue<Overflow>>,
pub overflow_y: Option<CssPropertyValue<Overflow>>,
pub direction: Option<CssPropertyValue<LayoutDirection>>,
pub wrap: Option<CssPropertyValue<LayoutWrap>>,
pub flex_grow: Option<CssPropertyValue<LayoutFlexGrow>>,
pub flex_shrink: Option<CssPropertyValue<LayoutFlexShrink>>,
pub justify_content: Option<CssPropertyValue<LayoutJustifyContent>>,
pub align_items: Option<CssPropertyValue<LayoutAlignItems>>,
pub align_content: Option<CssPropertyValue<LayoutAlignContent>>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ScrollbarInfo {
pub width: LayoutWidth,
pub padding_left: LayoutPaddingLeft,
pub padding_right: LayoutPaddingRight,
pub track: RectStyle,
pub thumb: RectStyle,
pub button: RectStyle,
pub corner: RectStyle,
pub resizer: RectStyle,
}
impl Default for ScrollbarInfo {
fn default() -> Self {
ScrollbarInfo {
width: LayoutWidth(PixelValue::px(17.0)),
padding_left: LayoutPaddingLeft(PixelValue::px(2.0)),
padding_right: LayoutPaddingRight(PixelValue::px(2.0)),
track: RectStyle {
background: Some(CssPropertyValue::Exact(StyleBackgroundContent::Color(ColorU {
r: 241, g: 241, b: 241, a: 255
}))),
.. Default::default()
},
thumb: RectStyle {
background: Some(CssPropertyValue::Exact(StyleBackgroundContent::Color(ColorU {
r: 193, g: 193, b: 193, a: 255
}))),
.. Default::default()
},
button: RectStyle {
background: Some(CssPropertyValue::Exact(StyleBackgroundContent::Color(ColorU {
r: 163, g: 163, b: 163, a: 255
}))),
.. Default::default()
},
corner: RectStyle::default(),
resizer: RectStyle::default(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ScrollbarStyle {
pub horizontal: Option<ScrollbarInfo>,
pub vertical: Option<ScrollbarInfo>,
}
impl RectStyle {
pub fn get_horizontal_scrollbar_style(&self) -> ScrollbarInfo {
ScrollbarInfo::default()
}
pub fn get_vertical_scrollbar_style(&self) -> ScrollbarInfo {
ScrollbarInfo::default()
}
pub fn has_box_shadow(&self) -> bool {
self.box_shadow_left.and_then(|bs| bs.get_property().map(|_| ())).is_some() ||
self.box_shadow_right.and_then(|bs| bs.get_property().map(|_| ())).is_some() ||
self.box_shadow_top.and_then(|bs| bs.get_property().map(|_| ())).is_some() ||
self.box_shadow_bottom.and_then(|bs| bs.get_property().map(|_| ())).is_some()
}
pub fn has_border(&self) -> bool {
self.border_left_style.and_then(|bs| bs.get_property_or_default()).is_some() ||
self.border_right_style.and_then(|bs| bs.get_property_or_default()).is_some() ||
self.border_top_style.and_then(|bs| bs.get_property_or_default()).is_some() ||
self.border_bottom_style.and_then(|bs| bs.get_property_or_default()).is_some()
}
}
impl RectLayout {
pub fn is_horizontal_overflow_visible(&self) -> bool {
self.overflow_x.map(|css_prop| css_prop.get_property().map(|overflow| overflow.is_overflow_visible()).unwrap_or_default()) == Some(true)
}
pub fn is_vertical_overflow_visible(&self) -> bool {
self.overflow_y.map(|css_prop| css_prop.get_property().map(|overflow| overflow.is_overflow_visible()).unwrap_or_default()) == Some(true)
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleFontSize(pub PixelValue);
impl_pixel_value!(StyleFontSize);
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StyleFontFamily {
pub fonts: Vec<FontId>
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FontId(pub String);
impl FontId {
pub fn get_str(&self) -> &str {
&self.0
}
}