1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use crate::{
catalog::{GroupAttributes, MetadataStream, OptionalContent, PagePiece},
data_structures::{Matrix, Rectangle},
date::Date,
error::PdfResult,
resources::Resources,
stream::Stream,
Resolve,
};
use super::{reference::ReferenceXObject, OpenPrepressInterface};
#[derive(Debug)]
pub struct FormXObject {
/// An array of four numbers in the form coordinate system (see above), giving the
/// coordinates of the left, bottom, right, and top edges, respectively, of the form
/// XObject's bounding box. These boundaries shall be used to clip the form XObject and
/// to determine its size for caching
bbox: Rectangle,
/// An array of six numbers specifying the form matrix, which maps form space into
/// user space
///
/// Default value: the identity matrix [1 0 0 1 0 0].
matrix: Matrix,
/// A dictionary specifying any resources (such as fonts and images) required by the
/// form XObject.
///
/// In a PDF whose version is 1.1 and earlier, all named resources used in the form
/// XObject shall be included in the resource dictionary of each page object on which
/// the form XObject appears, regardless of whether they also appear in the resource
/// dictionary of the form XObject. These resources should also be specified in the
/// form XObject's resource dictionary as well, to determine which resources are used
/// inside the form XObject. If a resource is included in both dictionaries, it shall
/// have the same name in both locations.
///
/// In PDF 1.2 and later versions, form XObjects may be independent of the content
/// streams in which they appear, and this is strongly recommended although not required.
/// In an independent form XObject, the resource dictionary of the form XObject is required
/// and shall contain all named resources used by the form XObject. These resources shall
/// not be promoted to the outer content stream's resource dictionary, although that
/// stream's resource dictionary refers to the form XObject
resources: Option<Resources>,
/// A group attributes dictionary indicating that the contents of the form XObject shall
/// be treated as a group and specifying the attributes of that group.
///
/// If a Ref entry (see below) is present, the group attributes shall also apply to
/// the external page imported by that entry, which allows such an imported page to be
/// treated as a group without further modification
group: Option<GroupAttributes>,
/// A reference dictionary identifying a page to be imported from another PDF file,
/// and for which the form XObject serves as a proxy
reference: Option<ReferenceXObject>,
/// A metadata stream containing metadata for the form XObject
metadata: Option<MetadataStream>,
/// A page-piece dictionary associated with the form XObject
piece_info: Option<PagePiece>,
/// The date and time when the form XObject's contents were most recently modified. If a
/// page-piece dictionary (PieceInfo) is present, the modification date shall be used to
/// ascertain which of the application data dictionaries it contains correspond to the
/// current content of the form
last_modified: Option<Date>,
/// The integer key of the form XObject's entry in the structural parent tree
struct_parent: Option<i32>,
/// The integer key of the form XObject's entry in the structural parent tree
///
/// At most one of the entries StructParent or StructParents shall be present. A form XObject
/// shall be either a content item in its entirety or a container for marked-content sequences
/// that are content items, but not both.
struct_parents: Option<i32>,
/// An OPI version dictionary for the form XObject
opi: Option<OpenPrepressInterface>,
/// An optional content group or optional content membership dictionary specifying the
/// optional content properties for the form XObject. Before the form is processed, its
/// visibility shall be determined based on this entry. If it is determined to be invisible,
/// the entire form shall be skipped, as if there were no Do operator to invoke it
oc: Option<OptionalContent>,
/// The name by which this form XObject is referenced in the XObject subdictionary of the
/// current resource dictionary
///
/// This entry is obsolescent and its use is no longer recommended
name: Option<String>,
}
impl FormXObject {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let dict = &mut stream.dict.other;
let bbox = dict.expect_rectangle("BBox", resolver)?;
let matrix = dict
.get_matrix("Matrix", resolver)?
.unwrap_or_else(Matrix::identity);
let resources = dict
.get_dict("Resources", resolver)?
.map(|dict| Resources::from_dict(dict, resolver))
.transpose()?;
let reference = dict
.get_dict("Ref", resolver)?
.map(|dict| ReferenceXObject::from_dict(dict, resolver))
.transpose()?;
let group = dict
.get_dict("Group", resolver)?
.map(|dict| GroupAttributes::from_dict(dict, resolver))
.transpose()?;
let metadata = dict
.get_stream("Metadata", resolver)?
.map(|stream| MetadataStream::from_stream(stream, resolver))
.transpose()?;
let piece_info = dict
.get_dict("PieceInfo", resolver)?
.map(|dict| PagePiece::from_dict(dict, resolver))
.transpose()?;
let last_modified = dict.get_date("LastModified", resolver)?;
let struct_parent = dict.get_integer("StructParent", resolver)?;
let struct_parents = dict.get_integer("StructParents", resolver)?;
let opi = dict
.get_dict("OPI", resolver)?
.map(|dict| OpenPrepressInterface::from_dict(dict, resolver))
.transpose()?;
let oc = dict
.get_dict("OC", resolver)?
.map(|dict| OptionalContent::from_dict(dict, resolver))
.transpose()?;
let name = dict.get_name("Name", resolver)?;
Ok(Self {
bbox,
matrix,
resources,
reference,
group,
metadata,
piece_info,
last_modified,
struct_parent,
struct_parents,
opi,
oc,
name,
})
}
}