lopdf_table/
style.rs

1//! Styling structures for tables, rows, and cells
2
3use crate::constants::DEFAULT_MARGIN;
4
5/// RGB color representation
6#[derive(Debug, Clone, Copy, PartialEq)]
7pub struct Color {
8    pub r: f32,
9    pub g: f32,
10    pub b: f32,
11}
12
13impl Color {
14    /// Create a new RGB color (values should be 0.0-1.0)
15    pub fn rgb(r: f32, g: f32, b: f32) -> Self {
16        Self {
17            r: r.clamp(0.0, 1.0),
18            g: g.clamp(0.0, 1.0),
19            b: b.clamp(0.0, 1.0),
20        }
21    }
22
23    /// Black color
24    pub fn black() -> Self {
25        Self::rgb(0.0, 0.0, 0.0)
26    }
27
28    /// White color
29    pub fn white() -> Self {
30        Self::rgb(1.0, 1.0, 1.0)
31    }
32
33    /// Gray color
34    pub fn gray(level: f32) -> Self {
35        let l = level.clamp(0.0, 1.0);
36        Self::rgb(l, l, l)
37    }
38
39    /// Light gray
40    pub fn light_gray() -> Self {
41        Self::gray(0.8)
42    }
43}
44
45impl Default for Color {
46    fn default() -> Self {
47        Self::black()
48    }
49}
50
51/// Text alignment options
52#[derive(Debug, Clone, Copy, PartialEq)]
53pub enum Alignment {
54    Left,
55    Center,
56    Right,
57}
58
59impl Default for Alignment {
60    fn default() -> Self {
61        Self::Left
62    }
63}
64
65/// Vertical alignment options
66#[derive(Debug, Clone, Copy, PartialEq)]
67pub enum VerticalAlignment {
68    Top,
69    Middle,
70    Bottom,
71}
72
73impl Default for VerticalAlignment {
74    fn default() -> Self {
75        Self::Middle
76    }
77}
78
79/// Border style options
80#[derive(Debug, Clone, Copy, PartialEq)]
81pub enum BorderStyle {
82    None,
83    Solid,
84    Dashed,
85    Dotted,
86}
87
88impl Default for BorderStyle {
89    fn default() -> Self {
90        Self::Solid
91    }
92}
93
94/// Padding for cells
95#[derive(Debug, Clone, Copy)]
96pub struct Padding {
97    pub top: f32,
98    pub right: f32,
99    pub bottom: f32,
100    pub left: f32,
101}
102
103impl Padding {
104    /// Create uniform padding
105    pub fn uniform(value: f32) -> Self {
106        Self {
107            top: value,
108            right: value,
109            bottom: value,
110            left: value,
111        }
112    }
113
114    /// Create padding with vertical and horizontal values
115    pub fn symmetric(vertical: f32, horizontal: f32) -> Self {
116        Self {
117            top: vertical,
118            bottom: vertical,
119            left: horizontal,
120            right: horizontal,
121        }
122    }
123}
124
125impl Default for Padding {
126    fn default() -> Self {
127        Self::uniform(5.0)
128    }
129}
130
131/// Styling for the entire table
132#[derive(Debug, Clone)]
133pub struct TableStyle {
134    pub border_style: BorderStyle,
135    pub border_width: f32,
136    pub border_color: Color,
137    pub background_color: Option<Color>,
138    pub padding: Padding,
139    /// Default font for the table
140    pub font_name: String,
141    pub default_font_size: f32,
142    /// Page height for pagination (if None, uses standard A4: 842 points)
143    pub page_height: Option<f32>,
144    /// Top margin for pages
145    pub top_margin: f32,
146    /// Bottom margin for pages
147    pub bottom_margin: f32,
148    /// Whether to repeat header rows on new pages
149    pub repeat_headers: bool,
150}
151
152impl Default for TableStyle {
153    fn default() -> Self {
154        Self {
155            border_style: BorderStyle::Solid,
156            border_width: 1.0,
157            border_color: Color::black(),
158            background_color: None,
159            padding: Padding::default(),
160            font_name: "Helvetica".to_string(),
161            default_font_size: 10.0,
162            page_height: None, // Will default to A4 (842 points)
163            top_margin: DEFAULT_MARGIN,
164            bottom_margin: DEFAULT_MARGIN,
165            repeat_headers: true,
166        }
167    }
168}
169
170/// Styling for a row
171#[derive(Debug, Clone)]
172pub struct RowStyle {
173    pub background_color: Option<Color>,
174    pub border_top: Option<(BorderStyle, f32, Color)>,
175    pub border_bottom: Option<(BorderStyle, f32, Color)>,
176    pub height: Option<f32>,
177}
178
179impl Default for RowStyle {
180    fn default() -> Self {
181        Self {
182            background_color: None,
183            border_top: None,
184            border_bottom: None,
185            height: None,
186        }
187    }
188}
189
190/// Styling for a cell
191#[derive(Debug, Clone)]
192pub struct CellStyle {
193    pub background_color: Option<Color>,
194    pub text_color: Color,
195    pub font_size: Option<f32>,
196    pub bold: bool,
197    pub italic: bool,
198    pub alignment: Alignment,
199    pub vertical_alignment: VerticalAlignment,
200    pub padding: Option<Padding>,
201    pub border_left: Option<(BorderStyle, f32, Color)>,
202    pub border_right: Option<(BorderStyle, f32, Color)>,
203    pub border_top: Option<(BorderStyle, f32, Color)>,
204    pub border_bottom: Option<(BorderStyle, f32, Color)>,
205}
206
207impl Default for CellStyle {
208    fn default() -> Self {
209        Self {
210            background_color: None,
211            text_color: Color::black(),
212            font_size: None,
213            bold: false,
214            italic: false,
215            alignment: Alignment::Left,
216            vertical_alignment: VerticalAlignment::Middle,
217            padding: None,
218            border_left: None,
219            border_right: None,
220            border_top: None,
221            border_bottom: None,
222        }
223    }
224}
225
226impl CellStyle {
227    /// Create a header cell style (bold, centered)
228    pub fn header() -> Self {
229        Self {
230            bold: true,
231            alignment: Alignment::Center,
232            background_color: Some(Color::light_gray()),
233            ..Default::default()
234        }
235    }
236}