Skip to main content

uzor_render/
ops.rs

1use crate::context::RenderContext;
2use crate::types::TextAlign;
3
4/// Render instructions that can be serialized
5#[derive(Clone, Debug)]
6pub enum RenderOp {
7    // Style
8    SetStrokeColor(String),
9    SetFillColor(String),
10    SetLineWidth(f64),
11    SetLineDash(Vec<f64>),
12
13    // Path
14    BeginPath,
15    MoveTo(f64, f64),
16    LineTo(f64, f64),
17    QuadraticCurveTo(f64, f64, f64, f64),
18    BezierCurveTo(f64, f64, f64, f64, f64, f64),
19    Arc(f64, f64, f64, f64, f64),
20    Ellipse(f64, f64, f64, f64, f64, f64, f64),
21    ClosePath,
22
23    // Draw
24    Stroke,
25    Fill,
26    StrokeRect(f64, f64, f64, f64),
27    FillRect(f64, f64, f64, f64),
28
29    // Text
30    SetFont(String),
31    SetTextAlign(TextAlign),
32    FillText(String, f64, f64),
33    StrokeText(String, f64, f64),
34
35    // State
36    Save,
37    Restore,
38    Translate(f64, f64),
39    Rotate(f64),
40    Scale(f64, f64),
41    Clip,
42}
43
44/// Collection of render operations
45pub type RenderOps = Vec<RenderOp>;
46
47/// Execute render operations on a context
48pub fn execute_ops(ctx: &mut dyn RenderContext, ops: &[RenderOp]) {
49    for op in ops {
50        match op {
51            RenderOp::SetStrokeColor(c) => ctx.set_stroke_color(c),
52            RenderOp::SetFillColor(c) => ctx.set_fill_color(c),
53            RenderOp::SetLineWidth(w) => ctx.set_stroke_width(*w),
54            RenderOp::SetLineDash(p) => ctx.set_line_dash(p),
55            RenderOp::BeginPath => ctx.begin_path(),
56            RenderOp::MoveTo(x, y) => ctx.move_to(*x, *y),
57            RenderOp::LineTo(x, y) => ctx.line_to(*x, *y),
58            RenderOp::QuadraticCurveTo(cpx, cpy, x, y) => {
59                ctx.quadratic_curve_to(*cpx, *cpy, *x, *y)
60            }
61            RenderOp::BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) => {
62                ctx.bezier_curve_to(*cp1x, *cp1y, *cp2x, *cp2y, *x, *y)
63            }
64            RenderOp::Arc(cx, cy, r, start, end) => ctx.arc(*cx, *cy, *r, *start, *end),
65            RenderOp::Ellipse(cx, cy, rx, ry, rot, start, end) => {
66                ctx.ellipse(*cx, *cy, *rx, *ry, *rot, *start, *end)
67            }
68            RenderOp::ClosePath => ctx.close_path(),
69            RenderOp::Stroke => ctx.stroke(),
70            RenderOp::Fill => ctx.fill(),
71            RenderOp::StrokeRect(x, y, w, h) => ctx.stroke_rect(*x, *y, *w, *h),
72            RenderOp::FillRect(x, y, w, h) => ctx.fill_rect(*x, *y, *w, *h),
73            RenderOp::SetFont(f) => ctx.set_font(f),
74            RenderOp::SetTextAlign(a) => ctx.set_text_align(*a),
75            RenderOp::FillText(t, x, y) => ctx.fill_text(t, *x, *y),
76            RenderOp::StrokeText(t, x, y) => ctx.stroke_text(t, *x, *y),
77            RenderOp::Save => ctx.save(),
78            RenderOp::Restore => ctx.restore(),
79            RenderOp::Translate(x, y) => ctx.translate(*x, *y),
80            RenderOp::Rotate(a) => ctx.rotate(*a),
81            RenderOp::Scale(x, y) => ctx.scale(*x, *y),
82            RenderOp::Clip => ctx.clip(),
83        }
84    }
85}