Progress on modularizing escpos.
This commit is contained in:
parent
280d2fcbab
commit
be3fd25fcf
5 changed files with 103 additions and 84 deletions
7
src/escpos/errors.rs
Normal file
7
src/escpos/errors.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#[derive(Debug)]
|
||||
pub enum EscPosError {
|
||||
EmptyQueue,
|
||||
InvalidQueueIndex,
|
||||
InvalidBitmapMode,
|
||||
InvalidBarcodeLength(String),
|
||||
}
|
||||
|
|
@ -1,16 +1,5 @@
|
|||
use crate::dithering::atkinson_mono;
|
||||
use crate::{dithering::atkinson_mono, escpos::errors::EscPosError};
|
||||
use image::{DynamicImage, imageops::FilterType};
|
||||
use std::{collections::HashMap, io::Write, ops::AddAssign};
|
||||
|
||||
const MAX_WIDTH: u32 = 384;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EscPosError {
|
||||
EmptyQueue,
|
||||
InvalidQueueIndex,
|
||||
InvalidBitmapMode,
|
||||
InvalidBarcodeLength(String),
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum QREcc {
|
||||
|
|
@ -39,11 +28,9 @@ pub enum ImageOrientation {
|
|||
}
|
||||
|
||||
pub struct Job {
|
||||
content: Vec<u8>,
|
||||
pub ready: bool,
|
||||
}
|
||||
pub struct Printer {
|
||||
pub queue: Vec<Job>,
|
||||
pub content: Vec<u8>,
|
||||
max_width: u16,
|
||||
}
|
||||
|
||||
fn is_numeric(s: &[u8]) -> bool {
|
||||
|
|
@ -51,10 +38,11 @@ fn is_numeric(s: &[u8]) -> bool {
|
|||
}
|
||||
|
||||
impl Job {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(max_width: u16) -> Self {
|
||||
Job {
|
||||
content: vec![0x1B, b'@'],
|
||||
ready: false,
|
||||
max_width: max_width,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,18 +59,18 @@ impl Job {
|
|||
|
||||
let (w, h) = (img.width(), img.height());
|
||||
let swap = matches!(orientation, Some(ImageOrientation::Largest))
|
||||
&& h.min(MAX_WIDTH) * w > w.min(MAX_WIDTH) * h;
|
||||
&& h.min(self.max_width as u32) * w > w.min(self.max_width as u32) * h;
|
||||
|
||||
let scale = if swap {
|
||||
MAX_WIDTH as f32 / h as f32
|
||||
self.max_width as f32 / h as f32
|
||||
} else {
|
||||
MAX_WIDTH as f32 / w as f32
|
||||
self.max_width as f32 / w as f32
|
||||
};
|
||||
|
||||
let (w, h) = if swap {
|
||||
((h as f32 * scale) as u32, MAX_WIDTH)
|
||||
((h as f32 * scale) as u32, self.max_width as u32)
|
||||
} else {
|
||||
(MAX_WIDTH, (h as f32 * scale) as u32)
|
||||
(self.max_width as u32, (h as f32 * scale) as u32)
|
||||
};
|
||||
|
||||
let img =
|
||||
|
|
@ -95,6 +83,8 @@ impl Job {
|
|||
let buf = &mut self.content;
|
||||
buf.reserve(8 + mono.len());
|
||||
buf.extend_from_slice(&[
|
||||
0x1B,
|
||||
b'@',
|
||||
0x1D,
|
||||
0x76,
|
||||
0x30,
|
||||
|
|
@ -124,6 +114,8 @@ impl Job {
|
|||
let text = text.as_bytes();
|
||||
let len = text.len() + 3;
|
||||
buf.extend_from_slice(&[
|
||||
0x1B,
|
||||
b'@',
|
||||
// Size
|
||||
0x1D,
|
||||
0x28,
|
||||
|
|
@ -186,6 +178,8 @@ impl Job {
|
|||
|
||||
let buf = &mut self.content;
|
||||
buf.extend([
|
||||
0x1B,
|
||||
b'@',
|
||||
0x1D,
|
||||
0x68,
|
||||
height,
|
||||
|
|
@ -205,42 +199,3 @@ impl Job {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Printer {
|
||||
pub fn new() -> Self {
|
||||
Printer { queue: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn new_job(&mut self) -> Result<&mut Job, EscPosError> {
|
||||
self.queue.push(Job::new());
|
||||
self.queue.last_mut().ok_or(EscPosError::InvalidQueueIndex)
|
||||
}
|
||||
pub fn print_job(&mut self, writer: &mut impl Write) -> Result<(), EscPosError> {
|
||||
let page_feed: u8 = 0x0A;
|
||||
let job = self
|
||||
.queue
|
||||
.extract_if(.., |j| j.ready)
|
||||
.next()
|
||||
.ok_or(EscPosError::EmptyQueue)?;
|
||||
|
||||
// writer.write(&[page_feed]).unwrap(); // FIXME: remove unwraps
|
||||
writer.write(&job.content).unwrap();
|
||||
// writer.write(&[page_feed]).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn export_job(&mut self) -> Result<Vec<u8>, EscPosError> {
|
||||
let page_feed: u8 = 0x0A;
|
||||
let job = self
|
||||
.queue
|
||||
.extract_if(.., |j| j.ready)
|
||||
.next()
|
||||
.ok_or(EscPosError::EmptyQueue)?;
|
||||
|
||||
let mut out = Vec::with_capacity(2 + job.content.len());
|
||||
out.push(page_feed);
|
||||
out.extend(job.content);
|
||||
out.push(page_feed);
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
3
src/escpos/mod.rs
Normal file
3
src/escpos/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
pub mod errors;
|
||||
pub mod job;
|
||||
pub mod printer;
|
||||
49
src/escpos/printer.rs
Normal file
49
src/escpos/printer.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use crate::escpos::{errors::EscPosError, job::Job};
|
||||
use std::io::Write;
|
||||
|
||||
pub struct Printer {
|
||||
pub queue: Vec<Job>,
|
||||
pub max_width: u16,
|
||||
}
|
||||
impl Printer {
|
||||
pub fn new(max_width: u16) -> Self {
|
||||
Printer {
|
||||
queue: Vec::new(),
|
||||
max_width: max_width,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_job(&mut self) -> Result<&mut Job, EscPosError> {
|
||||
self.queue.push(Job::new(self.max_width));
|
||||
self.queue.last_mut().ok_or(EscPosError::InvalidQueueIndex)
|
||||
}
|
||||
pub fn print_job(&mut self, writer: &mut impl Write) -> Result<(), EscPosError> {
|
||||
// let page_feed: u8 = 0x0A;
|
||||
let job = self
|
||||
.queue
|
||||
.extract_if(.., |j| j.ready)
|
||||
.next()
|
||||
.ok_or(EscPosError::EmptyQueue)?;
|
||||
|
||||
// writer.write(&[page_feed]).unwrap(); // FIXME: remove unwraps
|
||||
writer.write(&job.content).unwrap();
|
||||
// writer.write(&[page_feed]).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn export_job(&mut self) -> Result<Vec<u8>, EscPosError> {
|
||||
let page_feed: u8 = 0x0A;
|
||||
let job = self
|
||||
.queue
|
||||
.extract_if(.., |j| j.ready)
|
||||
.next()
|
||||
.ok_or(EscPosError::EmptyQueue)?;
|
||||
|
||||
let mut out = Vec::with_capacity(2 + job.content.len());
|
||||
out.push(page_feed);
|
||||
out.extend(job.content);
|
||||
out.push(page_feed);
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
51
src/main.rs
51
src/main.rs
|
|
@ -4,33 +4,38 @@ mod escpos;
|
|||
use image::{ImageError, ImageReader};
|
||||
use std::{env, process};
|
||||
|
||||
use crate::escpos::Printer;
|
||||
use crate::escpos::{
|
||||
job::{BARTextPosition, BARType},
|
||||
printer::Printer,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
// let args: Vec<String> = env::args().collect();
|
||||
//
|
||||
// let len = args.len();
|
||||
// if len < 2 || len > 2 {
|
||||
// println!("Please provide a path to the image.");
|
||||
// process::exit(1);
|
||||
// }
|
||||
//
|
||||
// let img = ImageReader::open(&args[1])
|
||||
// .map_err(|err| ImageError::IoError(err))
|
||||
// .and_then(|v| v.decode())
|
||||
// .unwrap();
|
||||
|
||||
let len = args.len();
|
||||
if len < 2 || len > 2 {
|
||||
println!("Please provide a path to the image.");
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let img = ImageReader::open(&args[1])
|
||||
.map_err(|err| ImageError::IoError(err))
|
||||
.and_then(|v| v.decode())
|
||||
.unwrap();
|
||||
|
||||
let mut printer = Printer::new();
|
||||
let mut printer = Printer::new(384);
|
||||
let job = printer.new_job().unwrap();
|
||||
// job.write_qr("hi".to_string(), None, None).unwrap();
|
||||
job.write_barcode(
|
||||
"hhhhhhhhhhh".to_string(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(escpos::BARType::UPCA),
|
||||
)
|
||||
.unwrap();
|
||||
job.write_qr("https://pornhub.com".to_string(), None, None)
|
||||
// .unwrap();
|
||||
// job.write_barcode(
|
||||
// "kleintje".to_string(),
|
||||
// Some(10),
|
||||
// None,
|
||||
// Some(BARTextPosition::Both),
|
||||
// Some(BARType::CODE128),
|
||||
// )
|
||||
.unwrap();
|
||||
job.content.extend_from_slice(&[b'\n', b'\n']);
|
||||
// job.write_bitmap(&img, None, None).unwrap();
|
||||
job.ready = true;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue