#[cfg(not(feature = "std"))]
use alloc::string::ToString;
use alloc::{collections::btree_map::BTreeMap, format, string::String, vec::Vec};
use core::hash::Hash;
use crate::{
corety::*,
css::*,
props::{basic::*, layout::*, property::*, style::*},
};
pub trait FormatAsRustCode {
fn format_as_rust_code(&self, tabs: usize) -> String;
}
pub trait GetHash {
fn get_hash(&self) -> u64;
}
impl<T: Hash> GetHash for T {
fn get_hash(&self) -> u64 {
use highway::{HighwayHash, HighwayHasher, Key};
let mut hasher = HighwayHasher::new(Key([0; 4]));
self.hash(&mut hasher);
hasher.finalize64()
}
}
#[derive(Default)]
pub struct VecContents {
pub strings: BTreeMap<u64, AzString>,
pub style_filters: BTreeMap<u64, StyleFilterVec>,
pub style_background_sizes: BTreeMap<u64, StyleBackgroundSizeVec>,
pub style_background_repeats: BTreeMap<u64, StyleBackgroundRepeatVec>,
pub style_background_contents: BTreeMap<u64, StyleBackgroundContentVec>,
pub style_background_positions: BTreeMap<u64, StyleBackgroundPositionVec>,
pub style_transforms: BTreeMap<u64, StyleTransformVec>,
pub font_families: BTreeMap<u64, StyleFontFamilyVec>,
pub linear_color_stops: BTreeMap<u64, NormalizedLinearColorStopVec>,
pub radial_color_stops: BTreeMap<u64, NormalizedRadialColorStopVec>,
}
impl VecContents {
pub fn format(&self, tabs: usize) -> String {
let mut result = String::new();
let t = " ".repeat(tabs);
let t2 = " ".repeat(tabs + 1);
for (key, item) in self.strings.iter() {
result.push_str(&format!(
"\r\n const STRING_{}: AzString = AzString::from_const_str(\"{}\");",
key,
item.as_str()
));
}
for (key, item) in self.style_filters.iter() {
let val = item
.iter()
.map(|filter| format_style_filter(filter, tabs + 1))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t));
result.push_str(&format!(
"\r\n const STYLE_FILTER_{}_ITEMS: &[StyleFilter] = &[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.style_background_sizes.iter() {
let val = item
.iter()
.map(|bgs| format_style_background_size(bgs))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t));
result.push_str(&format!(
"\r\n const STYLE_BACKGROUND_SIZE_{}_ITEMS: &[StyleBackgroundSize] = \
&[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.style_background_repeats.iter() {
let val = item
.iter()
.map(|bgr| bgr.format_as_rust_code(tabs + 1))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t));
result.push_str(&format!(
"\r\n const STYLE_BACKGROUND_REPEAT_{}_ITEMS: &[StyleBackgroundRepeat] = \
&[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.style_background_contents.iter() {
let val = item
.iter()
.map(|bgc| format_style_background_content(bgc, tabs + 1))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t));
result.push_str(&format!(
"\r\n const STYLE_BACKGROUND_CONTENT_{}_ITEMS: &[StyleBackgroundContent] = \
&[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.style_background_positions.iter() {
let val = item
.iter()
.map(|bgp| format_style_background_position(bgp, tabs))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t));
result.push_str(&format!(
"\r\n const STYLE_BACKGROUND_POSITION_{}_ITEMS: &[StyleBackgroundPosition] = \
&[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.style_transforms.iter() {
let val = format_style_transforms(item.as_ref(), tabs + 1);
result.push_str(&format!(
"\r\n const STYLE_TRANSFORM_{}_ITEMS: &[StyleTransform] = &[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.font_families.iter() {
let val = format_font_ids(item.as_ref(), tabs + 1);
result.push_str(&format!(
"\r\n const STYLE_FONT_FAMILY_{}_ITEMS: &[StyleFontFamily] = &[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.linear_color_stops.iter() {
let val = format_linear_color_stops(item.as_ref(), 1);
result.push_str(&format!(
"\r\n const LINEAR_COLOR_STOP_{}_ITEMS: &[NormalizedLinearColorStop] = \
&[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
for (key, item) in self.radial_color_stops.iter() {
let val = format_radial_color_stops(item.as_ref(), tabs);
result.push_str(&format!(
"\r\n const RADIAL_COLOR_STOP_{}_ITEMS: &[NormalizedRadialColorStop] = \
&[\r\n{}{}\r\n{}];",
key, t2, val, t
));
}
result
}
pub fn insert_from_css_property(&mut self, prop: &CssProperty) {
match prop {
CssProperty::FontFamily(CssPropertyValue::Exact(v)) => {
for family in v.iter() {
match family {
StyleFontFamily::System(s) => {
let s = s.as_str();
let s = s.trim();
let s = s.trim_start_matches('\"');
let s = s.trim_end_matches('\"');
let s = s.trim_start_matches('\'');
let s = s.trim_end_matches('\'');
self.strings.insert(s.get_hash(), s.to_string().into());
}
StyleFontFamily::File(s) => {
let s = s.as_str();
let s = s.trim();
let s = s.trim_start_matches('\"');
let s = s.trim_end_matches('\"');
let s = s.trim_start_matches('\'');
let s = s.trim_end_matches('\'');
self.strings.insert(s.get_hash(), s.to_string().into());
}
_ => {}
}
}
self.font_families.insert(v.get_hash(), v.clone());
}
CssProperty::Transform(CssPropertyValue::Exact(v)) => {
self.style_transforms.insert(v.get_hash(), v.clone());
}
CssProperty::BackgroundRepeat(CssPropertyValue::Exact(v)) => {
self.style_background_repeats
.insert(v.get_hash(), v.clone());
}
CssProperty::BackgroundSize(CssPropertyValue::Exact(v)) => {
self.style_background_sizes.insert(v.get_hash(), v.clone());
}
CssProperty::BackgroundPosition(CssPropertyValue::Exact(v)) => {
self.style_background_positions
.insert(v.get_hash(), v.clone());
}
CssProperty::BackgroundContent(CssPropertyValue::Exact(v)) => {
for background in v.iter() {
match background {
StyleBackgroundContent::Image(id) => {
self.strings.insert(id.get_hash(), id.clone());
}
StyleBackgroundContent::LinearGradient(lg) => {
self.linear_color_stops
.insert(lg.stops.get_hash(), lg.stops.clone());
}
StyleBackgroundContent::RadialGradient(rg) => {
self.linear_color_stops
.insert(rg.stops.get_hash(), rg.stops.clone());
}
StyleBackgroundContent::ConicGradient(lg) => {
self.radial_color_stops
.insert(lg.stops.get_hash(), lg.stops.clone());
}
_ => {}
}
}
self.style_background_contents
.insert(v.get_hash(), v.clone());
}
CssProperty::Filter(CssPropertyValue::Exact(v)) => {
self.style_filters.insert(v.get_hash(), v.clone());
}
CssProperty::BackdropFilter(CssPropertyValue::Exact(v)) => {
self.style_filters.insert(v.get_hash(), v.clone());
}
_ => {}
}
}
}
pub fn format_pixel_value(p: &PixelValue) -> String {
let value = p.number.get();
let pre_comma = libm::floorf(value) as isize;
let fraction = value - pre_comma as f32;
let post_comma = libm::roundf(fraction * 100.0) as isize;
match p.metric {
SizeMetric::Px => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Px, {}, {})",
pre_comma, post_comma
),
SizeMetric::Pt => format!(
"PixelValue::const_pt_fractional({}, {})",
pre_comma, post_comma
),
SizeMetric::Em => format!(
"PixelValue::const_em_fractional({}, {})",
pre_comma, post_comma
),
SizeMetric::Rem => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Rem, {}, {})",
pre_comma, post_comma
),
SizeMetric::Percent => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Percent, {}, {})",
pre_comma, post_comma
),
SizeMetric::In => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::In, {}, {})",
pre_comma, post_comma
),
SizeMetric::Cm => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Cm, {}, {})",
pre_comma, post_comma
),
SizeMetric::Mm => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Mm, {}, {})",
pre_comma, post_comma
),
SizeMetric::Vw => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Vw, {}, {})",
pre_comma, post_comma
),
SizeMetric::Vh => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Vh, {}, {})",
pre_comma, post_comma
),
SizeMetric::Vmin => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Vmin, {}, {})",
pre_comma, post_comma
),
SizeMetric::Vmax => format!(
"PixelValue::const_from_metric_fractional(SizeMetric::Vmax, {}, {})",
pre_comma, post_comma
),
}
}
pub fn format_pixel_value_no_percent(p: &PixelValueNoPercent) -> String {
format!(
"PixelValueNoPercent {{ inner: {} }}",
format_pixel_value(&p.inner)
)
}
pub fn format_float_value(f: &FloatValue) -> String {
format!("FloatValue::const_new({})", libm::roundf(f.get()) as isize)
}
pub fn format_percentage_value(f: &PercentageValue) -> String {
format!(
"PercentageValue::const_new({})",
libm::roundf(f.normalized() * 100.0) as isize
)
}
pub fn format_angle_value(f: &AngleValue) -> String {
format!(
"AngleValue::const_deg({})",
libm::roundf(f.to_degrees()) as isize
)
}
pub fn format_color_value(c: &ColorU) -> String {
format!(
"ColorU {{ r: {}, g: {}, b: {}, a: {} }}",
c.r, c.g, c.b, c.a
)
}
pub fn format_color_or_system(c: &crate::props::basic::color::ColorOrSystem) -> String {
use crate::props::basic::color::{ColorOrSystem, SystemColorRef};
match c {
ColorOrSystem::Color(color) => format!("ColorOrSystem::Color({})", format_color_value(color)),
ColorOrSystem::System(system_ref) => {
let variant = match system_ref {
SystemColorRef::Text => "Text",
SystemColorRef::Background => "Background",
SystemColorRef::Accent => "Accent",
SystemColorRef::AccentText => "AccentText",
SystemColorRef::ButtonFace => "ButtonFace",
SystemColorRef::ButtonText => "ButtonText",
SystemColorRef::WindowBackground => "WindowBackground",
SystemColorRef::SelectionBackground => "SelectionBackground",
SystemColorRef::SelectionText => "SelectionText",
};
format!("ColorOrSystem::System(SystemColorRef::{})", variant)
}
}
}
macro_rules! impl_float_value_fmt {
($struct_name:ident) => {
impl FormatAsRustCode for $struct_name {
fn format_as_rust_code(&self, _tabs: usize) -> String {
format!(
"{} {{ inner: {} }}",
stringify!($struct_name),
format_float_value(&self.inner)
)
}
}
};
}
impl_float_value_fmt!(LayoutFlexGrow);
impl_float_value_fmt!(LayoutFlexShrink);
macro_rules! impl_percentage_value_fmt {
($struct_name:ident) => {
impl FormatAsRustCode for $struct_name {
fn format_as_rust_code(&self, _tabs: usize) -> String {
format!(
"{} {{ inner: {} }}",
stringify!($struct_name),
format_percentage_value(&self.inner)
)
}
}
};
}
impl_percentage_value_fmt!(StyleLineHeight);
impl_percentage_value_fmt!(StyleOpacity);
macro_rules! impl_pixel_value_fmt {
($struct_name:ident) => {
impl FormatAsRustCode for $struct_name {
fn format_as_rust_code(&self, _tabs: usize) -> String {
format!(
"{} {{ inner: {} }}",
stringify!($struct_name),
format_pixel_value(&self.inner)
)
}
}
};
}
impl_pixel_value_fmt!(StyleTabSize);
impl_pixel_value_fmt!(StyleBorderTopLeftRadius);
impl_pixel_value_fmt!(StyleBorderBottomLeftRadius);
impl_pixel_value_fmt!(StyleBorderTopRightRadius);
impl_pixel_value_fmt!(StyleBorderBottomRightRadius);
impl_pixel_value_fmt!(LayoutBorderTopWidth);
impl_pixel_value_fmt!(LayoutBorderLeftWidth);
impl_pixel_value_fmt!(LayoutBorderRightWidth);
impl_pixel_value_fmt!(LayoutBorderBottomWidth);
impl_pixel_value_fmt!(StyleLetterSpacing);
impl_pixel_value_fmt!(StyleWordSpacing);
impl_pixel_value_fmt!(StyleFontSize);
impl_pixel_value_fmt!(LayoutMarginTop);
impl_pixel_value_fmt!(LayoutMarginBottom);
impl_pixel_value_fmt!(LayoutMarginRight);
impl_pixel_value_fmt!(LayoutMarginLeft);
impl_pixel_value_fmt!(LayoutPaddingTop);
impl_pixel_value_fmt!(LayoutPaddingBottom);
impl_pixel_value_fmt!(LayoutPaddingRight);
impl_pixel_value_fmt!(LayoutPaddingLeft);
impl_pixel_value_fmt!(LayoutPaddingInlineStart);
impl_pixel_value_fmt!(LayoutPaddingInlineEnd);
impl FormatAsRustCode for LayoutWidth {
fn format_as_rust_code(&self, _tabs: usize) -> String {
match self {
LayoutWidth::Auto => "LayoutWidth::Auto".to_string(),
LayoutWidth::Px(px) => format!("LayoutWidth::Px({})", format_pixel_value(px)),
LayoutWidth::MinContent => "LayoutWidth::MinContent".to_string(),
LayoutWidth::MaxContent => "LayoutWidth::MaxContent".to_string(),
LayoutWidth::Calc(items) => format!("LayoutWidth::Calc(/* {} items */)", items.len()),
}
}
}
impl FormatAsRustCode for LayoutHeight {
fn format_as_rust_code(&self, _tabs: usize) -> String {
match self {
LayoutHeight::Auto => "LayoutHeight::Auto".to_string(),
LayoutHeight::Px(px) => format!("LayoutHeight::Px({})", format_pixel_value(px)),
LayoutHeight::MinContent => "LayoutHeight::MinContent".to_string(),
LayoutHeight::MaxContent => "LayoutHeight::MaxContent".to_string(),
LayoutHeight::Calc(items) => format!("LayoutHeight::Calc(/* {} items */)", items.len()),
}
}
}
impl_pixel_value_fmt!(LayoutMinHeight);
impl_pixel_value_fmt!(LayoutMinWidth);
impl_pixel_value_fmt!(LayoutMaxWidth);
impl_pixel_value_fmt!(LayoutMaxHeight);
impl_pixel_value_fmt!(LayoutTop);
impl_pixel_value_fmt!(LayoutInsetBottom);
impl_pixel_value_fmt!(LayoutRight);
impl_pixel_value_fmt!(LayoutLeft);
impl_pixel_value_fmt!(LayoutColumnGap);
impl_pixel_value_fmt!(LayoutRowGap);
impl_grid_value_fmt!(GridTemplate);
impl_grid_value_fmt!(GridPlacement);
impl_color_value_fmt!(StyleTextColor);
impl_color_value_fmt!(StyleBorderTopColor);
impl_color_value_fmt!(StyleBorderLeftColor);
impl_color_value_fmt!(StyleBorderRightColor);
impl_color_value_fmt!(StyleBorderBottomColor);
impl_enum_fmt!(
StyleMixBlendMode,
Normal,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
HardLight,
SoftLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity
);
impl_enum_fmt!(StyleHyphens, Auto, None);
impl_enum_fmt!(StyleDirection, Ltr, Rtl);
impl_enum_fmt!(StyleWhiteSpace, Normal, Pre, Nowrap, PreWrap, PreLine, BreakSpaces);
impl_enum_fmt!(StyleVisibility, Visible, Hidden, Collapse);
impl_enum_fmt!(LayoutWritingMode, HorizontalTb, VerticalRl, VerticalLr);
impl_enum_fmt!(LayoutClear, None, Left, Right, Both);
impl_enum_fmt!(
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_enum_fmt!(
BorderStyle,
None,
Solid,
Double,
Dotted,
Dashed,
Hidden,
Groove,
Ridge,
Inset,
Outset
);
impl_enum_fmt!(
StyleBackgroundRepeat,
NoRepeat,
PatternRepeat,
RepeatX,
RepeatY
);
impl_enum_fmt!(
LayoutDisplay,
None,
Block,
Inline,
InlineBlock,
Flex,
InlineFlex,
Table,
InlineTable,
TableRowGroup,
TableHeaderGroup,
TableFooterGroup,
TableRow,
TableColumnGroup,
TableColumn,
TableCell,
TableCaption,
ListItem,
RunIn,
Marker,
Grid,
InlineGrid,
FlowRoot
);
impl_enum_fmt!(LayoutFloat, Left, Right, None);
impl_enum_fmt!(LayoutBoxSizing, ContentBox, BorderBox);
impl_enum_fmt!(LayoutFlexDirection, Row, RowReverse, Column, ColumnReverse);
impl_enum_fmt!(LayoutFlexWrap, Wrap, NoWrap, WrapReverse);
impl_enum_fmt!(
LayoutJustifyContent,
Start,
End,
FlexStart,
FlexEnd,
Center,
SpaceBetween,
SpaceAround,
SpaceEvenly
);
impl_enum_fmt!(LayoutAlignItems, Stretch, Center, Start, End, Baseline);
impl_enum_fmt!(
LayoutAlignContent,
Start,
End,
Stretch,
Center,
SpaceBetween,
SpaceAround
);
impl_enum_fmt!(Shape, Circle, Ellipse);
impl_enum_fmt!(LayoutOverflow, Auto, Scroll, Visible, Hidden, Clip);
impl_enum_fmt!(StyleTextAlign, Center, Left, Right, Justify, Start, End);
impl_enum_fmt!(StyleUserSelect, Auto, Text, None, All);
impl_enum_fmt!(StyleTextDecoration, None, Underline, Overline, LineThrough);
impl_enum_fmt!(
DirectionCorner,
Right,
Left,
Top,
Bottom,
TopRight,
TopLeft,
BottomRight,
BottomLeft
);
impl_enum_fmt!(ExtendMode, Clamp, Repeat);
impl_enum_fmt!(StyleBackfaceVisibility, Visible, Hidden);
fn format_style_background_size(c: &StyleBackgroundSize) -> String {
match c {
StyleBackgroundSize::Contain => String::from("StyleBackgroundSize::Contain"),
StyleBackgroundSize::Cover => String::from("StyleBackgroundSize::Cover"),
StyleBackgroundSize::ExactSize(size) => format!(
"StyleBackgroundSize::ExactSize(PixelValueSize {{ width: {}, height: {} }})",
format_pixel_value(&size.width),
format_pixel_value(&size.height)
),
}
}
pub fn format_scrollbar_info(s: &ScrollbarInfo, tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
let t1 = String::from(" ").repeat(tabs + 1);
format!(
"ScrollbarInfo {{\r\n{}width: {},\r\n{}padding_left: {},\r\n{}padding_right: \
{},\r\n{}track: {},\r\n{}thumb: {},\r\n{}button: {},\r\n{}button: {},\r\n{}resizer: \
{},\r\n{}}}",
t1,
s.width.format_as_rust_code(tabs + 1),
t1,
s.padding_left.format_as_rust_code(tabs + 1),
t1,
s.padding_right.format_as_rust_code(tabs + 1),
t1,
format_style_background_content(&s.track, tabs + 1),
t1,
format_style_background_content(&s.thumb, tabs + 1),
t1,
format_style_background_content(&s.button, tabs + 1),
t1,
format_style_background_content(&s.corner, tabs + 1),
t1,
format_style_background_content(&s.resizer, tabs + 1),
t
)
}
fn format_style_background_content(content: &StyleBackgroundContent, tabs: usize) -> String {
match content {
StyleBackgroundContent::LinearGradient(l) => format!(
"StyleBackgroundContent::LinearGradient({})",
format_linear_gradient(l, tabs)
),
StyleBackgroundContent::RadialGradient(r) => format!(
"StyleBackgroundContent::RadialGradient({})",
format_radial_gradient(r, tabs)
),
StyleBackgroundContent::ConicGradient(r) => format!(
"StyleBackgroundContent::ConicGradient({})",
format_conic_gradient(r, tabs)
),
StyleBackgroundContent::Image(id) => format!("StyleBackgroundContent::Image({:?})", id),
StyleBackgroundContent::Color(c) => {
format!("StyleBackgroundContent::Color({})", format_color_value(c))
}
}
}
fn format_direction(d: &Direction, tabs: usize) -> String {
match d {
Direction::Angle(fv) => format!("Direction::Angle({})", format_angle_value(fv)),
Direction::FromTo(DirectionCorners { dir_from, dir_to }) => format!(
"Direction::FromTo(DirectionCorners {{ dir_from: {}, dir_to: {} }})",
dir_from.format_as_rust_code(tabs + 1),
dir_to.format_as_rust_code(tabs + 1)
),
}
}
fn format_linear_gradient(l: &LinearGradient, tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
let t1 = String::from(" ").repeat(tabs + 1);
format!(
"LinearGradient {{\r\n{}direction: {},\r\n{}extend_mode: {},\r\n{}stops: \
NormalizedLinearColorStopVec::from_const_slice(LINEAR_COLOR_STOP_{}_ITEMS),\r\n{}}}",
t1,
format_direction(&l.direction, tabs + 1),
t1,
l.extend_mode.format_as_rust_code(tabs + 1),
t1,
l.stops.get_hash(),
t,
)
}
fn format_conic_gradient(r: &ConicGradient, tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
let t1 = String::from(" ").repeat(tabs + 1);
format!(
"ConicGradient {{\r\n{}extend_mode: {},\r\n{}center: {},\r\n{}angle: {},\r\n{}stops: \
NormalizedRadialColorStopVec::from_const_slice(RADIAL_COLOR_STOP_{}_ITEMS),\r\n{}}}",
t1,
r.extend_mode.format_as_rust_code(tabs + 1),
t1,
format_style_background_position(&r.center, tabs + 1),
t1,
format_angle_value(&r.angle),
t1,
r.stops.get_hash(),
t,
)
}
fn format_radial_gradient(r: &RadialGradient, tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
let t1 = String::from(" ").repeat(tabs + 1);
format!(
"RadialGradient {{\r\n{}shape: {},\r\n{}extend_mode: {},\r\n{}position: {},\r\n{}size: \
RadialGradientSize::{:?},\r\n{}stops: \
NormalizedLinearColorStopVec::from_const_slice(LINEAR_COLOR_STOP_{}_ITEMS),\r\n{}}}",
t1,
r.shape.format_as_rust_code(tabs + 1),
t1,
r.extend_mode.format_as_rust_code(tabs + 1),
t1,
format_style_background_position(&r.position, tabs + 1),
t1,
r.size,
t1,
r.stops.get_hash(),
t,
)
}
fn format_linear_color_stops(stops: &[NormalizedLinearColorStop], tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
stops
.iter()
.map(|s| format_linear_color_stop(s))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t))
}
fn format_linear_color_stop(g: &NormalizedLinearColorStop) -> String {
format!(
"NormalizedLinearColorStop {{ offset: {}, color: {} }}",
format_percentage_value(&g.offset),
format_color_or_system(&g.color),
)
}
fn format_radial_color_stops(stops: &[NormalizedRadialColorStop], tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
stops
.iter()
.map(|s| format_radial_color_stop(s))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t))
}
fn format_radial_color_stop(g: &NormalizedRadialColorStop) -> String {
format!(
"RadialColorStop {{ angle: {}, color: {} }}",
format_angle_value(&g.angle),
format_color_or_system(&g.color),
)
}
fn format_style_filter(st: &StyleFilter, tabs: usize) -> String {
let tabs_minus_one = String::from(" ").repeat(tabs);
let tabs_str = String::from(" ").repeat(tabs + 1);
match st {
StyleFilter::Blend(mb) => format!("StyleFilter::Blend({})", mb.format_as_rust_code(tabs)),
StyleFilter::Flood(c) => format!("StyleFilter::Flood({})", format_color_value(c)),
StyleFilter::Blur(m) => format!(
"StyleFilter::Blur(StyleBlur {{ width: {}, height: {} }})",
format_pixel_value(&m.width),
format_pixel_value(&m.height)
),
StyleFilter::Opacity(pct) => {
format!("StyleFilter::Opacity({})", format_percentage_value(pct))
}
StyleFilter::ColorMatrix(cm) => format!(
"StyleFilter::ColorMatrix(StyleColorMatrix {{ m0: {}, m1: {}, m2: {}, m3: {}, m4: {}, \
m5: {}, m6: {}, m7: {}, m8: {}, m9: {}, m10: {}, m11: {}, m12: {}, m13: {}, m14: {}, \
m15: {}, m16: {}, m17: {}, m18: {}, m19: {} }})",
format_float_value(&cm.m0),
format_float_value(&cm.m1),
format_float_value(&cm.m2),
format_float_value(&cm.m3),
format_float_value(&cm.m4),
format_float_value(&cm.m5),
format_float_value(&cm.m6),
format_float_value(&cm.m7),
format_float_value(&cm.m8),
format_float_value(&cm.m9),
format_float_value(&cm.m10),
format_float_value(&cm.m11),
format_float_value(&cm.m12),
format_float_value(&cm.m13),
format_float_value(&cm.m14),
format_float_value(&cm.m15),
format_float_value(&cm.m16),
format_float_value(&cm.m17),
format_float_value(&cm.m18),
format_float_value(&cm.m19)
),
StyleFilter::DropShadow(m) => {
format!("StyleFilter::DropShadow({})", m.format_as_rust_code(tabs))
}
StyleFilter::ComponentTransfer => format!("StyleFilter::ComponentTransfer"),
StyleFilter::Offset(o) => format!(
"StyleFilter::Offset(StyleFilterOffset {{ x: {}, y: {} }})",
format_pixel_value(&o.x),
format_pixel_value(&o.y)
),
StyleFilter::Composite(StyleCompositeFilter::Over) => {
format!("StyleFilter::Composite(StyleCompositeFilter::Over)")
}
StyleFilter::Composite(StyleCompositeFilter::In) => {
format!("StyleFilter::Composite(StyleCompositeFilter::In)")
}
StyleFilter::Composite(StyleCompositeFilter::Atop) => {
format!("StyleFilter::Composite(StyleCompositeFilter::Atop)")
}
StyleFilter::Composite(StyleCompositeFilter::Out) => {
format!("StyleFilter::Composite(StyleCompositeFilter::Out)")
}
StyleFilter::Composite(StyleCompositeFilter::Xor) => {
format!("StyleFilter::Composite(StyleCompositeFilter::Xor)")
}
StyleFilter::Composite(StyleCompositeFilter::Lighter) => {
format!("StyleFilter::Composite(StyleCompositeFilter::Lighter)")
}
StyleFilter::Composite(StyleCompositeFilter::Arithmetic(fv)) => format!(
"StyleFilter::Composite(StyleCompositeFilter::Arithmetic(ArithmeticCoefficients {{ \
k1: {}, k2: {}, k3: {}, k4: {} }}))",
format_float_value(&fv.k1),
format_float_value(&fv.k2),
format_float_value(&fv.k3),
format_float_value(&fv.k4)
),
StyleFilter::Brightness(v) => format!("StyleFilter::Brightness({})", format_percentage_value(v)),
StyleFilter::Contrast(v) => format!("StyleFilter::Contrast({})", format_percentage_value(v)),
StyleFilter::Grayscale(v) => format!("StyleFilter::Grayscale({})", format_percentage_value(v)),
StyleFilter::HueRotate(a) => format!("StyleFilter::HueRotate({})", format_angle_value(a)),
StyleFilter::Invert(v) => format!("StyleFilter::Invert({})", format_percentage_value(v)),
StyleFilter::Saturate(v) => format!("StyleFilter::Saturate({})", format_percentage_value(v)),
StyleFilter::Sepia(v) => format!("StyleFilter::Sepia({})", format_percentage_value(v)),
}
}
fn format_style_transforms(stops: &[StyleTransform], tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
stops
.iter()
.map(|s| format_style_transform(s, tabs))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t))
}
fn format_style_transform(st: &StyleTransform, tabs: usize) -> String {
let tabs_minus_one = String::from(" ").repeat(tabs);
let tabs = String::from(" ").repeat(tabs + 1);
match st {
StyleTransform::Matrix(m) => format!(
"StyleTransform::Matrix(StyleTransformMatrix2D {{ a: {}, b: {}, c: {}, d: {}, tx: {}, \
ty: {} }})",
format_float_value(&m.a),
format_float_value(&m.b),
format_float_value(&m.c),
format_float_value(&m.d),
format_float_value(&m.tx),
format_float_value(&m.ty)
),
StyleTransform::Matrix3D(m) => format!(
"StyleTransform::Matrix3D(StyleTransformMatrix3D {{\r\n{tabs}m11: {},\r\n{tabs}m12: \
{},\r\n{tabs}m13: {},\r\n{tabs}m14: {},\r\n{tabs}m21: {},\r\n{tabs}m22: \
{},\r\n{tabs}m23: {},\r\n{tabs}m24: {},\r\n{tabs}m31: {},\r\n{tabs}m32: \
{},\r\n{tabs}m33: {},\r\n{tabs}m34: {},\r\n{tabs}m41: {},\r\n{tabs}m42: \
{},\r\n{tabs}m43: {},\r\n{tabs}m44: {}\r\n{tabs_minus_one}}})",
format_float_value(&m.m11),
format_float_value(&m.m12),
format_float_value(&m.m13),
format_float_value(&m.m14),
format_float_value(&m.m21),
format_float_value(&m.m22),
format_float_value(&m.m23),
format_float_value(&m.m24),
format_float_value(&m.m31),
format_float_value(&m.m32),
format_float_value(&m.m33),
format_float_value(&m.m34),
format_float_value(&m.m41),
format_float_value(&m.m42),
format_float_value(&m.m43),
format_float_value(&m.m44),
tabs = tabs,
tabs_minus_one = tabs_minus_one,
),
StyleTransform::Translate(t) => format!(
"StyleTransform::Translate(StyleTransformTranslate2D {{ x: {}, y: {} }})",
format_pixel_value(&t.x),
format_pixel_value(&t.y)
),
StyleTransform::Translate3D(t) => format!(
"StyleTransform::Translate3D(StyleTransformTranslate3D {{ x: {}, y: {}, z: {})",
format_pixel_value(&t.x),
format_pixel_value(&t.y),
format_pixel_value(&t.z)
),
StyleTransform::TranslateX(x) => {
format!("StyleTransform::TranslateX({})", format_pixel_value(&x))
}
StyleTransform::TranslateY(y) => {
format!("StyleTransform::TranslateY({})", format_pixel_value(&y))
}
StyleTransform::TranslateZ(z) => {
format!("StyleTransform::TranslateZ({})", format_pixel_value(&z))
}
StyleTransform::Rotate(r) => format!("StyleTransform::Rotate({})", format_angle_value(&r)),
StyleTransform::Rotate3D(r) => format!(
"StyleTransform::Rotate3D(StyleTransformRotate3D {{ {}, {}, {}, {} }})",
format_float_value(&r.x),
format_float_value(&r.y),
format_float_value(&r.z),
format_angle_value(&r.angle)
),
StyleTransform::RotateX(x) => {
format!("StyleTransform::RotateX({})", format_angle_value(&x))
}
StyleTransform::RotateY(y) => {
format!("StyleTransform::RotateY({})", format_angle_value(&y))
}
StyleTransform::RotateZ(z) => {
format!("StyleTransform::RotateZ({})", format_angle_value(&z))
}
StyleTransform::Scale(s) => format!(
"StyleTransform::Scale(StyleTransformScale2D {{ x: {}, y: {} }})",
format_float_value(&s.x),
format_float_value(&s.y)
),
StyleTransform::Scale3D(s) => format!(
"StyleTransform::Scale3D(StyleTransformScale3D {{ x; {}, y: {}, z: {} }})",
format_float_value(&s.x),
format_float_value(&s.y),
format_float_value(&s.z)
),
StyleTransform::ScaleX(x) => {
format!("StyleTransform::ScaleX({})", format_percentage_value(&x))
}
StyleTransform::ScaleY(y) => {
format!("StyleTransform::ScaleY({})", format_percentage_value(&y))
}
StyleTransform::ScaleZ(z) => {
format!("StyleTransform::ScaleZ({})", format_percentage_value(&z))
}
StyleTransform::Skew(sk) => format!(
"StyleTransform::Skew(StyleTransformSkew2D {{ x: {}, y: {} }})",
format_angle_value(&sk.x),
format_angle_value(&sk.y)
),
StyleTransform::SkewX(x) => {
format!("StyleTransform::SkewX({})", format_angle_value(&x))
}
StyleTransform::SkewY(y) => {
format!("StyleTransform::SkewY({})", format_angle_value(&y))
}
StyleTransform::Perspective(dist) => {
format!("StyleTransform::Perspective({})", format_pixel_value(&dist))
}
}
}
fn format_font_ids(font_ids: &[StyleFontFamily], tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
font_ids
.iter()
.map(|s| format!("{}", s.format_as_rust_code(tabs + 1)))
.collect::<Vec<_>>()
.join(&format!(",\r\n{}", t))
}
fn format_style_background_position(b: &StyleBackgroundPosition, tabs: usize) -> String {
let t = String::from(" ").repeat(tabs);
let t1 = String::from(" ").repeat(tabs + 1);
format!(
"StyleBackgroundPosition {{\r\n{}horizontal: {},\r\n{}vertical: {},\r\n{}}}",
t1,
format_background_position_horizontal(&b.horizontal),
t1,
format_background_position_vertical(&b.vertical),
t
)
}
fn format_background_position_horizontal(b: &BackgroundPositionHorizontal) -> String {
match b {
BackgroundPositionHorizontal::Left => format!("BackgroundPositionHorizontal::Left"),
BackgroundPositionHorizontal::Center => format!("BackgroundPositionHorizontal::Center"),
BackgroundPositionHorizontal::Right => format!("BackgroundPositionHorizontal::Right"),
BackgroundPositionHorizontal::Exact(p) => format!(
"BackgroundPositionHorizontal::Exact({})",
format_pixel_value(p)
),
}
}
fn format_background_position_vertical(b: &BackgroundPositionVertical) -> String {
match b {
BackgroundPositionVertical::Top => format!("BackgroundPositionVertical::Top"),
BackgroundPositionVertical::Center => format!("BackgroundPositionVertical::Center"),
BackgroundPositionVertical::Bottom => format!("BackgroundPositionVertical::Bottom"),
BackgroundPositionVertical::Exact(p) => format!(
"BackgroundPositionVertical::Exact({})",
format_pixel_value(p)
),
}
}