zpl_forge/engine/
common.rs

1/// Represents a self-contained ZPL instruction ready for rendering.
2///
3/// Unlike AST commands, instructions are calculated based on the cumulative
4/// state of the parser (e.g., coordinates are absolute, fonts are resolved).
5#[derive(Debug)]
6pub enum ZplInstruction {
7    /// Renders a text field.
8    Text {
9        /// Absolute X coordinate.
10        x: u32,
11        /// Absolute Y coordinate.
12        y: u32,
13        /// Font identifier.
14        font: char,
15        /// Height in dots.
16        height: Option<u32>,
17        /// Width in dots.
18        width: Option<u32>,
19        /// Text content.
20        text: String,
21        /// Whether to print white-on-black.
22        reverse_print: bool,
23        /// Custom text color.
24        color: Option<String>,
25    },
26    /// Draws a rectangular box.
27    GraphicBox {
28        x: u32,
29        y: u32,
30        width: u32,
31        height: u32,
32        thickness: u32,
33        color: char,
34        custom_color: Option<String>,
35        rounding: u32,
36        reverse_print: bool,
37    },
38    /// Draws a circle.
39    GraphicCircle {
40        x: u32,
41        y: u32,
42        radius: u32,
43        thickness: u32,
44        color: char,
45        custom_color: Option<String>,
46        reverse_print: bool,
47    },
48    /// Draws an ellipse.
49    GraphicEllipse {
50        x: u32,
51        y: u32,
52        width: u32,
53        height: u32,
54        thickness: u32,
55        color: char,
56        custom_color: Option<String>,
57        reverse_print: bool,
58    },
59    /// Renders a bitmap graphic.
60    GraphicField {
61        x: u32,
62        y: u32,
63        width: u32,
64        height: u32,
65        data: Vec<u8>,
66        reverse_print: bool,
67    },
68    /// Renders a custom color image (extension).
69    CustomImage {
70        /// Absolute X coordinate.
71        x: u32,
72        /// Absolute Y coordinate.
73        y: u32,
74        /// Requested width (0 for natural/proportional).
75        width: u32,
76        /// Requested height (0 for natural/proportional).
77        height: u32,
78        /// Base64 encoded image data.
79        data: String,
80    },
81    /// Draws a Code 128 barcode.
82    Code128 {
83        x: u32,
84        y: u32,
85        orientation: char,
86        height: u32,
87        module_width: u32,
88        interpretation_line: char,
89        interpretation_line_above: char,
90        check_digit: char,
91        mode: char,
92        data: String,
93        reverse_print: bool,
94    },
95    /// Draws a QR Code.
96    QRCode {
97        x: u32,
98        y: u32,
99        orientation: char,
100        model: u32,
101        magnification: u32,
102        error_correction: char,
103        mask: u32,
104        data: String,
105        reverse_print: bool,
106    },
107    /// Draws a Code 39 barcode.
108    Code39 {
109        x: u32,
110        y: u32,
111        orientation: char,
112        check_digit: char,
113        height: u32,
114        module_width: u32,
115        interpretation_line: char,
116        interpretation_line_above: char,
117        data: String,
118        reverse_print: bool,
119    },
120}
121
122/// Represents common printer resolutions.
123#[derive(Debug, Clone, Copy, PartialEq)]
124pub enum Resolution {
125    /// 152 DPI (6 dots/mm)
126    Dpi152,
127    /// 203 DPI (8 dots/mm) - Zebra Standard
128    Dpi203,
129    /// 300 DPI (12 dots/mm)
130    Dpi300,
131    /// 600 DPI (24 dots/mm)
132    Dpi600,
133    /// Custom DPI value
134    Custom(f32),
135}
136
137impl Resolution {
138    /// Returns the dots per millimeter for this resolution.
139    pub fn dpmm(&self) -> f32 {
140        match self {
141            Resolution::Dpi152 => 6.0,
142            Resolution::Dpi203 => 8.0,
143            Resolution::Dpi300 => 12.0,
144            Resolution::Dpi600 => 24.0,
145            Resolution::Custom(val) => val / 25.4,
146        }
147    }
148
149    /// Returns the dots per inch for this resolution.
150    pub fn dpi(&self) -> f32 {
151        match self {
152            Resolution::Dpi152 => 152.0,
153            Resolution::Dpi203 => 203.2,
154            Resolution::Dpi300 => 304.8,
155            Resolution::Dpi600 => 609.6,
156            Resolution::Custom(val) => *val,
157        }
158    }
159}
160
161/// Physical units of measurement supported by the engine.
162#[derive(Debug, Clone, Copy, PartialEq)]
163pub enum Unit {
164    /// Raw dots.
165    Dots(u32),
166    /// Inches.
167    Inches(f32),
168    /// Millimeters.
169    Millimeters(f32),
170    /// Centimeters.
171    Centimeters(f32),
172}
173
174impl Unit {
175    /// Converts the unit to dots based on the provided resolution.
176    pub fn to_dots(&self, resolution: Resolution) -> u32 {
177        match self {
178            Unit::Dots(dots) => *dots,
179            Unit::Inches(inches) => (inches.max(0.0) * resolution.dpi()).round() as u32,
180            Unit::Millimeters(mm) => (mm.max(0.0) * resolution.dpmm()).round() as u32,
181            Unit::Centimeters(cm) => (cm.max(0.0) * 10.0 * resolution.dpmm()).round() as u32,
182        }
183    }
184}