umya_spreadsheet/structs/drawing/
blip.rs1use std::io::Cursor;
3
4use quick_xml::{
5 Reader,
6 Writer,
7 events::{
8 BytesStart,
9 Event,
10 },
11};
12
13use crate::{
14 helper::const_str::{
15 DRAWING_MAIN_NS,
16 REL_OFC_NS,
17 },
18 reader::driver::{
19 get_attribute,
20 xml_read_loop,
21 },
22 structs::{
23 MediaObject,
24 raw::RawRelationships,
25 },
26 writer::driver::{
27 write_end_tag,
28 write_start_tag,
29 },
30};
31
32#[derive(Clone, Default, Debug)]
33pub struct Blip {
34 image: MediaObject,
35 cstate: Box<str>,
36}
37
38impl Blip {
39 #[inline]
40 #[must_use]
41 pub fn image(&self) -> &MediaObject {
42 &self.image
43 }
44
45 #[inline]
46 #[must_use]
47 #[deprecated(since = "3.0.0", note = "Use image()")]
48 pub fn get_image(&self) -> &MediaObject {
49 self.image()
50 }
51
52 #[inline]
53 pub fn image_mut(&mut self) -> &mut MediaObject {
54 &mut self.image
55 }
56
57 #[inline]
58 #[deprecated(since = "3.0.0", note = "Use image_mut()")]
59 pub fn get_image_mut(&mut self) -> &mut MediaObject {
60 self.image_mut()
61 }
62
63 #[inline]
64 pub fn set_image(&mut self, value: MediaObject) -> &mut Self {
65 self.image = value;
66 self
67 }
68
69 #[inline]
70 #[must_use]
71 pub fn cstate(&self) -> &str {
72 &self.cstate
73 }
74
75 #[inline]
76 #[must_use]
77 #[deprecated(since = "3.0.0", note = "Use cstate()")]
78 pub fn get_cstate(&self) -> &str {
79 self.cstate()
80 }
81
82 #[inline]
83 pub fn set_cstate<S: Into<String>>(&mut self, value: S) -> &mut Self {
84 self.cstate = value.into().into_boxed_str();
85 self
86 }
87
88 pub(crate) fn set_attributes<R: std::io::BufRead>(
89 &mut self,
90 reader: &mut Reader<R>,
91 e: &BytesStart,
92 drawing_relationships: &RawRelationships,
93 empty_flag: bool,
94 ) {
95 if let Some(v) = get_attribute(e, b"cstate") {
96 self.set_cstate(v);
97 }
98
99 let picture_id = get_attribute(e, b"r:embed").unwrap();
100 let relationship = drawing_relationships.relationship_by_rid(&picture_id);
101 self.image_mut()
102 .set_image_name(relationship.raw_file().file_name());
103 self.image_mut()
104 .set_image_data(relationship.raw_file().file_data());
105
106 if empty_flag {
107 return;
108 }
109
110 xml_read_loop!(
111 reader,
112 Event::End(ref e) => {
113 if e.name().into_inner() == b"a:blip" {
114 return
115 }
116 },
117 Event::Eof => panic!("Error: Could not find {} end element", "a:blip")
118 );
119 }
120
121 pub(crate) fn write_to(
122 &self,
123 writer: &mut Writer<Cursor<Vec<u8>>>,
124 rel_list: &mut Vec<(String, String)>,
125 ) {
126 let r_id = self.image.rid(rel_list);
128 let r_id_str = format!("rId{r_id}");
129 let mut attributes: crate::structs::AttrCollection = Vec::new();
130 attributes.push(("xmlns:r", REL_OFC_NS).into());
131 attributes.push(("r:embed", &r_id_str).into());
132 if !&self.cstate.is_empty() {
133 attributes.push(("cstate", &self.cstate).into());
134 }
135 write_start_tag(writer, "a:blip", attributes, false);
136
137 write_start_tag(writer, "a:extLst", vec![], false);
139
140 write_start_tag(
142 writer,
143 "a:ext",
144 vec![("uri", "{28A0092B-C50C-407E-A947-70E740481C1C}").into()],
145 false,
146 );
147
148 write_start_tag(
150 writer,
151 "a14:useLocalDpi",
152 vec![("xmlns:a14", DRAWING_MAIN_NS).into(), ("val", "0").into()],
153 true,
154 );
155 write_end_tag(writer, "a:ext");
156 write_end_tag(writer, "a:extLst");
157 write_end_tag(writer, "a:blip");
158 }
159}