Skip to main content

sequoia_draw/
lib.rs

1#![forbid(unsafe_code)]
2
3use sequoia_core::{Color, Quad, Rect};
4
5mod cache;
6mod flatten;
7mod gradient;
8mod path;
9mod raster;
10mod stroke;
11mod svg_path;
12mod transform;
13mod waveform;
14
15pub use cache::{DEFAULT_CAPACITY, Shape, ShapeCache, ShapeStats};
16pub use flatten::{Contour, flatten};
17pub use gradient::{Gradient, GradientStop};
18pub use path::{FillRule, Path, PathError, PathSeg, Radius};
19pub use raster::{FillStyle, RasterOptions, fill, fill_contours, fill_styled};
20pub use stroke::{Dash, LineCap, LineJoin, StrokeStyle, stroke, stroke_path};
21pub use transform::Transform;
22pub use waveform::{
23    MinMax, Peaks, WaveformCache, WaveformOpts, bake_strip, layout_bars, waveform_line_points,
24    white_noise,
25};
26
27pub const TOLERANCE: f32 = 0.25;
28
29pub const DEFAULT_OPTIONS: RasterOptions = RasterOptions {
30    tolerance: TOLERANCE,
31    row_height: 1.0,
32    merge_tol: 0.35,
33    aa_samples: 4,
34    analytic: true,
35    parallel: true,
36};
37
38#[derive(Clone, Copy, Debug, PartialEq)]
39pub struct Span {
40    pub rect: Rect,
41
42    pub radius: f32,
43
44    pub alpha: f32,
45}
46
47impl Span {
48    pub fn rect(rect: Rect) -> Self {
49        Self {
50            rect,
51            radius: 0.0,
52            alpha: 1.0,
53        }
54    }
55
56    pub fn rounded(rect: Rect, radius: f32) -> Self {
57        Self {
58            rect,
59            radius,
60            alpha: 1.0,
61        }
62    }
63
64    pub fn solid(rect: Rect) -> Self {
65        Self::rect(rect)
66    }
67
68    pub fn edge(rect: Rect, coverage: f32) -> Self {
69        Self::rect(rect).with_alpha(coverage)
70    }
71
72    #[must_use]
73    pub fn with_alpha(mut self, alpha: f32) -> Self {
74        self.alpha = alpha.clamp(0.0, 1.0);
75        self
76    }
77
78    pub fn quad(self, color: Color) -> Quad {
79        Quad {
80            rect: self.rect,
81            color: Color {
82                a: color.a * self.alpha,
83                ..color
84            },
85            radius: self.radius,
86            border_color: Color::TRANSPARENT,
87            border_width: 0.0,
88        }
89    }
90
91    pub fn is_visible(&self) -> bool {
92        !self.rect.is_empty() && self.alpha > 0.0
93    }
94}
95
96pub(crate) fn union_rect(a: Rect, b: Rect) -> Rect {
97    if a.is_empty() {
98        return b;
99    }
100    if b.is_empty() {
101        return a;
102    }
103    let x0 = a.left().min(b.left());
104    let y0 = a.top().min(b.top());
105    let x1 = a.right().max(b.right());
106    let y1 = a.bottom().max(b.bottom());
107    Rect::from_xywh(x0, y0, x1 - x0, y1 - y0)
108}