docx_reader/documents/elements/
pic.rs

1use image::*;
2use serde::Serialize;
3
4use crate::documents::*;
5use crate::types::*;
6
7#[derive(Debug, Clone, Serialize, PartialEq)]
8#[serde(rename_all = "camelCase")]
9pub struct Pic {
10	pub id: String,
11	// For writer only
12	#[serde(skip_serializing_if = "Vec::is_empty")]
13	pub image: Vec<u8>,
14	// unit is emu
15	pub size: (u32, u32),
16	pub position_type: DrawingPositionType,
17	/// Specifies that this object shall be positioned using the positioning information in the
18	/// simplePos child element (ยง20.4.2.13). This positioning, when specified, positions the
19	/// object on the page by placing its top left point at the x-y coordinates specified by that
20	/// element.
21	pub simple_pos: bool,
22	// unit is emu
23	pub simple_pos_x: i32,
24	pub simple_pos_y: i32,
25	/// Specifies how this DrawingML object behaves when its anchor is located in a table cell;
26	/// and its specified position would cause it to intersect with a table cell displayed in the
27	/// document. That behavior shall be as follows:
28	pub layout_in_cell: bool,
29	/// Specifies the relative Z-ordering of all DrawingML objects in this document. Each floating
30	/// DrawingML object shall have a Z-ordering value, which determines which object is
31	/// displayed when any two objects intersect. Higher values shall indicate higher Z-order;
32	/// lower values shall indicate lower Z-order.
33	pub relative_height: u32,
34	pub allow_overlap: bool,
35	pub position_h: DrawingPosition,
36	pub position_v: DrawingPosition,
37	pub relative_from_h: RelativeFromHType,
38	pub relative_from_v: RelativeFromVType,
39	/// Specifies the minimum distance which shall be maintained between the top edge of this drawing object and any subsequent text within the document when this graphical object is displayed within the document's contents.,
40	/// The distance shall be measured in EMUs (English Metric Units).,
41	pub dist_t: i32,
42	pub dist_b: i32,
43	pub dist_l: i32,
44	pub dist_r: i32,
45	// deg
46	pub rot: u16,
47}
48
49impl Pic {
50	pub fn new(buf: &[u8]) -> Pic {
51		let id = create_pic_rid(generate_pic_id());
52		let dimg = image::load_from_memory(buf).expect("Should load image from memory.");
53		let size = dimg.dimensions();
54		let mut image = std::io::Cursor::new(vec![]);
55		// For now only png supported
56		dimg.write_to(&mut image, ImageFormat::Png)
57			.expect("Unable to write dynamic image");
58		Self {
59			id,
60			image: image.into_inner(),
61			size: (from_px(size.0), from_px(size.1)),
62			position_type: DrawingPositionType::Inline,
63			simple_pos: false,
64			simple_pos_x: 0,
65			simple_pos_y: 0,
66			layout_in_cell: false,
67			relative_height: 190500,
68			allow_overlap: false,
69			position_v: DrawingPosition::Offset(0),
70			position_h: DrawingPosition::Offset(0),
71			relative_from_h: RelativeFromHType::default(),
72			relative_from_v: RelativeFromVType::default(),
73			dist_t: 0,
74			dist_b: 0,
75			dist_l: 0,
76			dist_r: 0,
77			rot: 0,
78		}
79	}
80
81	pub(crate) fn with_empty() -> Pic {
82		Self {
83			id: "".to_string(),
84			image: vec![],
85			size: (0, 0),
86			position_type: DrawingPositionType::Inline,
87			simple_pos: false,
88			simple_pos_x: 0,
89			simple_pos_y: 0,
90			layout_in_cell: false,
91			relative_height: 190500,
92			allow_overlap: false,
93			position_v: DrawingPosition::Offset(0),
94			position_h: DrawingPosition::Offset(0),
95			relative_from_h: RelativeFromHType::default(),
96			relative_from_v: RelativeFromVType::default(),
97			dist_t: 0,
98			dist_b: 0,
99			dist_l: 0,
100			dist_r: 0,
101			rot: 0,
102		}
103	}
104
105	pub fn id(mut self, id: impl Into<String>) -> Pic {
106		self.id = id.into();
107		self
108	}
109
110	// unit is emu
111	pub fn size(mut self, w_emu: u32, h_emu: u32) -> Pic {
112		self.size = (w_emu, h_emu);
113		self
114	}
115
116	// unit is deg
117	pub fn rotate(mut self, deg: u16) -> Pic {
118		self.rot = deg;
119		self
120	}
121
122	pub fn floating(mut self) -> Pic {
123		self.position_type = DrawingPositionType::Anchor;
124		self
125	}
126
127	pub fn overlapping(mut self) -> Pic {
128		self.allow_overlap = true;
129		self
130	}
131
132	pub fn offset_x(mut self, x: i32) -> Pic {
133		self.position_h = DrawingPosition::Offset(x);
134		self
135	}
136
137	pub fn offset_y(mut self, y: i32) -> Pic {
138		self.position_v = DrawingPosition::Offset(y);
139		self
140	}
141
142	pub fn position_h(mut self, pos: DrawingPosition) -> Self {
143		self.position_h = pos;
144		self
145	}
146
147	pub fn position_v(mut self, pos: DrawingPosition) -> Self {
148		self.position_v = pos;
149		self
150	}
151
152	pub fn relative_from_h(mut self, t: RelativeFromHType) -> Self {
153		self.relative_from_h = t;
154		self
155	}
156
157	pub fn relative_from_v(mut self, t: RelativeFromVType) -> Self {
158		self.relative_from_v = t;
159		self
160	}
161
162	pub fn dist_t(mut self, v: i32) -> Self {
163		self.dist_t = v;
164		self
165	}
166
167	pub fn dist_b(mut self, v: i32) -> Self {
168		self.dist_b = v;
169		self
170	}
171
172	pub fn dist_l(mut self, v: i32) -> Self {
173		self.dist_l = v;
174		self
175	}
176
177	pub fn dist_r(mut self, v: i32) -> Self {
178		self.dist_r = v;
179		self
180	}
181
182	pub fn simple_pos(mut self, v: bool) -> Self {
183		self.simple_pos = v;
184		self
185	}
186
187	pub fn relative_height(mut self, v: u32) -> Self {
188		self.relative_height = v;
189		self
190	}
191}