Skip to main content

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