use std::{path::Path, str::Lines};
use printpdf::{FontId, Mm, Op, Point, Pt, TextItem, TextMatrix, TextRenderingMode};
use crate::{dimensions::Dimensions, text_manipulation::TextWrapper};
#[derive(Clone)]
pub struct ProcessedText {
text: String,
width: f32,
}
impl ProcessedText {
pub fn new(text: String, wrapper: &mut TextWrapper) -> Option<Self> {
let width = text
.lines()
.map(|line| wrapper.get_width(line).0)
.reduce(f32::max)?;
Some(Self { text, width })
}
fn lines<'a>(&'a self) -> Lines<'a> {
self.text.lines()
}
}
pub fn init_page(
contents: &mut Vec<Op>,
page_dimensions: &Dimensions,
font_id: FontId,
font_size: f32,
path: &Path,
additional_text: Option<&ProcessedText>,
include_path: bool,
wrapper: &mut TextWrapper,
) {
contents.extend_from_slice(&[
Op::StartTextSection,
Op::SetLineHeight {
lh: Pt(font_size * 1.2),
},
Op::SetFontSize {
size: Pt(font_size),
font: font_id.clone(),
},
]);
if let Some(text) = additional_text {
contents.extend_from_slice(&[
Op::SetTextMatrix {
matrix: TextMatrix::Translate(Pt(0.0), Pt(0.0)),
},
Op::SetTextCursor {
pos: Point {
x: (page_dimensions.width - page_dimensions.margin_right).into_pt() - Pt(text.width),
y: (page_dimensions.height - Mm(7.5)).into(),
},
},
]);
for line in text.lines() {
contents.push(Op::WriteText {
items: vec![TextItem::Text(line.to_string())],
font: font_id.clone(),
});
contents.push(Op::AddLineBreak);
}
}
if include_path {
contents.extend_from_slice(&[
Op::SetTextMatrix {
matrix: TextMatrix::Translate(Pt(0.0), Pt(0.0)),
},
Op::SetTextCursor {
pos: Point {
x: page_dimensions.margin_left.into(),
y: (page_dimensions.height - Mm(7.5)).into(),
},
},
]);
let max_path_width = (page_dimensions.max_text_width()
- if let Some(text) = &additional_text {
Mm::from(Pt(text.width)) + Mm(5.0)
} else {
Mm(0.0)
})
.into_pt();
for (line, _) in wrapper.split_into_lines(&path.display().to_string(), |_| max_path_width) {
contents.push(Op::WriteText {
items: vec![TextItem::Text(line)],
font: font_id.clone(),
});
contents.push(Op::AddLineBreak);
}
}
contents.extend_from_slice(&[
Op::SetTextMatrix {
matrix: TextMatrix::Translate(Pt(0.0), Pt(0.0)),
},
Op::SetTextCursor {
pos: Point {
x: page_dimensions.margin_left.into(),
y: (page_dimensions.height - page_dimensions.margin_top).into(),
},
},
Op::SetTextRenderingMode {
mode: TextRenderingMode::Fill,
},
]);
}