lightweight_pdf_core/watermark.rs
1//! `Watermark` (Phase 6, `plan/phases/phase-6-business-polish.md` step 2):
2//! a rotated diagonal stamp ("ENTWURF", "STORNIERT"). Deliberately **not**
3//! a normal flow `Element` — it's a document-level, independent layer,
4//! always drawn first (bottom) and clipped to the body content box, per
5//! `05-overflow-and-robustness.md`'s explicit requirement that it must
6//! never make normal content unreadable or bleed into the header/footer
7//! bands. No general rotation/transform API is introduced for other
8//! elements (ADR/plan: "kein allgemeine Transform-API").
9
10use crate::style::{Color, FontKey};
11
12#[derive(Clone, Debug)]
13pub struct Watermark {
14 pub text: String,
15 /// Counter-clockwise rotation in degrees, applied around the body
16 /// box's center. 45° (bottom-left to top-right diagonal) matches the
17 /// conventional "ENTWURF"/"DRAFT" stamp look.
18 pub rotation_deg: f32,
19 pub size: f32,
20 pub color: Color,
21 pub font: FontKey,
22}
23
24impl Watermark {
25 pub fn new(text: impl Into<String>) -> Self {
26 Watermark {
27 text: text.into(),
28 rotation_deg: 45.0,
29 size: 72.0,
30 // Light gray: legible-by-construction since normal content
31 // always draws *after* (on top of) the watermark, but a light
32 // color keeps the page from looking visually "shouted at".
33 color: Color::rgb(210, 210, 210),
34 font: FontKey::SANS_BOLD,
35 }
36 }
37
38 pub fn rotation(mut self, degrees: f32) -> Self {
39 self.rotation_deg = degrees;
40 self
41 }
42
43 pub fn size(mut self, size: f32) -> Self {
44 self.size = size;
45 self
46 }
47
48 pub fn color(mut self, color: Color) -> Self {
49 self.color = color;
50 self
51 }
52}