docling_pdf/render/
objects.rs1use lopdf::{Dictionary, Document, Object};
4
5pub fn deref<'a>(doc: &'a Document, obj: &'a Object) -> &'a Object {
7 match obj {
8 Object::Reference(id) => doc.get_object(*id).unwrap_or(obj),
9 o => o,
10 }
11}
12
13pub fn as_dict<'a>(doc: &'a Document, obj: &'a Object) -> Option<&'a Dictionary> {
14 match deref(doc, obj) {
15 Object::Dictionary(d) => Some(d),
16 Object::Stream(s) => Some(&s.dict),
17 _ => None,
18 }
19}
20
21pub fn as_stream<'a>(doc: &'a Document, obj: &'a Object) -> Option<&'a lopdf::Stream> {
22 match deref(doc, obj) {
23 Object::Stream(s) => Some(s),
24 _ => None,
25 }
26}
27
28pub fn num(o: &Object) -> Option<f64> {
29 match o {
30 Object::Integer(i) => Some(*i as f64),
31 Object::Real(r) => Some(f64::from(*r)),
32 _ => None,
33 }
34}
35
36pub fn nums(doc: &Document, o: &Object) -> Option<Vec<f64>> {
38 match deref(doc, o) {
39 Object::Array(a) => Some(a.iter().filter_map(|x| num(deref(doc, x))).collect()),
40 _ => None,
41 }
42}
43
44pub fn name(o: &Object) -> Option<&[u8]> {
45 match o {
46 Object::Name(n) => Some(n),
47 _ => None,
48 }
49}
50
51pub fn get<'a>(doc: &'a Document, dict: &'a Dictionary, key: &[u8]) -> Option<&'a Object> {
53 dict.get(key).ok().map(|o| deref(doc, o))
54}
55
56pub fn get2<'a>(
58 doc: &'a Document,
59 dict: &'a Dictionary,
60 key: &[u8],
61 alt: &[u8],
62) -> Option<&'a Object> {
63 get(doc, dict, key).or_else(|| get(doc, dict, alt))
64}
65
66pub fn get_int2(doc: &Document, d: &Dictionary, key: &[u8], alt: &[u8]) -> Option<i64> {
68 get_int(doc, d, key).or_else(|| get_int(doc, d, alt))
69}
70
71pub fn get_bool2(doc: &Document, d: &Dictionary, key: &[u8], alt: &[u8]) -> Option<bool> {
73 get_bool(doc, d, key).or_else(|| get_bool(doc, d, alt))
74}
75
76pub fn get_num(doc: &Document, dict: &Dictionary, key: &[u8]) -> Option<f64> {
77 get(doc, dict, key).and_then(num)
78}
79
80pub fn get_int(doc: &Document, dict: &Dictionary, key: &[u8]) -> Option<i64> {
81 get(doc, dict, key).and_then(|o| match o {
82 Object::Integer(i) => Some(*i),
83 Object::Real(r) => Some(*r as i64),
84 _ => None,
85 })
86}
87
88pub fn get_bool(doc: &Document, dict: &Dictionary, key: &[u8]) -> Option<bool> {
89 get(doc, dict, key).and_then(|o| match o {
90 Object::Boolean(b) => Some(*b),
91 Object::Integer(i) => Some(*i != 0),
92 _ => None,
93 })
94}
95
96pub fn get_name<'a>(doc: &'a Document, dict: &'a Dictionary, key: &[u8]) -> Option<&'a [u8]> {
97 get(doc, dict, key).and_then(name)
98}
99
100pub fn get_dict<'a>(doc: &'a Document, dict: &'a Dictionary, key: &[u8]) -> Option<&'a Dictionary> {
101 dict.get(key).ok().and_then(|o| as_dict(doc, o))
102}
103
104pub fn resource<'a>(
106 doc: &'a Document,
107 res: Option<&'a Dictionary>,
108 kind: &[u8],
109 name: &[u8],
110) -> Option<&'a Object> {
111 res?.get(kind)
112 .ok()
113 .and_then(|o| as_dict(doc, o))
114 .and_then(|d| d.get(name).ok())
115}
116
117pub fn stream_data(s: &lopdf::Stream) -> Option<Vec<u8>> {
119 s.decompressed_content().ok()
120}