Skip to main content

rust_pdf_box/pd/
resources.rs

1use crate::cos::object::{COSDictionary, COSName, COSObject, ObjectId};
2
3/// The Resources dictionary of a page or form XObject (/Resources).
4#[derive(Debug, Clone, Default)]
5pub struct PDResources {
6    pub dict: COSDictionary,
7}
8
9impl PDResources {
10    pub fn new() -> Self {
11        Self {
12            dict: COSDictionary::new(),
13        }
14    }
15
16    pub fn from_dict(dict: COSDictionary) -> Self {
17        Self { dict }
18    }
19
20    /// Adds a font reference and returns the font resource name (e.g., "F1").
21    pub fn add_font(&mut self, font_ref: ObjectId) -> String {
22        let font_dict = self
23            .dict
24            .entries
25            .entry(COSName::new("Font"))
26            .or_insert_with(|| COSObject::Dictionary(COSDictionary::new()));
27
28        if let COSObject::Dictionary(d) = font_dict {
29            let next_index = d.entries.len() + 1;
30            let name = format!("F{}", next_index);
31            d.set(COSName::new(&name), font_ref);
32            name
33        } else {
34            "F1".to_string()
35        }
36    }
37
38    /// Adds an XObject (image or form) reference and returns the resource name (e.g., "Im1").
39    pub fn add_xobject(&mut self, prefix: &str, xobj_ref: ObjectId) -> String {
40        let xobj_dict = self
41            .dict
42            .entries
43            .entry(COSName::new("XObject"))
44            .or_insert_with(|| COSObject::Dictionary(COSDictionary::new()));
45
46        if let COSObject::Dictionary(d) = xobj_dict {
47            let next_index = d.entries.len() + 1;
48            let name = format!("{}{}", prefix, next_index);
49            d.set(COSName::new(&name), xobj_ref);
50            name
51        } else {
52            format!("{}1", prefix)
53        }
54    }
55
56    /// Adds an Extended Graphics State (opacity / alpha) and returns resource name (e.g. "GS1").
57    pub fn add_ext_gstate(&mut self, stroke_alpha: f64, fill_alpha: f64) -> String {
58        let gs_dict = self
59            .dict
60            .entries
61            .entry(COSName::new("ExtGState"))
62            .or_insert_with(|| COSObject::Dictionary(COSDictionary::new()));
63
64        if let COSObject::Dictionary(d) = gs_dict {
65            let next_index = d.entries.len() + 1;
66            let name = format!("GS{}", next_index);
67            let mut state_dict = COSDictionary::new();
68            state_dict.set("Type", COSName::new("ExtGState"));
69            state_dict.set("CA", stroke_alpha);
70            state_dict.set("ca", fill_alpha);
71            d.set(COSName::new(&name), state_dict);
72            name
73        } else {
74            "GS1".to_string()
75        }
76    }
77}