Skip to main content

ptouch_rs/
printer_stats.rs

1use std::{collections::HashMap, sync::LazyLock};
2
3use enumflags2::{BitFlags, bitflags};
4
5static USB_TO_DEVICE: LazyLock<HashMap<(u16, u16), PrinterType>> = LazyLock::new(|| {
6  let mut map = HashMap::new();
7
8  for (printer, info) in PrinterType::iter_info() {
9    map.insert((info.vendor_id, info.product_id), *printer);
10  }
11
12  map
13});
14
15static INFO: LazyLock<HashMap<PrinterType, PrinterInfo>> = LazyLock::new(|| {
16  let mut map = HashMap::new();
17
18  for printer in PrinterType::iter() {
19    map.insert(printer, printer.info());
20  }
21
22  map
23});
24
25#[bitflags]
26#[repr(u8)]
27#[derive(Debug, Clone, Copy, PartialEq)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub enum PrinterFlags {
30  UnsupportedRaster = (1 << 0),
31  RasterPackBits = (1 << 1),
32  PLite = (1 << 2),
33  P700Init = (1 << 3),
34  UseInfoCmd = (1 << 4),
35  HasPrecut = (1 << 5),
36  D460BTMagic = (1 << 6),
37}
38
39#[derive(Debug, Clone)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub struct PrinterInfo {
42  pub vendor_id: u16,
43  pub product_id: u16,
44  pub max_px: u32,
45  pub dpi: u32,
46  pub flags: BitFlags<PrinterFlags>,
47}
48
49#[allow(non_camel_case_types)]
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52pub enum PrinterType {
53  PT_9200DX,
54  PT_2300,
55  PT_2420PC,
56  PT_2450PC,
57  PT_1950,
58  PT_2700,
59  /// Notes about the PT-1230PC: While it is true that this printer supports max 12mm tapes, it apparently expects > 76px data - the first 32px must be blank.
60  PT_1230PC,
61  PT_2430PC,
62  PT_1230PC_PLite,
63  PT_2430PC_PLite,
64  /// Notes about the PT-2730: was reported to need 48px whitespace within png-images before content is actually printed - can not check this
65  PT_2730,
66  /// Note about the PT-E500: was reported by Jesse Becker with the remark that it also needs some padding (white pixels)
67  PT_H500,
68  /// Note about the PT-E500: was reported by Jesse Becker with the remark that it also needs some padding (white pixels)
69  PT_E500,
70  PT_P700,
71  PT_P750W,
72  PT_P700_PLite,
73  PT_P750W_PLite,
74  PT_D410,
75  /// Notes about the PT-D450: I'm unsure if print width really is 128px
76  PT_D450,
77  PT_D460BT,
78  /// PT-D600 was reported to work, but with some quirks (premature cutting of tape, printing maximum of 73mm length)
79  PT_D600,
80  PT_D610BT,
81  PT_P710BT,
82  /// added by Christian, PT-E310BT (aka PT-E310BTVP) requires these flags, otherwise not returning from libusb_bulk_transfer-call
83  /// printhead 128px, 180 dpi resolution
84  /// 3,5/6/9/12/18 mm TZe Tapes, 12mm and 18mm tested
85  /// 5,2/9/11,2 mm HSe heat shrink tubes not tested, probably requiring extension of struct _pt_tape_info
86  PT_E310BT,
87}
88
89impl PrinterType {
90  pub fn from_usb(vendor: u16, product: u16) -> Option<Self> {
91    USB_TO_DEVICE.get(&(vendor, product)).cloned()
92  }
93
94  pub fn iter() -> impl Iterator<Item = Self> {
95    <Self as strum::IntoEnumIterator>::iter()
96  }
97
98  pub fn iter_info() -> impl Iterator<Item = (&'static Self, &'static PrinterInfo)> {
99    INFO.iter()
100  }
101
102  pub fn info(&self) -> PrinterInfo {
103    match self {
104      PrinterType::PT_9200DX => PrinterInfo {
105        vendor_id: 0x04f9,
106        product_id: 0x2001,
107        max_px: 384,
108        dpi: 360,
109        flags: PrinterFlags::RasterPackBits | PrinterFlags::HasPrecut,
110      },
111      PrinterType::PT_2300 => PrinterInfo {
112        vendor_id: 0x04f9,
113        product_id: 0x2004,
114        max_px: 112,
115        dpi: 180,
116        flags: PrinterFlags::RasterPackBits | PrinterFlags::HasPrecut,
117      },
118      PrinterType::PT_2420PC => PrinterInfo {
119        vendor_id: 0x04f9,
120        product_id: 0x2007,
121        max_px: 128,
122        dpi: 180,
123        flags: PrinterFlags::RasterPackBits.into(),
124      },
125      PrinterType::PT_2450PC => PrinterInfo {
126        vendor_id: 0x04f9,
127        product_id: 0x2011,
128        max_px: 128,
129        dpi: 180,
130        flags: PrinterFlags::RasterPackBits.into(),
131      },
132      PrinterType::PT_1950 => PrinterInfo {
133        vendor_id: 0x04f9,
134        product_id: 0x2019,
135        max_px: 112,
136        dpi: 180,
137        flags: PrinterFlags::RasterPackBits.into(),
138      },
139      PrinterType::PT_2700 => PrinterInfo {
140        vendor_id: 0x04f9,
141        product_id: 0x201f,
142        max_px: 128,
143        dpi: 180,
144        flags: PrinterFlags::HasPrecut.into(),
145      },
146      PrinterType::PT_1230PC => PrinterInfo {
147        vendor_id: 0x04f9,
148        product_id: 0x202c,
149        max_px: 128,
150        dpi: 180,
151        flags: BitFlags::empty(),
152      },
153      PrinterType::PT_2430PC => PrinterInfo {
154        vendor_id: 0x04f9,
155        product_id: 0x202d,
156        max_px: 128,
157        dpi: 180,
158        flags: BitFlags::empty(),
159      },
160      PrinterType::PT_1230PC_PLite => PrinterInfo {
161        vendor_id: 0x04f9,
162        product_id: 0x2030,
163        max_px: 128,
164        dpi: 180,
165        flags: PrinterFlags::PLite.into(),
166      },
167      PrinterType::PT_2430PC_PLite => PrinterInfo {
168        vendor_id: 0x04f9,
169        product_id: 0x2031,
170        max_px: 128,
171        dpi: 180,
172        flags: PrinterFlags::PLite.into(),
173      },
174      PrinterType::PT_2730 => PrinterInfo {
175        vendor_id: 0x04f9,
176        product_id: 0x2041,
177        max_px: 128,
178        dpi: 180,
179        flags: BitFlags::empty(),
180      },
181      PrinterType::PT_H500 => PrinterInfo {
182        vendor_id: 0x04f9,
183        product_id: 0x205e,
184        max_px: 128,
185        dpi: 180,
186        flags: PrinterFlags::RasterPackBits.into(),
187      },
188      PrinterType::PT_E500 => PrinterInfo {
189        vendor_id: 0x04f9,
190        product_id: 0x205f,
191        max_px: 128,
192        dpi: 180,
193        flags: PrinterFlags::RasterPackBits.into(),
194      },
195      PrinterType::PT_P700 => PrinterInfo {
196        vendor_id: 0x04f9,
197        product_id: 0x2061,
198        max_px: 128,
199        dpi: 180,
200        flags: PrinterFlags::RasterPackBits | PrinterFlags::P700Init | PrinterFlags::HasPrecut,
201      },
202      PrinterType::PT_P750W => PrinterInfo {
203        vendor_id: 0x04f9,
204        product_id: 0x2062,
205        max_px: 128,
206        dpi: 180,
207        flags: PrinterFlags::RasterPackBits | PrinterFlags::P700Init,
208      },
209      PrinterType::PT_P700_PLite => PrinterInfo {
210        vendor_id: 0x04f9,
211        product_id: 0x2064,
212        max_px: 128,
213        dpi: 180,
214        flags: PrinterFlags::PLite.into(),
215      },
216      PrinterType::PT_P750W_PLite => PrinterInfo {
217        vendor_id: 0x04f9,
218        product_id: 0x2065,
219        max_px: 128,
220        dpi: 180,
221        flags: PrinterFlags::PLite.into(),
222      },
223      PrinterType::PT_D410 => PrinterInfo {
224        vendor_id: 0x04f9,
225        product_id: 0x20df,
226        max_px: 128,
227        dpi: 180,
228        flags: PrinterFlags::UseInfoCmd | PrinterFlags::HasPrecut | PrinterFlags::D460BTMagic,
229      },
230      PrinterType::PT_D450 => PrinterInfo {
231        vendor_id: 0x04f9,
232        product_id: 0x2073,
233        max_px: 128,
234        dpi: 180,
235        flags: PrinterFlags::UseInfoCmd.into(),
236      },
237      PrinterType::PT_D460BT => PrinterInfo {
238        vendor_id: 0x04f9,
239        product_id: 0x20e0,
240        max_px: 128,
241        dpi: 180,
242        flags: PrinterFlags::P700Init
243          | PrinterFlags::UseInfoCmd
244          | PrinterFlags::HasPrecut
245          | PrinterFlags::D460BTMagic,
246      },
247      PrinterType::PT_D600 => PrinterInfo {
248        vendor_id: 0x04f9,
249        product_id: 0x2074,
250        max_px: 128,
251        dpi: 180,
252        flags: PrinterFlags::RasterPackBits.into(),
253      },
254      PrinterType::PT_D610BT => PrinterInfo {
255        vendor_id: 0x04f9,
256        product_id: 0x20e1,
257        max_px: 128,
258        dpi: 180,
259        flags: PrinterFlags::P700Init
260          | PrinterFlags::UseInfoCmd
261          | PrinterFlags::HasPrecut
262          | PrinterFlags::D460BTMagic,
263      },
264      PrinterType::PT_P710BT => PrinterInfo {
265        vendor_id: 0x04f9,
266        product_id: 0x20af,
267        max_px: 128,
268        dpi: 180,
269        flags: PrinterFlags::RasterPackBits | PrinterFlags::HasPrecut,
270      },
271      PrinterType::PT_E310BT => PrinterInfo {
272        vendor_id: 0x04f9,
273        product_id: 0x2201,
274        max_px: 128,
275        dpi: 180,
276        flags: PrinterFlags::P700Init | PrinterFlags::UseInfoCmd | PrinterFlags::D460BTMagic,
277      },
278    }
279  }
280}