| 1 | //! One scene painted by `draw` over wgpu on the dev Mac (`reference`) and over OpenGL on |
| 2 | //! 10.6 (`render-probe`), whose PNGs `reference --compare` diffs. Device pixels, linear |
| 3 | //! colours. |
| 4 | #![allow(dead_code)] // Each binary paints part of it. |
| 5 | use draw::{Layer, Primitive, RasterImage, Stroke}; |
| 6 | |
| 7 | pub const SIZE: [u32; 2] = [400, 300]; |
| 8 | pub const CLEAR: [f32; 4] = [0.85, 0.85, 0.85, 1.0]; |
| 9 | |
| 10 | /// A 4×4 opaque sRGB checker, stretched and filtered by the image path. |
| 11 | pub fn checker() -> RasterImage { |
| 12 | let pixels = (0..16) |
| 13 | .flat_map(|i| if (i % 4 + i / 4) % 2 == 0 { [240, 200, 40, 255] } else { [30, 120, 90, 255] }) |
| 14 | .collect(); |
| 15 | RasterImage::new([4, 4], pixels).unwrap() |
| 16 | } |
| 17 | |
| 18 | pub fn primitives(checker: &RasterImage) -> Vec<Primitive<'_>> { |
| 19 | let red = [0.6, 0.05, 0.05, 1.0]; |
| 20 | let blue = [0.05, 0.1, 0.6, 1.0]; |
| 21 | let green = [0.05, 0.4, 0.1, 1.0]; |
| 22 | let ink = [0.02, 0.02, 0.02, 1.0]; |
| 23 | use Primitive::*; |
| 24 | vec![ |
| 25 | Rect { rect: [20.0, 20.0, 120.0, 80.0], color: red }, |
| 26 | Gradient { rect: [140.0, 20.0, 260.0, 80.0], radius: [12.0, 12.0], colors: [blue; 2] }, |
| 27 | Gradient { rect: [280.0, 20.5, 380.0, 80.25], radius: [30.0, 12.0], colors: [green; 2] }, |
| 28 | RoundedRect { rect: [20.0, 100.0, 120.0, 160.0], radius: [10.0, 10.0], stroke: Some(Stroke::Solid(3.0)), color: ink }, |
| 29 | RoundedRect { rect: [140.0, 100.0, 260.0, 160.0], radius: [16.0, 16.0], stroke: Some(Stroke::Dashed(2.0)), color: ink }, |
| 30 | Gradient { rect: [280.0, 100.0, 380.0, 160.0], radius: [8.0, 8.0], colors: [[0.9, 0.5, 0.1, 1.0], [0.2, 0.05, 0.4, 1.0]] }, |
| 31 | Image { image: checker, rect: [20.0, 180.0, 120.0, 280.0] }, |
| 32 | Rect { rect: [60.0, 200.0, 200.0, 260.0], color: [0.1, 0.3, 0.8, 0.5] }, |
| 33 | RoundedRect { rect: [220.0, 180.0, 380.0, 280.0], radius: [30.0, 10.0], stroke: Some(Stroke::Dashed(3.0)), color: red }, |
| 34 | ] |
| 35 | } |
| 36 | |
| 37 | pub fn layer<'a>(primitives: &'a [Primitive<'a>]) -> Layer<'a> { |
| 38 | Layer { scale: 1.0, origin: [0.0; 2], clip: None, backdrop: None, round: None, motion: None, primitives } |
| 39 | } |
| 40 | |
| 41 | /// Lines of interface text through `ui`: black on white like a Cocoa label, the same in |
| 42 | /// Arial, then the light theme's text on its strip. Logical pixels. |
| 43 | pub const TEXT_SIZE: [u32; 2] = [640, 150]; |
| 44 | pub const TEXT: [&str; 2] = [ |
| 45 | "Garden Kitchen Journal Reading Trips Home", |
| 46 | "Search All Notebooks Up to date 100% Calibri", |
| 47 | ]; |
| 48 | |
| 49 | pub fn interface(scale: f32) -> ui::Ui { |
| 50 | let theme = ui::Theme::light(); |
| 51 | let strip = theme.strip; |
| 52 | let mut ui = ui::Ui::new(theme, std::time::Duration::from_millis(500)); |
| 53 | ui.begin(TEXT_SIZE.map(|side| side as f32), scale, std::time::Instant::now()); |
| 54 | ui.open("page", ui::Spec { size: [ui::fill(), ui::fill()], axis: ui::Axis::Y, fill: Some([1.0; 4]), pad: [10.0, 6.0], gap: 6.0, ..Default::default() }); |
| 55 | let black = Some([0.0, 0.0, 0.0, 1.0]); |
| 56 | for (index, text) in TEXT.into_iter().enumerate() { |
| 57 | ui.leaf(index, ui::Spec { size: [ui::fit(), ui::px(24.0)], text: Some(text), color: black, ..Default::default() }); |
| 58 | } |
| 59 | ui.leaf("arial", ui::Spec { size: [ui::fit(), ui::px(24.0)], text: Some(TEXT[0]), font: Some("Arial"), color: black, ..Default::default() }); |
| 60 | ui.leaf("strip", ui::Spec { size: [ui::fill(), ui::px(24.0)], text: Some(TEXT[1]), fill: Some(strip), ..Default::default() }); |
| 61 | ui.close(); |
| 62 | ui.end(); |
| 63 | ui |
| 64 | } |
| 65 | |
| 66 | pub fn interface_layers<'a>(layers: &'a [ui::Layer<'a>], scale: f32) -> Vec<Layer<'a>> { |
| 67 | layers |
| 68 | .iter() |
| 69 | .map(|layer| match layer { |
| 70 | ui::Layer::Primitives(primitives) => primitives.layer(scale), |
| 71 | ui::Layer::Custom { .. } => unreachable!(), |
| 72 | }) |
| 73 | .collect() |
| 74 | } |