Skip to main content

umya_spreadsheet/structs/drawing/
blip.rs

1// a:blip
2use 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        // a:blip
127        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        // a:extLst
138        write_start_tag(writer, "a:extLst", vec![], false);
139
140        // a:ext
141        write_start_tag(
142            writer,
143            "a:ext",
144            vec![("uri", "{28A0092B-C50C-407E-A947-70E740481C1C}").into()],
145            false,
146        );
147
148        // a14:useLocalDpi
149        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}