Skip to main content

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}