1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
use super::constants;
use super::network;
use super::qr;
use std::fs::File;
use std::io::Write;
pub struct Printer {
message: Vec<u8>,
}
impl Printer {
///Call this function to create a new printer object.
///It will start with the initial values ESC and @ which initializes the printer.
///This is done in order to reset the printer to initial state
pub fn new() -> Printer {
let mut p = Printer {
message: Vec::new(),
};
p.message.push(constants::ESC);
p.message.push(constants::AT);
p
}
///Add a list of u8 characters to be printed.
///This is intended to mainly be used to print plaintext.
///It could however be used for commands as well.
pub fn add(&mut self, text: Vec<u8>) {
for i in text {
self.message.push(i);
}
}
///Prints the given qr code.
///The qr code is to be constructed with the qr submodule..
pub fn add_qr(&mut self, qr: qr::Qr) {
self.add(qr.export());
}
///Add a list of str to be printed.
///keep in mind that the printer only works on ASCII characters.
///So it's the responsibility of the callee to make sure that the string is ASCII.
///If not then it will most likely be malformed.
pub fn add_str(&mut self, text: &str) {
for i in text.bytes() {
self.message.push(i);
}
}
///This function will turn on or off double strike mode
///This is done by giving either the value constants::ON or constants::OFF
pub fn set_double_strike(&mut self, value: u8) {
self.message.push(constants::ESC);
self.message.push(b'G');
if value == constants::ON {
self.message.push(constants::ON);
} else {
self.message.push(constants::OFF);
}
}
///Call this to either turn on or off emphisized text.
///This is done by giving either the value constants::ON or constants::OFF
pub fn set_emph(&mut self, value: u8) {
self.message.push(constants::ESC);
self.message.push(b'E');
if value == constants::ON {
self.message.push(constants::ON);
} else {
self.message.push(constants::OFF);
}
}
///Call this to turn smoothing on or off
///This is done by giving either the value constants::ON or constants::OFF
pub fn set_smoothing(&mut self, value: u8) {
self.message.push(constants::GS);
self.message.push(0x62);
if value == constants::ON {
self.message.push(constants::ON);
} else {
self.message.push(constants::OFF);
}
}
fn _barcode_mode_a(&mut self, text:&str, barcode_type: u8) {
self.message.push(constants::GS);
self.message.push(0x6b);
self.message.push(barcode_type);
for i in text.bytes() {
self.message.push(i);
}
self.message.push(0x00);
}
fn _barcode_mode_b(&mut self, text:&str, barcode_type: u8) {
self.message.push(constants::GS);
self.message.push(0x6b);
self.message.push(barcode_type + 65);
self.message.push(text.len() as u8);
for i in text.bytes() {
self.message.push(i);
}
}
///This function will set the height of the barcode.
///The actual height depends on the printer, try and find what works for you.
///Can be given values between 0-255
pub fn set_barcode_height(&mut self, height: u8) {
self.message.push(constants::GS);
self.message.push(0x68);
self.message.push(height);
}
///This function will set the width of the barcode
///The actual width depends on the printer, try and find what works for you.
///Can be given values between 2-6
///Not sure why this is the case, but it is.
///Will set to either highest or lowest if out of range.
pub fn set_barcode_width(&mut self, mut width: u8) {
if width >6 {
width = 6;
}
else if width < 2 {
width = 2;
}
self.message.push(constants::GS);
self.message.push(0x77);
self.message.push(width);
}
///Prints a given barcode
///The barcode to print is given as a str
///There can be different types of barcodes. Check which you want to print https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=128
///There are two kinds of ways to print barcode, either constant::MODE_A or constant::MODE_B
///You have to know which mode is right for you.
pub fn add_barcode(&mut self, text: &str, barcode_type: u8, mode: u8) {
if mode == constants::MODE_A {
self._barcode_mode_a(text, barcode_type);
}
else {
self._barcode_mode_b( text, barcode_type);
}
}
///Call this to reverse feed paper.
///This is done by giving the number of lines to reverse feed.
///The maximum number of lines is 255.
///WARNING: I don't think this works on most printers
pub fn reverse_feed(&mut self, lines: u8) {
self.message.push(constants::ESC);
self.message.push(0x4b);
self.message.push(lines);
}
///Call this to either turn on or off upside down text
///This is done by giving either the value constants::ON or constants::OFF
pub fn set_upside_down(&mut self, value: u8) {
self.message.push(constants::ESC);
self.message.push(b'{');
if value == constants::ON {
self.message.push(constants::ON);
} else {
self.message.push(constants::OFF);
}
}
///Call this to either set underline text on or off
///This is done by giving either the value constants::SINGLE, constant::DOUBLE or constants::OFF
pub fn set_underline(&mut self, value: u8) {
self.message.push(constants::ESC);
self.message.push(0x2D);
self.message.push(value);
}
///Call this to change the spacing between lines
///This is done by giving a value between 0 and 255
pub fn set_line_spacing(&mut self, value: u8) {
self.message.push(constants::ESC);
self.message.push(0x33);
self.message.push(value);
}
///Call this to set back to the default line spacing
pub fn set_default_line_spacing(&mut self) {
self.message.push(constants::ESC);
self.message.push(0x32);
}
pub fn cut(&mut self) {
self.message.push(constants::LF);
self.message.push(constants::GS);
self.message.push(0x56);
self.message.push(0x41);
self.message.push(0x08);
self.message.push(constants::LF);
}
///Prints the message straight to stdout
pub fn print_stdout(&self) {
for i in &self.message {
print!("{}", *i as char);
}
}
///Prints the message to a file
///The path is given as a str
pub fn print_file(&self, path: &str) {
let mut file = File::create(path).unwrap();
for i in &self.message {
file.write(&[*i]).unwrap();
}
}
///Sends a printjob to the correct address and port.
///This requires that other functions adding actions have been called before this.
pub fn print(&self, address: String, port: u32) -> Result<(), String> {
if self.message.len() == 2 {
return Err("No message to print".to_string());
}
network::send_message(&self.message, address, port)
}
}