1use std::{path::Path, str::Lines};
4
5use printpdf::{FontId, Mm, Op, Point, Pt, TextItem, TextMatrix, TextRenderingMode};
6
7use crate::{dimensions::Dimensions, text_manipulation::TextWrapper};
8#[derive(Clone)]
12pub struct ProcessedText {
13 text: String,
14 width: f32,
15}
16impl ProcessedText {
17 pub fn new(text: String, wrapper: &mut TextWrapper) -> Option<Self> {
19 let width = text
20 .lines()
21 .map(|line| wrapper.get_width(line).0)
22 .reduce(f32::max)?;
23 Some(Self { text, width })
24 }
25 fn lines(&self) -> Lines {
26 self.text.lines()
27 }
28}
29pub fn init_page(
31 contents: &mut Vec<Op>,
32 page_dimensions: &Dimensions,
33 font_id: FontId,
34 font_size: f32,
35 path: &Path,
36 additional_text: Option<&ProcessedText>,
37 include_path: bool,
38 wrapper: &mut TextWrapper,
39) {
40 contents.extend_from_slice(&[
41 Op::StartTextSection,
42 Op::SetLineHeight {
43 lh: Pt(font_size * 1.2),
44 },
45 Op::SetFontSize {
46 size: Pt(font_size),
47 font: font_id.clone(),
48 },
49 ]);
50 if let Some(text) = additional_text {
52 contents.extend_from_slice(&[
53 Op::SetTextMatrix {
54 matrix: TextMatrix::Translate(Pt(0.0), Pt(0.0)),
55 },
56 Op::SetTextCursor {
57 pos: Point {
58 x: (page_dimensions.width - page_dimensions.margin_right).into_pt() - Pt(text.width),
59 y: (page_dimensions.height - Mm(7.5)).into(),
60 },
61 },
62 ]);
63 for line in text.lines() {
64 contents.push(Op::WriteText {
65 items: vec![TextItem::Text(line.to_string())],
66 font: font_id.clone(),
67 });
68 contents.push(Op::AddLineBreak);
69 }
70 }
71 if include_path {
72 contents.extend_from_slice(&[
73 Op::SetTextMatrix {
74 matrix: TextMatrix::Translate(Pt(0.0), Pt(0.0)),
75 },
76 Op::SetTextCursor {
78 pos: Point {
79 x: page_dimensions.margin_left.into(),
80 y: (page_dimensions.height - Mm(7.5)).into(),
81 },
82 },
83 ]);
84 let max_path_width = (page_dimensions.max_text_width()
85 - if let Some(text) = &additional_text {
86 Mm::from(Pt(text.width)) + Mm(5.0)
87 } else {
88 Mm(0.0)
89 })
90 .into_pt();
91 for (line, _) in wrapper.split_into_lines(&path.display().to_string(), |_| max_path_width) {
92 contents.push(Op::WriteText {
93 items: vec![TextItem::Text(line)],
94 font: font_id.clone(),
95 });
96 contents.push(Op::AddLineBreak);
97 }
98 }
99
100 contents.extend_from_slice(&[
102 Op::SetTextMatrix {
104 matrix: TextMatrix::Translate(Pt(0.0), Pt(0.0)),
105 },
106 Op::SetTextCursor {
107 pos: Point {
108 x: page_dimensions.margin_left.into(),
109 y: (page_dimensions.height - page_dimensions.margin_top).into(),
110 },
111 },
112 Op::SetTextRenderingMode {
113 mode: TextRenderingMode::Fill,
114 },
115 ]);
116}