1#[cfg(not(feature = "std"))]
4use alloc::string::ToString;
5use alloc::{collections::btree_map::BTreeMap, format, string::String, vec::Vec};
6use core::hash::Hash;
7
8use crate::{
9 corety::*,
10 css::*,
11 props::{basic::*, layout::*, property::*, style::*},
12};
13
14pub trait FormatAsRustCode {
16 fn format_as_rust_code(&self, tabs: usize) -> String;
17}
18
19pub trait GetHash {
21 fn get_hash(&self) -> u64;
22}
23
24impl<T: Hash> GetHash for T {
25 fn get_hash(&self) -> u64 {
26 use highway::{HighwayHash, HighwayHasher, Key};
27 let mut hasher = HighwayHasher::new(Key([0; 4]));
28 self.hash(&mut hasher);
29 hasher.finalize64()
30 }
31}
32
33#[derive(Default)]
36pub struct VecContents {
37 pub strings: BTreeMap<u64, AzString>,
39 pub style_filters: BTreeMap<u64, StyleFilterVec>,
40 pub style_background_sizes: BTreeMap<u64, StyleBackgroundSizeVec>,
41 pub style_background_repeats: BTreeMap<u64, StyleBackgroundRepeatVec>,
42 pub style_background_contents: BTreeMap<u64, StyleBackgroundContentVec>,
43 pub style_background_positions: BTreeMap<u64, StyleBackgroundPositionVec>,
44 pub style_transforms: BTreeMap<u64, StyleTransformVec>,
45 pub font_families: BTreeMap<u64, StyleFontFamilyVec>,
46 pub linear_color_stops: BTreeMap<u64, NormalizedLinearColorStopVec>,
47 pub radial_color_stops: BTreeMap<u64, NormalizedRadialColorStopVec>,
48}
49
50impl VecContents {
51 pub fn format(&self, tabs: usize) -> String {
52 let mut result = String::new();
53 let t = " ".repeat(tabs);
54 let t2 = " ".repeat(tabs + 1);
55
56 for (key, item) in self.strings.iter() {
57 result.push_str(&format!(
58 "\r\n const STRING_{}: AzString = AzString::from_const_str(\"{}\");",
59 key,
60 item.as_str()
61 ));
62 }
63
64 for (key, item) in self.style_filters.iter() {
65 let val = item
66 .iter()
67 .map(|filter| format_style_filter(filter, tabs + 1))
68 .collect::<Vec<_>>()
69 .join(&format!(",\r\n{}", t));
70
71 result.push_str(&format!(
72 "\r\n const STYLE_FILTER_{}_ITEMS: &[StyleFilter] = &[\r\n{}{}\r\n{}];",
73 key, t2, val, t
74 ));
75 }
76
77 for (key, item) in self.style_background_sizes.iter() {
78 let val = item
79 .iter()
80 .map(|bgs| format_style_background_size(bgs))
81 .collect::<Vec<_>>()
82 .join(&format!(",\r\n{}", t));
83
84 result.push_str(&format!(
85 "\r\n const STYLE_BACKGROUND_SIZE_{}_ITEMS: &[StyleBackgroundSize] = \
86 &[\r\n{}{}\r\n{}];",
87 key, t2, val, t
88 ));
89 }
90
91 for (key, item) in self.style_background_repeats.iter() {
92 let val = item
93 .iter()
94 .map(|bgr| bgr.format_as_rust_code(tabs + 1))
95 .collect::<Vec<_>>()
96 .join(&format!(",\r\n{}", t));
97
98 result.push_str(&format!(
99 "\r\n const STYLE_BACKGROUND_REPEAT_{}_ITEMS: &[StyleBackgroundRepeat] = \
100 &[\r\n{}{}\r\n{}];",
101 key, t2, val, t
102 ));
103 }
104
105 for (key, item) in self.style_background_contents.iter() {
106 let val = item
107 .iter()
108 .map(|bgc| format_style_background_content(bgc, tabs + 1))
109 .collect::<Vec<_>>()
110 .join(&format!(",\r\n{}", t));
111
112 result.push_str(&format!(
113 "\r\n const STYLE_BACKGROUND_CONTENT_{}_ITEMS: &[StyleBackgroundContent] = \
114 &[\r\n{}{}\r\n{}];",
115 key, t2, val, t
116 ));
117 }
118
119 for (key, item) in self.style_background_positions.iter() {
120 let val = item
121 .iter()
122 .map(|bgp| format_style_background_position(bgp, tabs))
123 .collect::<Vec<_>>()
124 .join(&format!(",\r\n{}", t));
125
126 result.push_str(&format!(
127 "\r\n const STYLE_BACKGROUND_POSITION_{}_ITEMS: &[StyleBackgroundPosition] = \
128 &[\r\n{}{}\r\n{}];",
129 key, t2, val, t
130 ));
131 }
132
133 for (key, item) in self.style_transforms.iter() {
134 let val = format_style_transforms(item.as_ref(), tabs + 1);
135
136 result.push_str(&format!(
137 "\r\n const STYLE_TRANSFORM_{}_ITEMS: &[StyleTransform] = &[\r\n{}{}\r\n{}];",
138 key, t2, val, t
139 ));
140 }
141
142 for (key, item) in self.font_families.iter() {
143 let val = format_font_ids(item.as_ref(), tabs + 1);
144
145 result.push_str(&format!(
146 "\r\n const STYLE_FONT_FAMILY_{}_ITEMS: &[StyleFontFamily] = &[\r\n{}{}\r\n{}];",
147 key, t2, val, t
148 ));
149 }
150
151 for (key, item) in self.linear_color_stops.iter() {
152 let val = format_linear_color_stops(item.as_ref(), 1);
153
154 result.push_str(&format!(
155 "\r\n const LINEAR_COLOR_STOP_{}_ITEMS: &[NormalizedLinearColorStop] = \
156 &[\r\n{}{}\r\n{}];",
157 key, t2, val, t
158 ));
159 }
160
161 for (key, item) in self.radial_color_stops.iter() {
162 let val = format_radial_color_stops(item.as_ref(), tabs);
163
164 result.push_str(&format!(
165 "\r\n const RADIAL_COLOR_STOP_{}_ITEMS: &[NormalizedRadialColorStop] = \
166 &[\r\n{}{}\r\n{}];",
167 key, t2, val, t
168 ));
169 }
170
171 result
172 }
173
174 pub fn insert_from_css_property(&mut self, prop: &CssProperty) {
176 match prop {
177 CssProperty::FontFamily(CssPropertyValue::Exact(v)) => {
178 for family in v.iter() {
179 match family {
180 StyleFontFamily::System(s) => {
181 let s = s.as_str();
184 let s = s.trim();
185 let s = s.trim_start_matches('\"');
186 let s = s.trim_end_matches('\"');
187 let s = s.trim_start_matches('\'');
188 let s = s.trim_end_matches('\'');
189
190 self.strings.insert(s.get_hash(), s.to_string().into());
191 }
192 StyleFontFamily::File(s) => {
193 let s = s.as_str();
194 let s = s.trim();
195 let s = s.trim_start_matches('\"');
196 let s = s.trim_end_matches('\"');
197 let s = s.trim_start_matches('\'');
198 let s = s.trim_end_matches('\'');
199
200 self.strings.insert(s.get_hash(), s.to_string().into());
201 }
202 _ => {}
203 }
204 }
205 self.font_families.insert(v.get_hash(), v.clone());
206 }
207 CssProperty::Transform(CssPropertyValue::Exact(v)) => {
208 self.style_transforms.insert(v.get_hash(), v.clone());
209 }
210 CssProperty::BackgroundRepeat(CssPropertyValue::Exact(v)) => {
211 self.style_background_repeats
212 .insert(v.get_hash(), v.clone());
213 }
214 CssProperty::BackgroundSize(CssPropertyValue::Exact(v)) => {
215 self.style_background_sizes.insert(v.get_hash(), v.clone());
216 }
217 CssProperty::BackgroundPosition(CssPropertyValue::Exact(v)) => {
218 self.style_background_positions
219 .insert(v.get_hash(), v.clone());
220 }
221 CssProperty::BackgroundContent(CssPropertyValue::Exact(v)) => {
222 for background in v.iter() {
223 match background {
224 StyleBackgroundContent::Image(id) => {
225 self.strings.insert(id.get_hash(), id.clone());
226 }
227 StyleBackgroundContent::LinearGradient(lg) => {
228 self.linear_color_stops
229 .insert(lg.stops.get_hash(), lg.stops.clone());
230 }
231 StyleBackgroundContent::RadialGradient(rg) => {
232 self.linear_color_stops
233 .insert(rg.stops.get_hash(), rg.stops.clone());
234 }
235 StyleBackgroundContent::ConicGradient(lg) => {
236 self.radial_color_stops
237 .insert(lg.stops.get_hash(), lg.stops.clone());
238 }
239 _ => {}
240 }
241 }
242 self.style_background_contents
243 .insert(v.get_hash(), v.clone());
244 }
245 CssProperty::Filter(CssPropertyValue::Exact(v)) => {
246 self.style_filters.insert(v.get_hash(), v.clone());
247 }
248 CssProperty::BackdropFilter(CssPropertyValue::Exact(v)) => {
249 self.style_filters.insert(v.get_hash(), v.clone());
250 }
251 _ => {}
252 }
253 }
254}
255
256pub fn format_pixel_value(p: &PixelValue) -> String {
259 let value = p.number.get();
260
261 let pre_comma = libm::floorf(value) as isize;
266 let fraction = value - pre_comma as f32;
267 let post_comma = libm::roundf(fraction * 100.0) as isize;
269
270 match p.metric {
271 SizeMetric::Px => format!(
272 "PixelValue::const_from_metric_fractional(SizeMetric::Px, {}, {})",
273 pre_comma, post_comma
274 ),
275 SizeMetric::Pt => format!(
276 "PixelValue::const_pt_fractional({}, {})",
277 pre_comma, post_comma
278 ),
279 SizeMetric::Em => format!(
280 "PixelValue::const_em_fractional({}, {})",
281 pre_comma, post_comma
282 ),
283 SizeMetric::Rem => format!(
284 "PixelValue::const_from_metric_fractional(SizeMetric::Rem, {}, {})",
285 pre_comma, post_comma
286 ),
287 SizeMetric::Percent => format!(
288 "PixelValue::const_from_metric_fractional(SizeMetric::Percent, {}, {})",
289 pre_comma, post_comma
290 ),
291 SizeMetric::In => format!(
292 "PixelValue::const_from_metric_fractional(SizeMetric::In, {}, {})",
293 pre_comma, post_comma
294 ),
295 SizeMetric::Cm => format!(
296 "PixelValue::const_from_metric_fractional(SizeMetric::Cm, {}, {})",
297 pre_comma, post_comma
298 ),
299 SizeMetric::Mm => format!(
300 "PixelValue::const_from_metric_fractional(SizeMetric::Mm, {}, {})",
301 pre_comma, post_comma
302 ),
303 SizeMetric::Vw => format!(
304 "PixelValue::const_from_metric_fractional(SizeMetric::Vw, {}, {})",
305 pre_comma, post_comma
306 ),
307 SizeMetric::Vh => format!(
308 "PixelValue::const_from_metric_fractional(SizeMetric::Vh, {}, {})",
309 pre_comma, post_comma
310 ),
311 SizeMetric::Vmin => format!(
312 "PixelValue::const_from_metric_fractional(SizeMetric::Vmin, {}, {})",
313 pre_comma, post_comma
314 ),
315 SizeMetric::Vmax => format!(
316 "PixelValue::const_from_metric_fractional(SizeMetric::Vmax, {}, {})",
317 pre_comma, post_comma
318 ),
319 }
320}
321
322pub fn format_pixel_value_no_percent(p: &PixelValueNoPercent) -> String {
323 format!(
324 "PixelValueNoPercent {{ inner: {} }}",
325 format_pixel_value(&p.inner)
326 )
327}
328
329pub fn format_float_value(f: &FloatValue) -> String {
330 format!("FloatValue::const_new({})", libm::roundf(f.get()) as isize)
331}
332
333pub fn format_percentage_value(f: &PercentageValue) -> String {
334 format!(
335 "PercentageValue::const_new({})",
336 libm::roundf(f.normalized() * 100.0) as isize
337 )
338}
339
340pub fn format_angle_value(f: &AngleValue) -> String {
341 format!(
342 "AngleValue::const_deg({})",
343 libm::roundf(f.to_degrees()) as isize
344 )
345}
346
347pub fn format_color_value(c: &ColorU) -> String {
348 format!(
349 "ColorU {{ r: {}, g: {}, b: {}, a: {} }}",
350 c.r, c.g, c.b, c.a
351 )
352}
353
354macro_rules! impl_float_value_fmt {
357 ($struct_name:ident) => {
358 impl FormatAsRustCode for $struct_name {
359 fn format_as_rust_code(&self, _tabs: usize) -> String {
360 format!(
361 "{} {{ inner: {} }}",
362 stringify!($struct_name),
363 format_float_value(&self.inner)
364 )
365 }
366 }
367 };
368}
369
370impl_float_value_fmt!(LayoutFlexGrow);
371impl_float_value_fmt!(LayoutFlexShrink);
372
373macro_rules! impl_percentage_value_fmt {
374 ($struct_name:ident) => {
375 impl FormatAsRustCode for $struct_name {
376 fn format_as_rust_code(&self, _tabs: usize) -> String {
377 format!(
378 "{} {{ inner: {} }}",
379 stringify!($struct_name),
380 format_percentage_value(&self.inner)
381 )
382 }
383 }
384 };
385}
386
387impl_percentage_value_fmt!(StyleLineHeight);
388impl_percentage_value_fmt!(StyleOpacity);
389
390macro_rules! impl_pixel_value_fmt {
391 ($struct_name:ident) => {
392 impl FormatAsRustCode for $struct_name {
393 fn format_as_rust_code(&self, _tabs: usize) -> String {
394 format!(
395 "{} {{ inner: {} }}",
396 stringify!($struct_name),
397 format_pixel_value(&self.inner)
398 )
399 }
400 }
401 };
402}
403
404impl_pixel_value_fmt!(StyleTabWidth);
405impl_pixel_value_fmt!(StyleBorderTopLeftRadius);
406impl_pixel_value_fmt!(StyleBorderBottomLeftRadius);
407impl_pixel_value_fmt!(StyleBorderTopRightRadius);
408impl_pixel_value_fmt!(StyleBorderBottomRightRadius);
409
410impl_pixel_value_fmt!(LayoutBorderTopWidth);
411impl_pixel_value_fmt!(LayoutBorderLeftWidth);
412impl_pixel_value_fmt!(LayoutBorderRightWidth);
413impl_pixel_value_fmt!(LayoutBorderBottomWidth);
414impl_pixel_value_fmt!(StyleLetterSpacing);
415impl_pixel_value_fmt!(StyleWordSpacing);
416impl_pixel_value_fmt!(StyleFontSize);
417
418impl_pixel_value_fmt!(LayoutMarginTop);
419impl_pixel_value_fmt!(LayoutMarginBottom);
420impl_pixel_value_fmt!(LayoutMarginRight);
421impl_pixel_value_fmt!(LayoutMarginLeft);
422
423impl_pixel_value_fmt!(LayoutPaddingTop);
424impl_pixel_value_fmt!(LayoutPaddingBottom);
425impl_pixel_value_fmt!(LayoutPaddingRight);
426impl_pixel_value_fmt!(LayoutPaddingLeft);
427impl_pixel_value_fmt!(LayoutPaddingInlineStart);
428impl_pixel_value_fmt!(LayoutPaddingInlineEnd);
429
430impl FormatAsRustCode for LayoutWidth {
431 fn format_as_rust_code(&self, _tabs: usize) -> String {
432 match self {
433 LayoutWidth::Auto => "LayoutWidth::Auto".to_string(),
434 LayoutWidth::Px(px) => format!("LayoutWidth::Px({})", format_pixel_value(px)),
435 LayoutWidth::MinContent => "LayoutWidth::MinContent".to_string(),
436 LayoutWidth::MaxContent => "LayoutWidth::MaxContent".to_string(),
437 }
438 }
439}
440
441impl FormatAsRustCode for LayoutHeight {
442 fn format_as_rust_code(&self, _tabs: usize) -> String {
443 match self {
444 LayoutHeight::Auto => "LayoutHeight::Auto".to_string(),
445 LayoutHeight::Px(px) => format!("LayoutHeight::Px({})", format_pixel_value(px)),
446 LayoutHeight::MinContent => "LayoutHeight::MinContent".to_string(),
447 LayoutHeight::MaxContent => "LayoutHeight::MaxContent".to_string(),
448 }
449 }
450}
451
452impl_pixel_value_fmt!(LayoutMinHeight);
453impl_pixel_value_fmt!(LayoutMinWidth);
454impl_pixel_value_fmt!(LayoutMaxWidth);
455impl_pixel_value_fmt!(LayoutMaxHeight);
456impl_pixel_value_fmt!(LayoutTop);
457impl_pixel_value_fmt!(LayoutInsetBottom);
458
459impl_pixel_value_fmt!(LayoutRight);
460impl_pixel_value_fmt!(LayoutLeft);
461
462impl_pixel_value_fmt!(LayoutColumnGap);
465impl_pixel_value_fmt!(LayoutRowGap);
466
467impl_grid_value_fmt!(GridTemplate);
468impl_grid_value_fmt!(GridPlacement);
469
470impl_color_value_fmt!(StyleTextColor);
471impl_color_value_fmt!(StyleBorderTopColor);
472impl_color_value_fmt!(StyleBorderLeftColor);
473impl_color_value_fmt!(StyleBorderRightColor);
474impl_color_value_fmt!(StyleBorderBottomColor);
475
476impl_enum_fmt!(
477 StyleMixBlendMode,
478 Normal,
479 Multiply,
480 Screen,
481 Overlay,
482 Darken,
483 Lighten,
484 ColorDodge,
485 ColorBurn,
486 HardLight,
487 SoftLight,
488 Difference,
489 Exclusion,
490 Hue,
491 Saturation,
492 Color,
493 Luminosity
494);
495
496impl_enum_fmt!(StyleHyphens, Auto, None);
497
498impl_enum_fmt!(StyleDirection, Ltr, Rtl);
499
500impl_enum_fmt!(StyleWhiteSpace, Normal, Pre, Nowrap);
501
502impl_enum_fmt!(StyleVisibility, Visible, Hidden, Collapse);
503
504impl_enum_fmt!(LayoutWritingMode, HorizontalTb, VerticalRl, VerticalLr);
505
506impl_enum_fmt!(LayoutClear, None, Left, Right, Both);
507
508impl_enum_fmt!(
509 StyleCursor,
510 Alias,
511 AllScroll,
512 Cell,
513 ColResize,
514 ContextMenu,
515 Copy,
516 Crosshair,
517 Default,
518 EResize,
519 EwResize,
520 Grab,
521 Grabbing,
522 Help,
523 Move,
524 NResize,
525 NsResize,
526 NeswResize,
527 NwseResize,
528 Pointer,
529 Progress,
530 RowResize,
531 SResize,
532 SeResize,
533 Text,
534 Unset,
535 VerticalText,
536 WResize,
537 Wait,
538 ZoomIn,
539 ZoomOut
540);
541
542impl_enum_fmt!(
543 BorderStyle,
544 None,
545 Solid,
546 Double,
547 Dotted,
548 Dashed,
549 Hidden,
550 Groove,
551 Ridge,
552 Inset,
553 Outset
554);
555
556impl_enum_fmt!(
557 StyleBackgroundRepeat,
558 NoRepeat,
559 PatternRepeat,
560 RepeatX,
561 RepeatY
562);
563
564impl_enum_fmt!(
565 LayoutDisplay,
566 None,
567 Block,
568 Inline,
569 InlineBlock,
570 Flex,
571 InlineFlex,
572 Table,
573 InlineTable,
574 TableRowGroup,
575 TableHeaderGroup,
576 TableFooterGroup,
577 TableRow,
578 TableColumnGroup,
579 TableColumn,
580 TableCell,
581 TableCaption,
582 ListItem,
583 RunIn,
584 Marker,
585 Grid,
586 InlineGrid,
587 FlowRoot
588);
589
590impl_enum_fmt!(LayoutFloat, Left, Right, None);
591
592impl_enum_fmt!(LayoutBoxSizing, ContentBox, BorderBox);
593
594impl_enum_fmt!(LayoutFlexDirection, Row, RowReverse, Column, ColumnReverse);
595
596impl_enum_fmt!(LayoutFlexWrap, Wrap, NoWrap, WrapReverse);
597
598impl_enum_fmt!(
599 LayoutJustifyContent,
600 Start,
601 End,
602 FlexStart,
603 FlexEnd,
604 Center,
605 SpaceBetween,
606 SpaceAround,
607 SpaceEvenly
608);
609
610impl_enum_fmt!(LayoutAlignItems, Stretch, Center, Start, End, Baseline);
611
612impl_enum_fmt!(
613 LayoutAlignContent,
614 Start,
615 End,
616 Stretch,
617 Center,
618 SpaceBetween,
619 SpaceAround
620);
621
622impl_enum_fmt!(Shape, Circle, Ellipse);
623
624impl_enum_fmt!(LayoutOverflow, Auto, Scroll, Visible, Hidden, Clip);
625
626impl_enum_fmt!(StyleTextAlign, Center, Left, Right, Justify, Start, End);
627
628impl_enum_fmt!(StyleUserSelect, Auto, Text, None, All);
629
630impl_enum_fmt!(StyleTextDecoration, None, Underline, Overline, LineThrough);
631
632impl_enum_fmt!(
633 DirectionCorner,
634 Right,
635 Left,
636 Top,
637 Bottom,
638 TopRight,
639 TopLeft,
640 BottomRight,
641 BottomLeft
642);
643
644impl_enum_fmt!(ExtendMode, Clamp, Repeat);
645
646impl_enum_fmt!(StyleBackfaceVisibility, Visible, Hidden);
647
648fn format_style_background_size(c: &StyleBackgroundSize) -> String {
651 match c {
652 StyleBackgroundSize::Contain => String::from("StyleBackgroundSize::Contain"),
653 StyleBackgroundSize::Cover => String::from("StyleBackgroundSize::Cover"),
654 StyleBackgroundSize::ExactSize(size) => format!(
655 "StyleBackgroundSize::ExactSize(PixelValueSize {{ width: {}, height: {} }})",
656 format_pixel_value(&size.width),
657 format_pixel_value(&size.height)
658 ),
659 }
660}
661
662pub fn format_scrollbar_info(s: &ScrollbarInfo, tabs: usize) -> String {
665 let t = String::from(" ").repeat(tabs);
666 let t1 = String::from(" ").repeat(tabs + 1);
667 format!(
668 "ScrollbarInfo {{\r\n{}width: {},\r\n{}padding_left: {},\r\n{}padding_right: \
669 {},\r\n{}track: {},\r\n{}thumb: {},\r\n{}button: {},\r\n{}button: {},\r\n{}resizer: \
670 {},\r\n{}}}",
671 t1,
672 s.width.format_as_rust_code(tabs + 1),
673 t1,
674 s.padding_left.format_as_rust_code(tabs + 1),
675 t1,
676 s.padding_right.format_as_rust_code(tabs + 1),
677 t1,
678 format_style_background_content(&s.track, tabs + 1),
679 t1,
680 format_style_background_content(&s.thumb, tabs + 1),
681 t1,
682 format_style_background_content(&s.button, tabs + 1),
683 t1,
684 format_style_background_content(&s.corner, tabs + 1),
685 t1,
686 format_style_background_content(&s.resizer, tabs + 1),
687 t
688 )
689}
690
691fn format_style_background_content(content: &StyleBackgroundContent, tabs: usize) -> String {
694 match content {
695 StyleBackgroundContent::LinearGradient(l) => format!(
696 "StyleBackgroundContent::LinearGradient({})",
697 format_linear_gradient(l, tabs)
698 ),
699 StyleBackgroundContent::RadialGradient(r) => format!(
700 "StyleBackgroundContent::RadialGradient({})",
701 format_radial_gradient(r, tabs)
702 ),
703 StyleBackgroundContent::ConicGradient(r) => format!(
704 "StyleBackgroundContent::ConicGradient({})",
705 format_conic_gradient(r, tabs)
706 ),
707 StyleBackgroundContent::Image(id) => format!("StyleBackgroundContent::Image({:?})", id),
708 StyleBackgroundContent::Color(c) => {
709 format!("StyleBackgroundContent::Color({})", format_color_value(c))
710 }
711 }
712}
713
714fn format_direction(d: &Direction, tabs: usize) -> String {
715 match d {
716 Direction::Angle(fv) => format!("Direction::Angle({})", format_angle_value(fv)),
717 Direction::FromTo(DirectionCorners { dir_from, dir_to }) => format!(
718 "Direction::FromTo(DirectionCorners {{ dir_from: {}, dir_to: {} }})",
719 dir_from.format_as_rust_code(tabs + 1),
720 dir_to.format_as_rust_code(tabs + 1)
721 ),
722 }
723}
724
725fn format_linear_gradient(l: &LinearGradient, tabs: usize) -> String {
726 let t = String::from(" ").repeat(tabs);
727 let t1 = String::from(" ").repeat(tabs + 1);
728 format!(
729 "LinearGradient {{\r\n{}direction: {},\r\n{}extend_mode: {},\r\n{}stops: \
730 NormalizedLinearColorStopVec::from_const_slice(LINEAR_COLOR_STOP_{}_ITEMS),\r\n{}}}",
731 t1,
732 format_direction(&l.direction, tabs + 1),
733 t1,
734 l.extend_mode.format_as_rust_code(tabs + 1),
735 t1,
736 l.stops.get_hash(),
737 t,
738 )
739}
740
741fn format_conic_gradient(r: &ConicGradient, tabs: usize) -> String {
742 let t = String::from(" ").repeat(tabs);
743 let t1 = String::from(" ").repeat(tabs + 1);
744
745 format!(
746 "ConicGradient {{\r\n{}extend_mode: {},\r\n{}center: {},\r\n{}angle: {},\r\n{}stops: \
747 NormalizedRadialColorStopVec::from_const_slice(RADIAL_COLOR_STOP_{}_ITEMS),\r\n{}}}",
748 t1,
749 r.extend_mode.format_as_rust_code(tabs + 1),
750 t1,
751 format_style_background_position(&r.center, tabs + 1),
752 t1,
753 format_angle_value(&r.angle),
754 t1,
755 r.stops.get_hash(),
756 t,
757 )
758}
759
760fn format_radial_gradient(r: &RadialGradient, tabs: usize) -> String {
761 let t = String::from(" ").repeat(tabs);
762 let t1 = String::from(" ").repeat(tabs + 1);
763 format!(
764 "RadialGradient {{\r\n{}shape: {},\r\n{}extend_mode: {},\r\n{}position: {},\r\n{}size: \
765 RadialGradientSize::{:?},\r\n{}stops: \
766 NormalizedLinearColorStopVec::from_const_slice(LINEAR_COLOR_STOP_{}_ITEMS),\r\n{}}}",
767 t1,
768 r.shape.format_as_rust_code(tabs + 1),
769 t1,
770 r.extend_mode.format_as_rust_code(tabs + 1),
771 t1,
772 format_style_background_position(&r.position, tabs + 1),
773 t1,
774 r.size,
775 t1,
776 r.stops.get_hash(),
777 t,
778 )
779}
780
781fn format_linear_color_stops(stops: &[NormalizedLinearColorStop], tabs: usize) -> String {
782 let t = String::from(" ").repeat(tabs);
783 stops
784 .iter()
785 .map(|s| format_linear_color_stop(s))
786 .collect::<Vec<_>>()
787 .join(&format!(",\r\n{}", t))
788}
789
790fn format_linear_color_stop(g: &NormalizedLinearColorStop) -> String {
791 format!(
792 "NormalizedLinearColorStop {{ offset: {}, color: {} }}",
793 format_percentage_value(&g.offset),
794 format_color_value(&g.color),
795 )
796}
797
798fn format_radial_color_stops(stops: &[NormalizedRadialColorStop], tabs: usize) -> String {
799 let t = String::from(" ").repeat(tabs);
800 stops
801 .iter()
802 .map(|s| format_radial_color_stop(s))
803 .collect::<Vec<_>>()
804 .join(&format!(",\r\n{}", t))
805}
806
807fn format_radial_color_stop(g: &NormalizedRadialColorStop) -> String {
808 format!(
809 "RadialColorStop {{ angle: {}, color: {} }}",
810 format_angle_value(&g.angle),
811 format_color_value(&g.color),
812 )
813}
814
815fn format_style_filter(st: &StyleFilter, tabs: usize) -> String {
816 let tabs_minus_one = String::from(" ").repeat(tabs);
817 let tabs_str = String::from(" ").repeat(tabs + 1);
818 match st {
819 StyleFilter::Blend(mb) => format!("StyleFilter::Blend({})", mb.format_as_rust_code(tabs)),
820 StyleFilter::Flood(c) => format!("StyleFilter::Flood({})", format_color_value(c)),
821 StyleFilter::Blur(m) => format!(
822 "StyleFilter::Blur(StyleBlur {{ width: {}, height: {} }})",
823 format_pixel_value(&m.width),
824 format_pixel_value(&m.height)
825 ),
826 StyleFilter::Opacity(pct) => {
827 format!("StyleFilter::Opacity({})", format_percentage_value(pct))
828 }
829 StyleFilter::ColorMatrix(cm) => format!(
830 "StyleFilter::ColorMatrix(StyleColorMatrix {{ m0: {}, m1: {}, m2: {}, m3: {}, m4: {}, \
831 m5: {}, m6: {}, m7: {}, m8: {}, m9: {}, m10: {}, m11: {}, m12: {}, m13: {}, m14: {}, \
832 m15: {}, m16: {}, m17: {}, m18: {}, m19: {} }})",
833 format_float_value(&cm.m0),
834 format_float_value(&cm.m1),
835 format_float_value(&cm.m2),
836 format_float_value(&cm.m3),
837 format_float_value(&cm.m4),
838 format_float_value(&cm.m5),
839 format_float_value(&cm.m6),
840 format_float_value(&cm.m7),
841 format_float_value(&cm.m8),
842 format_float_value(&cm.m9),
843 format_float_value(&cm.m10),
844 format_float_value(&cm.m11),
845 format_float_value(&cm.m12),
846 format_float_value(&cm.m13),
847 format_float_value(&cm.m14),
848 format_float_value(&cm.m15),
849 format_float_value(&cm.m16),
850 format_float_value(&cm.m17),
851 format_float_value(&cm.m18),
852 format_float_value(&cm.m19)
853 ),
854 StyleFilter::DropShadow(m) => {
855 format!("StyleFilter::DropShadow({})", m.format_as_rust_code(tabs))
856 }
857 StyleFilter::ComponentTransfer => format!("StyleFilter::ComponentTransfer"),
858 StyleFilter::Offset(o) => format!(
859 "StyleFilter::Offset(StyleFilterOffset {{ x: {}, y: {} }})",
860 format_pixel_value(&o.x),
861 format_pixel_value(&o.y)
862 ),
863 StyleFilter::Composite(StyleCompositeFilter::Over) => {
864 format!("StyleFilter::Composite(StyleCompositeFilter::Over)")
865 }
866 StyleFilter::Composite(StyleCompositeFilter::In) => {
867 format!("StyleFilter::Composite(StyleCompositeFilter::In)")
868 }
869 StyleFilter::Composite(StyleCompositeFilter::Atop) => {
870 format!("StyleFilter::Composite(StyleCompositeFilter::Atop)")
871 }
872 StyleFilter::Composite(StyleCompositeFilter::Out) => {
873 format!("StyleFilter::Composite(StyleCompositeFilter::Out)")
874 }
875 StyleFilter::Composite(StyleCompositeFilter::Xor) => {
876 format!("StyleFilter::Composite(StyleCompositeFilter::Xor)")
877 }
878 StyleFilter::Composite(StyleCompositeFilter::Lighter) => {
879 format!("StyleFilter::Composite(StyleCompositeFilter::Lighter)")
880 }
881 StyleFilter::Composite(StyleCompositeFilter::Arithmetic(fv)) => format!(
882 "StyleFilter::Composite(StyleCompositeFilter::Arithmetic(ArithmeticCoefficients {{ \
883 k1: {}, k2: {}, k3: {}, k4: {} }}))",
884 format_float_value(&fv.k1),
885 format_float_value(&fv.k2),
886 format_float_value(&fv.k3),
887 format_float_value(&fv.k4)
888 ),
889 }
890}
891
892fn format_style_transforms(stops: &[StyleTransform], tabs: usize) -> String {
893 let t = String::from(" ").repeat(tabs);
894 stops
895 .iter()
896 .map(|s| format_style_transform(s, tabs))
897 .collect::<Vec<_>>()
898 .join(&format!(",\r\n{}", t))
899}
900
901fn format_style_transform(st: &StyleTransform, tabs: usize) -> String {
902 let tabs_minus_one = String::from(" ").repeat(tabs);
903 let tabs = String::from(" ").repeat(tabs + 1);
904 match st {
905 StyleTransform::Matrix(m) => format!(
906 "StyleTransform::Matrix(StyleTransformMatrix2D {{ a: {}, b: {}, c: {}, d: {}, tx: {}, \
907 ty: {} }})",
908 format_float_value(&m.a),
909 format_float_value(&m.b),
910 format_float_value(&m.c),
911 format_float_value(&m.d),
912 format_float_value(&m.tx),
913 format_float_value(&m.ty)
914 ),
915 StyleTransform::Matrix3D(m) => format!(
916 "StyleTransform::Matrix3D(StyleTransformMatrix3D {{\r\n{tabs}m11: {},\r\n{tabs}m12: \
917 {},\r\n{tabs}m13: {},\r\n{tabs}m14: {},\r\n{tabs}m21: {},\r\n{tabs}m22: \
918 {},\r\n{tabs}m23: {},\r\n{tabs}m24: {},\r\n{tabs}m31: {},\r\n{tabs}m32: \
919 {},\r\n{tabs}m33: {},\r\n{tabs}m34: {},\r\n{tabs}m41: {},\r\n{tabs}m42: \
920 {},\r\n{tabs}m43: {},\r\n{tabs}m44: {}\r\n{tabs_minus_one}}})",
921 format_float_value(&m.m11),
922 format_float_value(&m.m12),
923 format_float_value(&m.m13),
924 format_float_value(&m.m14),
925 format_float_value(&m.m21),
926 format_float_value(&m.m22),
927 format_float_value(&m.m23),
928 format_float_value(&m.m24),
929 format_float_value(&m.m31),
930 format_float_value(&m.m32),
931 format_float_value(&m.m33),
932 format_float_value(&m.m34),
933 format_float_value(&m.m41),
934 format_float_value(&m.m42),
935 format_float_value(&m.m43),
936 format_float_value(&m.m44),
937 tabs = tabs,
938 tabs_minus_one = tabs_minus_one,
939 ),
940 StyleTransform::Translate(t) => format!(
941 "StyleTransform::Translate(StyleTransformTranslate2D {{ x: {}, y: {} }})",
942 format_pixel_value(&t.x),
943 format_pixel_value(&t.y)
944 ),
945 StyleTransform::Translate3D(t) => format!(
946 "StyleTransform::Translate3D(StyleTransformTranslate3D {{ x: {}, y: {}, z: {})",
947 format_pixel_value(&t.x),
948 format_pixel_value(&t.y),
949 format_pixel_value(&t.z)
950 ),
951 StyleTransform::TranslateX(x) => {
952 format!("StyleTransform::TranslateX({})", format_pixel_value(&x))
953 }
954 StyleTransform::TranslateY(y) => {
955 format!("StyleTransform::TranslateY({})", format_pixel_value(&y))
956 }
957 StyleTransform::TranslateZ(z) => {
958 format!("StyleTransform::TranslateZ({})", format_pixel_value(&z))
959 }
960 StyleTransform::Rotate(r) => format!("StyleTransform::Rotate({})", format_angle_value(&r)),
961 StyleTransform::Rotate3D(r) => format!(
962 "StyleTransform::Rotate3D(StyleTransformRotate3D {{ {}, {}, {}, {} }})",
963 format_float_value(&r.x),
964 format_float_value(&r.y),
965 format_float_value(&r.z),
966 format_angle_value(&r.angle)
967 ),
968 StyleTransform::RotateX(x) => {
969 format!("StyleTransform::RotateX({})", format_angle_value(&x))
970 }
971 StyleTransform::RotateY(y) => {
972 format!("StyleTransform::RotateY({})", format_angle_value(&y))
973 }
974 StyleTransform::RotateZ(z) => {
975 format!("StyleTransform::RotateZ({})", format_angle_value(&z))
976 }
977 StyleTransform::Scale(s) => format!(
978 "StyleTransform::Scale(StyleTransformScale2D {{ x: {}, y: {} }})",
979 format_float_value(&s.x),
980 format_float_value(&s.y)
981 ),
982 StyleTransform::Scale3D(s) => format!(
983 "StyleTransform::Scale3D(StyleTransformScale3D {{ x; {}, y: {}, z: {} }})",
984 format_float_value(&s.x),
985 format_float_value(&s.y),
986 format_float_value(&s.z)
987 ),
988 StyleTransform::ScaleX(x) => {
989 format!("StyleTransform::ScaleX({})", format_percentage_value(&x))
990 }
991 StyleTransform::ScaleY(y) => {
992 format!("StyleTransform::ScaleY({})", format_percentage_value(&y))
993 }
994 StyleTransform::ScaleZ(z) => {
995 format!("StyleTransform::ScaleZ({})", format_percentage_value(&z))
996 }
997 StyleTransform::Skew(sk) => format!(
998 "StyleTransform::Skew(StyleTransformSkew2D {{ x: {}, y: {} }})",
999 format_angle_value(&sk.x),
1000 format_angle_value(&sk.y)
1001 ),
1002 StyleTransform::SkewX(x) => {
1003 format!("StyleTransform::SkewX({})", format_angle_value(&x))
1004 }
1005 StyleTransform::SkewY(y) => {
1006 format!("StyleTransform::SkewY({})", format_angle_value(&y))
1007 }
1008 StyleTransform::Perspective(dist) => {
1009 format!("StyleTransform::Perspective({})", format_pixel_value(&dist))
1010 }
1011 }
1012}
1013
1014fn format_font_ids(font_ids: &[StyleFontFamily], tabs: usize) -> String {
1015 let t = String::from(" ").repeat(tabs);
1016 font_ids
1017 .iter()
1018 .map(|s| format!("{}", s.format_as_rust_code(tabs + 1)))
1019 .collect::<Vec<_>>()
1020 .join(&format!(",\r\n{}", t))
1021}
1022
1023fn format_style_background_position(b: &StyleBackgroundPosition, tabs: usize) -> String {
1024 let t = String::from(" ").repeat(tabs);
1025 let t1 = String::from(" ").repeat(tabs + 1);
1026 format!(
1027 "StyleBackgroundPosition {{\r\n{}horizontal: {},\r\n{}vertical: {},\r\n{}}}",
1028 t1,
1029 format_background_position_horizontal(&b.horizontal),
1030 t1,
1031 format_background_position_vertical(&b.vertical),
1032 t
1033 )
1034}
1035
1036fn format_background_position_horizontal(b: &BackgroundPositionHorizontal) -> String {
1037 match b {
1038 BackgroundPositionHorizontal::Left => format!("BackgroundPositionHorizontal::Left"),
1039 BackgroundPositionHorizontal::Center => format!("BackgroundPositionHorizontal::Center"),
1040 BackgroundPositionHorizontal::Right => format!("BackgroundPositionHorizontal::Right"),
1041 BackgroundPositionHorizontal::Exact(p) => format!(
1042 "BackgroundPositionHorizontal::Exact({})",
1043 format_pixel_value(p)
1044 ),
1045 }
1046}
1047
1048fn format_background_position_vertical(b: &BackgroundPositionVertical) -> String {
1049 match b {
1050 BackgroundPositionVertical::Top => format!("BackgroundPositionVertical::Top"),
1051 BackgroundPositionVertical::Center => format!("BackgroundPositionVertical::Center"),
1052 BackgroundPositionVertical::Bottom => format!("BackgroundPositionVertical::Bottom"),
1053 BackgroundPositionVertical::Exact(p) => format!(
1054 "BackgroundPositionVertical::Exact({})",
1055 format_pixel_value(p)
1056 ),
1057 }
1058}
1059
1060