umya_spreadsheet/structs/drawing/
run_properties.rs

1use super::super::EnumValue;
2use super::super::Int32Value;
3use super::EffectList;
4use super::GradientFill;
5use super::NoFill;
6use super::Outline;
7use super::SolidFill;
8use super::TextCapsValues;
9use super::TextFontType;
10use crate::reader::driver::*;
11use crate::structs::StringValue;
12use crate::writer::driver::*;
13use quick_xml::events::{BytesStart, Event};
14use quick_xml::Reader;
15use quick_xml::Writer;
16use std::io::Cursor;
17
18#[derive(Clone, Default, Debug)]
19pub struct RunProperties {
20    text: Box<str>,
21    kumimoji: StringValue,
22    language: StringValue,
23    alternative_language: StringValue,
24    bold: StringValue,
25    sz: StringValue,
26    italic: StringValue,
27    capital: EnumValue<TextCapsValues>,
28    spacing: Int32Value,
29    strike: StringValue,
30    outline: Option<Box<Outline>>,
31    solid_fill: Option<Box<SolidFill>>,
32    latin_font: Option<Box<TextFontType>>,
33    east_asian_font: Option<Box<TextFontType>>,
34    complex_script_font: Option<Box<TextFontType>>,
35    gradient_fill: Option<Box<GradientFill>>,
36    no_fill: Option<NoFill>,
37    effect_list: Option<Box<EffectList>>,
38}
39
40impl RunProperties {
41    #[inline]
42    pub fn get_text(&self) -> &str {
43        &self.text
44    }
45
46    #[inline]
47    pub fn set_text<S: Into<String>>(&mut self, value: S) -> &mut Self {
48        self.text = value.into().into_boxed_str();
49        self
50    }
51
52    #[inline]
53    pub fn get_kumimoji(&self) -> &str {
54        self.kumimoji.get_value_str()
55    }
56
57    #[inline]
58    pub fn set_kumimoji<S: Into<String>>(&mut self, value: S) -> &mut Self {
59        self.kumimoji.set_value_string(value.into());
60        self
61    }
62
63    #[inline]
64    pub fn get_language(&self) -> &str {
65        self.language.get_value_str()
66    }
67
68    #[inline]
69    pub fn set_language<S: Into<String>>(&mut self, value: S) -> &mut Self {
70        self.language.set_value_string(value.into());
71        self
72    }
73
74    #[inline]
75    pub fn get_alternative_language(&self) -> &str {
76        self.alternative_language.get_value_str()
77    }
78
79    #[inline]
80    pub fn set_alternative_language<S: Into<String>>(&mut self, value: S) -> &mut Self {
81        self.alternative_language.set_value_string(value.into());
82        self
83    }
84
85    #[inline]
86    pub fn get_bold(&self) -> &str {
87        self.bold.get_value_str()
88    }
89
90    #[inline]
91    pub fn set_bold<S: Into<String>>(&mut self, value: S) -> &mut Self {
92        self.bold.set_value_string(value.into());
93        self
94    }
95
96    #[inline]
97    pub fn get_sz(&self) -> &str {
98        self.sz.get_value_str()
99    }
100
101    #[inline]
102    pub fn set_sz<S: Into<String>>(&mut self, value: S) -> &mut Self {
103        self.sz.set_value_string(value.into());
104        self
105    }
106
107    #[inline]
108    pub fn get_italic(&self) -> &str {
109        self.italic.get_value_str()
110    }
111
112    #[inline]
113    pub fn set_italic<S: Into<String>>(&mut self, value: S) -> &mut Self {
114        self.italic.set_value_string(value.into());
115        self
116    }
117
118    #[inline]
119    pub fn get_capital(&self) -> &TextCapsValues {
120        self.capital.get_value()
121    }
122
123    #[inline]
124    pub fn set_capital(&mut self, value: TextCapsValues) -> &mut Self {
125        self.capital.set_value(value);
126        self
127    }
128
129    #[inline]
130    pub fn get_spacing(&self) -> &i32 {
131        self.spacing.get_value()
132    }
133
134    #[inline]
135    pub fn set_spacing(&mut self, value: i32) -> &mut Self {
136        self.spacing.set_value(value);
137        self
138    }
139
140    #[inline]
141    pub fn get_strike(&self) -> &str {
142        self.strike.get_value_str()
143    }
144
145    #[inline]
146    pub fn set_strike<S: Into<String>>(&mut self, value: S) -> &mut Self {
147        self.strike.set_value_string(value.into());
148        self
149    }
150
151    #[inline]
152    pub fn get_solid_fill(&self) -> Option<&SolidFill> {
153        self.solid_fill.as_deref()
154    }
155
156    #[inline]
157    pub fn get_solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
158        self.solid_fill.as_deref_mut()
159    }
160
161    #[inline]
162    pub fn set_solid_fill(&mut self, value: SolidFill) -> &mut Self {
163        self.solid_fill = Some(Box::new(value));
164        self
165    }
166
167    #[inline]
168    pub fn get_outline(&self) -> Option<&Outline> {
169        self.outline.as_deref()
170    }
171
172    #[inline]
173    pub fn get_outline_mut(&mut self) -> Option<&mut Outline> {
174        self.outline.as_deref_mut()
175    }
176
177    #[inline]
178    pub fn set_outline(&mut self, value: Outline) -> &mut Self {
179        self.outline = Some(Box::new(value));
180        self
181    }
182
183    #[inline]
184    pub fn get_latin_font(&self) -> Option<&TextFontType> {
185        self.latin_font.as_deref()
186    }
187
188    #[inline]
189    pub fn get_latin_font_mut(&mut self) -> Option<&mut TextFontType> {
190        self.latin_font.as_deref_mut()
191    }
192
193    #[inline]
194    pub fn set_latin_font(&mut self, value: TextFontType) -> &mut Self {
195        self.latin_font = Some(Box::new(value));
196        self
197    }
198
199    #[inline]
200    pub fn get_east_asian_font(&self) -> Option<&TextFontType> {
201        self.east_asian_font.as_deref()
202    }
203
204    #[inline]
205    pub fn get_east_asian_font_mut(&mut self) -> Option<&mut TextFontType> {
206        self.east_asian_font.as_deref_mut()
207    }
208
209    #[inline]
210    pub fn set_east_asian_font(&mut self, value: TextFontType) -> &mut Self {
211        self.east_asian_font = Some(Box::new(value));
212        self
213    }
214
215    #[inline]
216    pub fn get_complex_script_font(&self) -> Option<&TextFontType> {
217        self.complex_script_font.as_deref()
218    }
219
220    #[inline]
221    pub fn get_complex_script_font_mut(&mut self) -> Option<&mut TextFontType> {
222        self.complex_script_font.as_deref_mut()
223    }
224
225    #[inline]
226    pub fn set_complex_script_font(&mut self, value: TextFontType) -> &mut Self {
227        self.complex_script_font = Some(Box::new(value));
228        self
229    }
230
231    #[inline]
232    pub fn get_gradient_fill(&self) -> Option<&GradientFill> {
233        self.gradient_fill.as_deref()
234    }
235
236    #[inline]
237    pub fn get_gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
238        self.gradient_fill.as_deref_mut()
239    }
240
241    #[inline]
242    pub fn set_gradient_fill(&mut self, value: GradientFill) -> &mut Self {
243        self.gradient_fill = Some(Box::new(value));
244        self
245    }
246
247    #[inline]
248    pub fn get_no_fill(&self) -> Option<&NoFill> {
249        self.no_fill.as_ref()
250    }
251
252    #[inline]
253    pub fn get_no_fill_mut(&mut self) -> Option<&mut NoFill> {
254        self.no_fill.as_mut()
255    }
256
257    #[inline]
258    pub fn set_no_fill(&mut self, value: NoFill) -> &mut Self {
259        self.no_fill = Some(value);
260        self
261    }
262
263    #[inline]
264    pub fn get_effect_list(&self) -> Option<&EffectList> {
265        self.effect_list.as_deref()
266    }
267
268    #[inline]
269    pub fn get_effect_list_mut(&mut self) -> Option<&mut EffectList> {
270        self.effect_list.as_deref_mut()
271    }
272
273    #[inline]
274    pub fn set_effect_list(&mut self, value: EffectList) -> &mut Self {
275        self.effect_list = Some(Box::new(value));
276        self
277    }
278
279    pub(crate) fn set_attributes<R: std::io::BufRead>(
280        &mut self,
281        reader: &mut Reader<R>,
282        e: &BytesStart,
283        empty_flag: bool,
284    ) {
285        if let Some(v) = get_attribute(e, b"kumimoji") {
286            self.set_kumimoji(v);
287        }
288        if let Some(v) = get_attribute(e, b"lang") {
289            self.set_language(v);
290        }
291        if let Some(v) = get_attribute(e, b"altLang") {
292            self.set_alternative_language(v);
293        }
294        if let Some(v) = get_attribute(e, b"b") {
295            self.set_bold(v);
296        }
297        if let Some(v) = get_attribute(e, b"sz") {
298            self.set_sz(v);
299        }
300        if let Some(v) = get_attribute(e, b"strike") {
301            self.set_strike(v);
302        }
303        if let Some(v) = get_attribute(e, b"i") {
304            self.set_italic(v);
305        }
306        if let Some(v) = get_attribute(e, b"cap") {
307            self.capital.set_value_string(v);
308        }
309        if let Some(v) = get_attribute(e, b"spc") {
310            self.spacing.set_value_string(v);
311        }
312
313        if empty_flag {
314            return;
315        }
316
317        xml_read_loop!(
318            reader,
319            Event::Start(ref e) => {
320                match e.name().into_inner() {
321                b"a:solidFill" => {
322                    let mut obj = SolidFill::default();
323                    obj.set_attributes(reader, e);
324                    self.set_solid_fill(obj);
325                }
326                b"a:ln" => {
327                    let mut obj = Outline::default();
328                    obj.set_attributes(reader, e);
329                    self.set_outline(obj);
330                }
331                b"a:gradFill" => {
332                    let mut obj = GradientFill::default();
333                    obj.set_attributes(reader, e);
334                    self.set_gradient_fill(obj);
335                }
336                b"a:effectLst" => {
337                    let mut effect_list = EffectList::default();
338                    effect_list.set_attributes(reader, e, false);
339                    self.set_effect_list(effect_list);
340                }
341                _ => (),
342                }
343            },
344            Event::Empty(ref e) => {
345                match e.name().into_inner() {
346                b"a:latin" => {
347                    let mut obj = TextFontType::default();
348                    obj.set_attributes(reader, e, true);
349                    self.set_latin_font(obj);
350                }
351                b"a:ea" => {
352                    let mut obj = TextFontType::default();
353                    obj.set_attributes(reader, e, true);
354                    self.set_east_asian_font(obj);
355                }
356                b"a:cs" => {
357                    let mut obj = TextFontType::default();
358                    obj.set_attributes(reader, e, true);
359                    self.set_complex_script_font(obj);
360                }
361                b"a:noFill" => {
362                    let mut obj = NoFill::default();
363                    obj.set_attributes(reader, e, true);
364                    self.set_no_fill(obj);
365                }
366                b"a:effectLst" => {
367                    let mut obj = EffectList::default();
368                    obj.set_attributes(reader, e, true);
369                    self.set_effect_list(obj);
370                }
371                _ => (),
372                }
373            },
374            Event::End(ref e) => {
375                match e.name().into_inner() {
376                b"a:rPr" => return,
377                b"a:endParaRPr" => return,
378                b"a:defRPr" => return,
379                _ => (),
380                }
381            },
382            Event::Eof => panic!(
383                "Error: Could not find {} end element",
384                "a:rPr, a:endParaRPr, a:defRPr"
385            )
386        );
387    }
388
389    #[inline]
390    pub(crate) fn write_to_rpr(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
391        self.write_to(writer, "a:rPr")
392    }
393
394    #[inline]
395    pub(crate) fn write_to_end_para_rpr(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
396        self.write_to(writer, "a:endParaRPr")
397    }
398
399    #[inline]
400    pub(crate) fn write_to_def_rpr(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
401        self.write_to(writer, "a:defRPr")
402    }
403
404    fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>, tag_name: &str) {
405        let mut attributes: Vec<(&str, &str)> = Vec::new();
406        if self.kumimoji.has_value() {
407            attributes.push(("kumimoji", self.kumimoji.get_value_str()))
408        }
409        if self.language.has_value() {
410            attributes.push(("lang", self.language.get_value_str()))
411        }
412        if self.alternative_language.has_value() {
413            attributes.push(("altLang", self.alternative_language.get_value_str()))
414        }
415        if self.sz.has_value() {
416            attributes.push(("sz", self.sz.get_value_str()))
417        }
418        if self.bold.has_value() {
419            attributes.push(("b", self.bold.get_value_str()))
420        }
421        if self.italic.has_value() {
422            attributes.push(("i", self.italic.get_value_str()))
423        }
424        if self.capital.has_value() {
425            attributes.push(("cap", self.capital.get_value_string()));
426        }
427        let spc = self.spacing.get_value_string();
428        if self.spacing.has_value() {
429            attributes.push(("spc", &spc));
430        }
431        if self.strike.has_value() {
432            attributes.push(("strike", self.strike.get_value_str()));
433        }
434        if self.solid_fill.is_some()
435            || self.outline.is_some()
436            || self.latin_font.is_some()
437            || self.east_asian_font.is_some()
438            || self.gradient_fill.is_some()
439            || self.effect_list.is_some()
440        {
441            write_start_tag(writer, tag_name, attributes, false);
442
443            // a:solidFill
444            if let Some(v) = &self.solid_fill {
445                v.write_to(writer);
446            }
447
448            // a:ln
449            if let Some(v) = &self.outline {
450                v.write_to(writer);
451            }
452
453            // a:latin
454            if let Some(v) = &self.latin_font {
455                v.write_to_latin(writer);
456            }
457
458            // a:ea
459            if let Some(v) = &self.east_asian_font {
460                v.write_to_ea(writer);
461            }
462
463            // a:cs
464            if let Some(v) = &self.complex_script_font {
465                v.write_to_cs(writer);
466            }
467
468            // a:gradFill
469            if let Some(v) = &self.gradient_fill {
470                v.write_to(writer);
471            }
472
473            // a:noFill
474            if let Some(v) = &self.no_fill {
475                v.write_to(writer);
476            }
477
478            // a:effectLst
479            if let Some(v) = &self.effect_list {
480                v.write_to(writer);
481            }
482
483            write_end_tag(writer, tag_name);
484        } else {
485            write_start_tag(writer, tag_name, attributes, true);
486        }
487    }
488}