use crate::font::Font;
use format_bytes::write_bytes as wb;
use std::collections::BTreeSet;
#[derive(Default)]
pub struct Page {
pub width: i16,
pub height: i16,
pub os: Vec<u8>,
pub ts: Vec<u8>,
pub text: Vec<u8>,
pub x: i16,
pub y: i16,
font_obj: usize,
font_size: i16,
pub sup: i16,
last_font_obj: usize,
last_font_size: i16,
pub fonts: BTreeSet<usize>,
pub xobjs: BTreeSet<usize>,
}
impl Page {
pub fn goto(&mut self, x: i16, y: i16) {
self.td(x - self.x, y - self.y);
}
pub fn td(&mut self, x: i16, y: i16) {
self.flush_text();
let _ = wb!(&mut self.ts, b"\n{} {} Td ", x, y);
self.x += x;
self.y += y;
}
pub fn text(&mut self, font: &dyn Font, size: i16, s: &str) {
if size != self.font_size || font.obj() != self.font_obj {
self.flush_text();
self.font_obj = font.obj();
self.font_size = size;
}
font.encode(s, &mut self.text);
}
fn flush_text(&mut self) {
if self.text.is_empty() {
return;
}
if self.font_obj != self.last_font_obj || self.font_size != self.last_font_size {
self.fonts.insert(self.font_obj);
let obj = self.font_obj;
let size = self.font_size;
let _ = wb!(&mut self.ts, b"/F{} {} Tf", obj, size);
self.last_font_obj = obj;
self.last_font_size = size;
}
let mut hex = false;
for b in &self.text {
if *b < 32 || *b >= 128 {
hex = true;
break;
}
}
if hex {
self.ts.push(b'<');
for b in &self.text {
let x = *b >> 4;
self.ts.push(x + if x < 10 { 48 } else { 55 });
let x = *b & 15;
self.ts.push(x + if x < 10 { 48 } else { 55 });
}
self.ts.extend_from_slice(b"> Tj");
} else {
self.ts.push(b'(');
for b in &self.text {
let b = *b;
if b == b'(' || b == b')' || b == b'\\' {
self.ts.push(b'\\');
}
self.ts.push(b);
}
self.ts.extend_from_slice(b") Tj");
}
self.text.clear();
}
pub fn finish(&mut self) {
self.flush_text();
self.os.extend_from_slice(b"\nBT");
self.os.extend_from_slice(&self.ts);
self.ts.clear();
self.os.extend_from_slice(b"\nET");
}
pub fn line(&mut self, x0: f64, y0: f64, x1: f64, y1: f64) {
let _ = wb!(&mut self.os, b"\n{} {} m {} {} l S", x0, y0, x1, y1);
}
pub fn rect(&mut self, x0: f64, y0: f64, x1: f64, y1: f64) {
let _ = wb!(&mut self.os, b"\n{} {} m {} {} re S", x0, y0, x1, y1);
}
pub fn set_sup(&mut self, sup: i16) {
if self.sup != sup {
self.flush_text();
self.sup = sup;
let _ = wb!(&mut self.ts, b" {} Ts", sup);
}
}
}