pdfboss_output/ir.rs
1//! The layout intermediate representation: what the structure pass builds
2//! from spans and what every output adapter renders.
3
4use serde::Serialize;
5
6/// A device-space box: `y` grows upward, as in PDF user space.
7#[derive(Debug, Clone, PartialEq, Serialize)]
8pub struct BBox {
9 pub x0: f32,
10 pub y0: f32,
11 pub x1: f32,
12 pub y1: f32,
13}
14
15/// A run of same-styled text within a line. `text` already carries the
16/// spaces the word-gap rule inserted, so rendering a line is concatenation.
17#[derive(Debug, Clone, PartialEq, Serialize)]
18pub struct Inline {
19 pub text: String,
20 pub bold: bool,
21 pub italic: bool,
22}
23
24/// One visual line. The geometry travels with it because later structure
25/// passes — lists, tables, page headers and footers — classify lines by it.
26#[derive(Debug, Clone, PartialEq, Serialize)]
27pub struct Line {
28 pub inlines: Vec<Inline>,
29 /// Baseline of the line's first span.
30 pub y: f32,
31 /// Left edge: the leftmost span's origin.
32 pub x: f32,
33 /// Right edge: the rightmost span's end, after its last glyph's advance.
34 pub end_x: f32,
35 /// The largest font size on the line.
36 pub size: f32,
37}
38
39/// What introduces a list item.
40#[derive(Debug, Clone, PartialEq, Serialize)]
41pub enum Marker {
42 Bullet,
43 Number(u32),
44}
45
46/// One list item: its marker, the marker text's length in characters (the
47/// continuation indent a wrapped item is measured against), and its lines.
48#[derive(Debug, Clone, PartialEq, Serialize)]
49pub struct ListItem {
50 pub marker: Marker,
51 pub marker_len: usize,
52 pub lines: Vec<Line>,
53}
54
55/// One table cell. An empty cell — or one covered by a neighbour's span —
56/// carries no line.
57#[derive(Debug, Clone, PartialEq, Serialize)]
58pub struct Cell {
59 pub line: Option<Line>,
60 pub colspan: u8,
61 pub rowspan: u8,
62}
63
64/// What a paragraph is to the page: its body, or a page header or footer repeated on
65/// every page.
66#[derive(Debug, Clone, PartialEq, Serialize)]
67pub enum Role {
68 Body,
69 PageHeader,
70 PageFooter,
71}
72
73/// One structural unit of a page, in reading order.
74#[derive(Debug, Clone, PartialEq, Serialize)]
75pub enum Block {
76 Heading {
77 level: u8,
78 lines: Vec<Line>,
79 bbox: BBox,
80 },
81 Paragraph {
82 lines: Vec<Line>,
83 bbox: BBox,
84 role: Role,
85 },
86 List {
87 items: Vec<ListItem>,
88 bbox: BBox,
89 },
90 Table {
91 rows: Vec<Vec<Cell>>,
92 bbox: BBox,
93 },
94}
95
96/// One page's blocks in reading order.
97#[derive(Debug, Clone, PartialEq, Serialize)]
98pub struct PageLayout {
99 pub blocks: Vec<Block>,
100}