1#![allow(clippy::type_complexity, clippy::unwrap_or_default)]
25
26mod kvasir;
27mod material;
28
29pub use material::{MaterialGraph, MaterialCompiler, CompiledMaterial, MaterialOp, MaterialError};
31pub use material::builtins;
32
33pub mod types;
34pub mod vertex;
35pub mod renderer;
36mod surtr_util;
37mod draw;
38mod api;
39
40pub mod heim;
41pub use heim::SundrPacker;
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 use super::heim::SundrPacker;
48
49 #[test]
50 fn test_shelf_packer_basic() {
51 let mut packer = SundrPacker::new(100, 100);
52 assert_eq!(packer.pack(10, 10), Some((0, 0)));
53 assert_eq!(packer.pack(20, 15), Some((10, 0)));
54 }
55
56 #[test]
57 fn test_shelf_packer_wrap() {
58 let mut packer = SundrPacker::new(100, 100);
59 packer.pack(60, 10);
60 assert_eq!(packer.pack(50, 20), Some((0, 10)));
61 }
62
63 #[test]
64 fn test_parse_svg_animations() {
65 let svg = r##"
66 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
67 <g id="spinner">
68 <animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="2s" />
69 </g>
70 <circle id="pulse">
71 <animate attributeName="opacity" from="0.5" to="1.0" dur="0.5s" />
72 </circle>
73 <!-- Edge cases: xlink:href, ms suffix, values list -->
74 <rect>
75 <animate xlink:href="#myRect" attributeName="x" values="10; 20; 30" dur="500ms" />
76 </rect>
77 </svg>
78 "##;
79 let anims = draw::parse_svg_animations(svg.as_bytes());
80 assert_eq!(anims.len(), 3);
81
82 assert_eq!(anims[0].target_id, "spinner");
83 assert_eq!(anims[0].attribute_name, "transform");
84 assert_eq!(anims[0].duration, 2.0);
85 assert_eq!(anims[0].from_val, 0.0);
86 assert_eq!(anims[0].to_val, 360.0);
87
88 assert_eq!(anims[1].target_id, "pulse");
89 assert_eq!(anims[1].attribute_name, "opacity");
90 assert_eq!(anims[1].duration, 0.5);
91 assert_eq!(anims[1].from_val, 0.5);
92 assert_eq!(anims[1].to_val, 1.0);
93
94 assert_eq!(anims[2].target_id, "myRect");
95 assert_eq!(anims[2].attribute_name, "x");
96 assert_eq!(anims[2].duration, 0.5); assert_eq!(anims[2].from_val, 10.0);
98 assert_eq!(anims[2].to_val, 30.0);
99 }
100
101 #[test]
102 fn test_shelf_packer_full() {
103 let mut packer = SundrPacker::new(10, 10);
104 assert_eq!(packer.pack(11, 5), None);
105 assert_eq!(packer.pack(5, 11), None);
106 }
107}
108
109pub(crate) const WGSL_SRC: &str = concat!(
110 include_str!("shaders/common.wgsl"),
111 include_str!("shaders/shapes.wgsl"),
112 include_str!("shaders/bifrost.wgsl"),
113 include_str!("shaders/bloom.wgsl"),
114 include_str!("shaders/color_blind.wgsl"),
115 include_str!(concat!(env!("OUT_DIR"), "/materials_generated.wgsl"))
116);
117
118pub(crate) const WGSL_OPAQUE: &str = concat!(
120 include_str!("shaders/common.wgsl"),
121 include_str!("shaders/material_opaque.wgsl"),
122 include_str!("shaders/bifrost.wgsl"),
123 include_str!("shaders/bloom.wgsl"),
124 include_str!("shaders/color_blind.wgsl"),
125 include_str!(concat!(env!("OUT_DIR"), "/materials_generated.wgsl"))
126);
127
128pub(crate) const WGSL_GLASS: &str = concat!(
130 include_str!("shaders/common.wgsl"),
131 include_str!("shaders/material_glass.wgsl"),
132 include_str!("shaders/bifrost.wgsl"),
133 include_str!("shaders/bloom.wgsl"),
134 include_str!("shaders/color_blind.wgsl"),
135 include_str!(concat!(env!("OUT_DIR"), "/materials_generated.wgsl"))
136);
137
138
139pub mod color_blindness;
140
141pub use color_blindness::ColorBlindMode;
143
144pub use accesskit::{
147 ActionHandler, ActionRequest, ActivationHandler, DeactivationHandler, Node, NodeId, Role, Tree,
148 TreeId, TreeUpdate,
149};
150pub use accesskit_winit::Adapter as ShieldWallAdapter;
151
152pub use cvkg_core::{ColorTheme, SceneUniforms};
154
155pub use renderer::SurtrRenderer;
156pub use types::{SvgModel, SvgAnimation};
157pub use vertex::{Vertex, InstanceData};