docx_reader/reader/
drawing.rs1use std::io::Read;
2use std::str::FromStr;
3use xml::attribute::OwnedAttribute;
4use xml::reader::{EventReader, XmlEvent};
5
6use crate::types::*;
7use crate::{DrawingPositionType, RelativeFromHType, RelativeFromVType};
8
9use super::*;
10
11fn read_position_h<R: Read>(
12 r: &mut EventReader<R>,
13 attrs: &[OwnedAttribute],
14) -> Result<(RelativeFromHType, i32), ReaderError> {
15 let mut offset: i32 = 0;
16 let mut relative_from_h = RelativeFromHType::default();
17
18 loop {
19 if let Some(h) = read(attrs, "relativeFrom") {
20 if let Ok(h) = RelativeFromHType::from_str(&h) {
21 relative_from_h = h;
22 }
23 }
24 let e = r.next();
25 match e {
26 Ok(XmlEvent::Characters(c)) => {
27 if let Ok(p) = f64::from_str(&c) {
28 offset = p as i32;
29 }
30 }
31 Ok(XmlEvent::EndElement { name, .. }) => {
32 let e = WpXMLElement::from_str(&name.local_name).unwrap();
33 if e == WpXMLElement::PositionH {
34 return Ok((relative_from_h, offset));
35 }
36 }
37 Err(_) => return Err(ReaderError::XMLReadError),
38 _ => {}
39 }
40 }
41}
42
43fn read_position_v<R: Read>(
44 r: &mut EventReader<R>,
45 attrs: &[OwnedAttribute],
46) -> Result<(RelativeFromVType, i32), ReaderError> {
47 let mut offset: i32 = 0;
48 let mut relative_from_v = RelativeFromVType::default();
49 loop {
50 if let Some(v) = read(attrs, "relativeFrom") {
51 if let Ok(v) = RelativeFromVType::from_str(&v) {
52 relative_from_v = v;
53 }
54 }
55
56 let e = r.next();
57 match e {
58 Ok(XmlEvent::Characters(c)) => {
59 if let Ok(p) = f64::from_str(&c) {
60 offset = p as i32;
61 }
62 }
63 Ok(XmlEvent::EndElement { name, .. }) => {
64 let e = WpXMLElement::from_str(&name.local_name).unwrap();
65 if e == WpXMLElement::PositionV {
66 return Ok((relative_from_v, offset));
67 }
68 }
69 Err(_) => return Err(ReaderError::XMLReadError),
70 _ => {}
71 }
72 }
73}
74
75fn read_textbox_content<R: Read>(
76 r: &mut EventReader<R>,
77 _attrs: &[OwnedAttribute],
78) -> Result<Vec<TextBoxContentChild>, ReaderError> {
79 let mut children = vec![];
80 loop {
81 let e = r.next();
82 match e {
83 Ok(XmlEvent::StartElement {
84 attributes, name, ..
85 }) => {
86 let e = XMLElement::from_str(&name.local_name).unwrap();
87 match e {
88 XMLElement::Paragraph => {
89 let p = Paragraph::read(r, &attributes)?;
90 children.push(TextBoxContentChild::Paragraph(Box::new(p)));
91 continue;
92 }
93 XMLElement::Table => {
94 let t = Table::read(r, &attributes)?;
95 children.push(TextBoxContentChild::Table(Box::new(t)));
96 continue;
97 }
98 _ => {}
99 }
100 }
101 Ok(XmlEvent::EndElement { name, .. }) => {
102 let e = WpsXMLElement::from_str(&name.local_name).unwrap();
103 if e == WpsXMLElement::Txbx {
104 return Ok(children);
105 }
106 }
107 Err(_) => return Err(ReaderError::XMLReadError),
108 _ => {}
109 }
110 }
111}
112
113impl ElementReader for Drawing {
114 fn read<R: Read>(
115 r: &mut EventReader<R>,
116 _attrs: &[OwnedAttribute],
117 ) -> Result<Self, ReaderError> {
118 let mut drawing = Drawing::new();
119 let mut drawing_position_type = DrawingPositionType::Inline;
120
121 let mut simple_pos = false;
122 let mut simple_pos_x = 0;
123 let mut simple_pos_y = 0;
124 let mut layout_in_cell = true;
125 let mut relative_height = 0;
126 let mut position_h = 0;
127 let mut position_v = 0;
128 let mut relative_from_h = RelativeFromHType::default();
129 let mut relative_from_v = RelativeFromVType::default();
130 let mut allow_overlap = true;
131 let mut dist_t = 0;
132 let mut dist_b = 0;
133 let mut dist_l = 0;
134 let mut dist_r = 0;
135
136 loop {
137 let e = r.next();
138 match e {
139 Ok(XmlEvent::StartElement {
140 name, attributes, ..
141 }) => {
142 if let Ok(wpe) = WpXMLElement::from_str(&name.local_name) {
144 match wpe {
145 WpXMLElement::Anchor => {
146 drawing_position_type = DrawingPositionType::Anchor;
147 if let Some(v) = read(&attributes, "simplePos") {
148 if !is_false(&v) {
149 simple_pos = true;
150 }
151 }
152 if let Some(d) = read(&attributes, "distT") {
153 if let Ok(d) = f64::from_str(&d) {
154 dist_t = d as i32;
155 }
156 }
157 if let Some(d) = read(&attributes, "distB") {
158 if let Ok(d) = f64::from_str(&d) {
159 dist_b = d as i32;
160 }
161 }
162 if let Some(d) = read(&attributes, "distL") {
163 if let Ok(d) = f64::from_str(&d) {
164 dist_l = d as i32;
165 }
166 }
167 if let Some(d) = read(&attributes, "distR") {
168 if let Ok(d) = f64::from_str(&d) {
169 dist_r = d as i32;
170 }
171 }
172 if let Some(d) = read(&attributes, "layoutInCell") {
173 if is_false(&d) {
174 layout_in_cell = false;
175 }
176 }
177 if let Some(d) = read(&attributes, "relativeHeight") {
178 if let Ok(d) = f64::from_str(&d) {
179 relative_height = d as u32;
180 }
181 }
182 if let Some(d) = read(&attributes, "allowOverlap") {
183 if is_false(&d) {
184 allow_overlap = false;
185 }
186 }
187 }
188 WpXMLElement::Inline => {
189 drawing_position_type = DrawingPositionType::Inline;
190 if let Some(d) = read(&attributes, "distT") {
191 if let Ok(d) = f64::from_str(&d) {
192 dist_t = d as i32;
193 }
194 }
195 if let Some(d) = read(&attributes, "distB") {
196 if let Ok(d) = f64::from_str(&d) {
197 dist_b = d as i32;
198 }
199 }
200 if let Some(d) = read(&attributes, "distL") {
201 if let Ok(d) = f64::from_str(&d) {
202 dist_l = d as i32;
203 }
204 }
205 if let Some(d) = read(&attributes, "distR") {
206 if let Ok(d) = i32::from_str(&d) {
207 dist_r = d;
208 }
209 }
210 }
211 WpXMLElement::SimplePos => {
212 if let Some(x) = read(&attributes, "x") {
213 if let Ok(x) = f64::from_str(&x) {
214 simple_pos_x = x as i32;
215 }
216 }
217 if let Some(y) = read(&attributes, "y") {
218 if let Ok(y) = f64::from_str(&y) {
219 simple_pos_y = y as i32;
220 }
221 }
222 }
223 WpXMLElement::PositionH => {
224 if let Ok(p) = read_position_h(r, &attributes) {
225 relative_from_h = p.0;
226 position_h = p.1;
227 }
228 }
229 WpXMLElement::PositionV => {
230 if let Ok(p) = read_position_v(r, &attributes) {
231 relative_from_v = p.0;
232 position_v = p.1;
233 }
234 }
235 _ => {}
236 }
237 }
238 if let Ok(PicXMLElement::Pic) = PicXMLElement::from_str(&name.local_name) {
240 if let Ok(mut pic) = Pic::read(r, &attributes) {
241 pic.position_type = drawing_position_type;
242 pic.simple_pos = simple_pos;
243 pic.simple_pos_x = simple_pos_x;
244 pic.simple_pos_y = simple_pos_y;
245 pic.layout_in_cell = layout_in_cell;
246 pic.relative_height = relative_height;
247 pic.allow_overlap = allow_overlap;
248 pic.dist_r = dist_r;
249 pic.dist_t = dist_t;
250 pic.dist_b = dist_b;
251 pic.dist_l = dist_l;
252 pic.dist_r = dist_r;
253 pic.relative_from_h = relative_from_h;
254 pic.relative_from_v = relative_from_v;
255 pic.position_v = DrawingPosition::Offset(position_v);
256 pic.position_h = DrawingPosition::Offset(position_h);
257 drawing = drawing.pic(pic);
258 }
259 }
260
261 if let Ok(WpsXMLElement::Txbx) = WpsXMLElement::from_str(&name.local_name) {
263 if let Ok(children) = read_textbox_content(r, &attributes) {
264 let mut text_box = TextBox::new();
265 text_box.position_type = drawing_position_type;
266 text_box.simple_pos = simple_pos;
267 text_box.simple_pos_x = simple_pos_x;
268 text_box.simple_pos_y = simple_pos_y;
269 text_box.layout_in_cell = layout_in_cell;
270 text_box.relative_height = relative_height;
271 text_box.allow_overlap = allow_overlap;
272 text_box.dist_r = dist_r;
273 text_box.dist_t = dist_t;
274 text_box.dist_b = dist_b;
275 text_box.dist_l = dist_l;
276 text_box.dist_r = dist_r;
277 text_box.relative_from_h = relative_from_h;
278 text_box.relative_from_v = relative_from_v;
279 text_box.position_v = DrawingPosition::Offset(position_v);
280 text_box.position_h = DrawingPosition::Offset(position_h);
281 text_box.children = children;
282 drawing = drawing.text_box(text_box);
283 }
284 }
285 }
286 Ok(XmlEvent::EndElement { name, .. }) => {
287 let e = XMLElement::from_str(&name.local_name).unwrap();
288 if e == XMLElement::Drawing {
289 return Ok(drawing);
290 }
291 }
292 Err(_) => return Err(ReaderError::XMLReadError),
293 _ => {}
294 }
295 }
296 }
297}