Skip to main content

umya_spreadsheet/structs/drawing/
outline.rs

1// a:ln
2use std::io::Cursor;
3
4use quick_xml::{
5    Reader,
6    Writer,
7    events::{
8        BytesStart,
9        Event,
10    },
11};
12
13use super::{
14    Bevel,
15    GradientFill,
16    Miter,
17    NoFill,
18    PenAlignmentValues,
19    PresetDash,
20    Round,
21    SolidFill,
22    TailEnd,
23};
24use crate::{
25    StringValue,
26    drawing::SystemColor,
27    reader::driver::{
28        get_attribute,
29        set_string_from_xml,
30        xml_read_loop,
31    },
32    structs::{
33        EnumValue,
34        UInt32Value,
35    },
36    writer::driver::{
37        write_end_tag,
38        write_start_tag,
39    },
40};
41
42#[derive(Clone, Default, Debug)]
43pub struct Outline {
44    width:              UInt32Value,
45    cap_type:           StringValue,
46    compound_line_type: StringValue,
47    solid_fill:         Option<Box<SolidFill>>,
48    gradient_fill:      Option<Box<GradientFill>>,
49    tail_end:           Option<Box<TailEnd>>,
50    no_fill:            Option<NoFill>,
51    bevel:              Option<Box<Bevel>>,
52    preset_dash:        Option<PresetDash>,
53    miter:              Option<Miter>,
54    round:              Option<Round>,
55    alignment:          EnumValue<PenAlignmentValues>,
56    system_color:       Option<Box<SystemColor>>,
57}
58
59impl Outline {
60    #[inline]
61    #[must_use]
62    pub fn width(&self) -> u32 {
63        self.width.value()
64    }
65
66    #[inline]
67    #[must_use]
68    #[deprecated(since = "3.0.0", note = "Use width()")]
69    pub fn get_width(&self) -> u32 {
70        self.width()
71    }
72
73    #[inline]
74    pub fn set_width(&mut self, value: u32) -> &mut Self {
75        self.width.set_value(value);
76        self
77    }
78
79    #[inline]
80    #[must_use]
81    pub fn cap_type(&self) -> Option<&str> {
82        self.cap_type.value()
83    }
84
85    #[inline]
86    #[must_use]
87    #[deprecated(since = "3.0.0", note = "Use cap_type()")]
88    pub fn get_cap_type(&self) -> Option<&str> {
89        self.cap_type()
90    }
91
92    #[inline]
93    pub fn set_cap_type<S: Into<String>>(&mut self, value: S) -> &mut Self {
94        self.cap_type.set_value(value);
95        self
96    }
97
98    #[inline]
99    #[must_use]
100    pub fn compound_line_type(&self) -> Option<&str> {
101        self.compound_line_type.value()
102    }
103
104    #[inline]
105    #[must_use]
106    #[deprecated(since = "3.0.0", note = "Use compound_line_type()")]
107    pub fn get_compound_line_type(&self) -> Option<&str> {
108        self.compound_line_type()
109    }
110
111    #[inline]
112    pub fn set_compound_line_type<S: Into<String>>(&mut self, value: S) -> &mut Self {
113        self.compound_line_type.set_value(value);
114        self
115    }
116
117    #[inline]
118    #[must_use]
119    pub fn solid_fill(&self) -> Option<&SolidFill> {
120        self.solid_fill.as_deref()
121    }
122
123    #[inline]
124    #[must_use]
125    #[deprecated(since = "3.0.0", note = "Use solid_fill()")]
126    pub fn get_solid_fill(&self) -> Option<&SolidFill> {
127        self.solid_fill()
128    }
129
130    #[inline]
131    pub fn solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
132        self.solid_fill.as_deref_mut()
133    }
134
135    #[inline]
136    #[deprecated(since = "3.0.0", note = "Use solid_fill_mut()")]
137    pub fn get_solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
138        self.solid_fill_mut()
139    }
140
141    #[inline]
142    pub fn set_solid_fill(&mut self, value: SolidFill) -> &mut Self {
143        self.solid_fill = Some(Box::new(value));
144        self
145    }
146
147    #[inline]
148    #[must_use]
149    pub fn gradient_fill(&self) -> Option<&GradientFill> {
150        self.gradient_fill.as_deref()
151    }
152
153    #[inline]
154    #[must_use]
155    #[deprecated(since = "3.0.0", note = "Use gradient_fill()")]
156    pub fn get_gradient_fill(&self) -> Option<&GradientFill> {
157        self.gradient_fill()
158    }
159
160    #[inline]
161    pub fn gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
162        self.gradient_fill.as_deref_mut()
163    }
164
165    #[inline]
166    #[deprecated(since = "3.0.0", note = "Use gradient_fill_mut()")]
167    pub fn get_gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
168        self.gradient_fill_mut()
169    }
170
171    #[inline]
172    pub fn set_gradient_fill(&mut self, value: GradientFill) -> &mut Self {
173        self.gradient_fill = Some(Box::new(value));
174        self
175    }
176
177    #[inline]
178    #[must_use]
179    pub fn tail_end(&self) -> Option<&TailEnd> {
180        self.tail_end.as_deref()
181    }
182
183    #[inline]
184    #[must_use]
185    #[deprecated(since = "3.0.0", note = "Use tail_end()")]
186    pub fn get_tail_end(&self) -> Option<&TailEnd> {
187        self.tail_end()
188    }
189
190    #[inline]
191    pub fn tail_end_mut(&mut self) -> Option<&mut TailEnd> {
192        self.tail_end.as_deref_mut()
193    }
194
195    #[inline]
196    #[deprecated(since = "3.0.0", note = "Use tail_end_mut()")]
197    pub fn get_tail_end_mut(&mut self) -> Option<&mut TailEnd> {
198        self.tail_end_mut()
199    }
200
201    #[inline]
202    pub fn set_tail_end(&mut self, value: TailEnd) -> &mut Self {
203        self.tail_end = Some(Box::new(value));
204        self
205    }
206
207    #[inline]
208    #[must_use]
209    pub fn no_fill(&self) -> Option<&NoFill> {
210        self.no_fill.as_ref()
211    }
212
213    #[inline]
214    #[must_use]
215    #[deprecated(since = "3.0.0", note = "Use no_fill()")]
216    pub fn get_no_fill(&self) -> Option<&NoFill> {
217        self.no_fill()
218    }
219
220    #[inline]
221    pub fn no_fill_mut(&mut self) -> Option<&mut NoFill> {
222        self.no_fill.as_mut()
223    }
224
225    #[inline]
226    #[deprecated(since = "3.0.0", note = "Use no_fill_mut()")]
227    pub fn get_no_fill_mut(&mut self) -> Option<&mut NoFill> {
228        self.no_fill_mut()
229    }
230
231    #[inline]
232    pub fn set_no_fill(&mut self, value: NoFill) -> &mut Self {
233        self.no_fill = Some(value);
234        self
235    }
236
237    #[inline]
238    #[must_use]
239    pub fn bevel(&self) -> Option<&Bevel> {
240        self.bevel.as_deref()
241    }
242
243    #[inline]
244    #[must_use]
245    #[deprecated(since = "3.0.0", note = "Use bevel()")]
246    pub fn get_bevel(&self) -> Option<&Bevel> {
247        self.bevel()
248    }
249
250    #[inline]
251    pub fn bevel_mut(&mut self) -> Option<&mut Bevel> {
252        self.bevel.as_deref_mut()
253    }
254
255    #[inline]
256    #[deprecated(since = "3.0.0", note = "Use bevel_mut()")]
257    pub fn get_bevel_mut(&mut self) -> Option<&mut Bevel> {
258        self.bevel_mut()
259    }
260
261    #[inline]
262    pub fn set_bevel(&mut self, value: Bevel) -> &mut Self {
263        self.bevel = Some(Box::new(value));
264        self
265    }
266
267    #[inline]
268    #[must_use]
269    pub fn preset_dash(&self) -> Option<&PresetDash> {
270        self.preset_dash.as_ref()
271    }
272
273    #[inline]
274    #[must_use]
275    #[deprecated(since = "3.0.0", note = "Use preset_dash()")]
276    pub fn get_preset_dash(&self) -> Option<&PresetDash> {
277        self.preset_dash()
278    }
279
280    #[inline]
281    pub fn preset_dash_mut(&mut self) -> Option<&mut PresetDash> {
282        self.preset_dash.as_mut()
283    }
284
285    #[inline]
286    #[deprecated(since = "3.0.0", note = "Use preset_dash_mut()")]
287    pub fn get_preset_dash_mut(&mut self) -> Option<&mut PresetDash> {
288        self.preset_dash_mut()
289    }
290
291    #[inline]
292    pub fn set_preset_dash(&mut self, value: PresetDash) -> &mut Self {
293        self.preset_dash = Some(value);
294        self
295    }
296
297    #[inline]
298    #[must_use]
299    pub fn miter(&self) -> Option<&Miter> {
300        self.miter.as_ref()
301    }
302
303    #[inline]
304    #[must_use]
305    #[deprecated(since = "3.0.0", note = "Use miter()")]
306    pub fn get_miter(&self) -> Option<&Miter> {
307        self.miter()
308    }
309
310    #[inline]
311    pub fn miter_mut(&mut self) -> Option<&mut Miter> {
312        self.miter.as_mut()
313    }
314
315    #[inline]
316    #[deprecated(since = "3.0.0", note = "Use miter_mut()")]
317    pub fn get_miter_mut(&mut self) -> Option<&mut Miter> {
318        self.miter_mut()
319    }
320
321    #[inline]
322    pub fn set_miter(&mut self, value: Miter) -> &mut Self {
323        self.miter = Some(value);
324        self
325    }
326
327    #[inline]
328    #[must_use]
329    pub fn round(&self) -> Option<&Round> {
330        self.round.as_ref()
331    }
332
333    #[inline]
334    #[must_use]
335    #[deprecated(since = "3.0.0", note = "Use round()")]
336    pub fn get_round(&self) -> Option<&Round> {
337        self.round()
338    }
339
340    #[inline]
341    pub fn round_mut(&mut self) -> Option<&mut Round> {
342        self.round.as_mut()
343    }
344
345    #[inline]
346    #[deprecated(since = "3.0.0", note = "Use round_mut()")]
347    pub fn get_round_mut(&mut self) -> Option<&mut Round> {
348        self.round_mut()
349    }
350
351    #[inline]
352    pub fn set_round(&mut self, value: Round) -> &mut Self {
353        self.round = Some(value);
354        self
355    }
356
357    #[inline]
358    #[must_use]
359    pub fn alignment(&self) -> &PenAlignmentValues {
360        self.alignment.value()
361    }
362
363    #[inline]
364    #[must_use]
365    #[deprecated(since = "3.0.0", note = "Use alignment()")]
366    pub fn get_alignment(&self) -> &PenAlignmentValues {
367        self.alignment()
368    }
369
370    #[inline]
371    pub fn set_alignment(&mut self, value: PenAlignmentValues) {
372        self.alignment.set_value(value);
373    }
374
375    #[inline]
376    #[must_use]
377    pub fn system_color(&self) -> Option<&SystemColor> {
378        self.system_color.as_deref()
379    }
380
381    #[inline]
382    #[must_use]
383    #[deprecated(since = "3.0.0", note = "Use system_color()")]
384    pub fn get_system_color(&self) -> Option<&SystemColor> {
385        self.system_color()
386    }
387
388    #[inline]
389    pub fn system_color_mut(&mut self) -> Option<&mut SystemColor> {
390        self.system_color.as_deref_mut()
391    }
392
393    #[inline]
394    #[deprecated(since = "3.0.0", note = "Use system_color_mut()")]
395    pub fn get_system_color_mut(&mut self) -> Option<&mut SystemColor> {
396        self.system_color_mut()
397    }
398
399    #[inline]
400    pub fn set_system_color(&mut self, value: SystemColor) {
401        self.system_color = Some(Box::new(value));
402    }
403
404    pub(crate) fn set_attributes<R: std::io::BufRead>(
405        &mut self,
406        reader: &mut Reader<R>,
407        e: &BytesStart,
408    ) {
409        if let Some(v) = get_attribute(e, b"w") {
410            self.set_width(v.parse::<u32>().unwrap());
411        }
412
413        if let Some(v) = get_attribute(e, b"cap") {
414            self.set_cap_type(v);
415        }
416
417        if let Some(v) = get_attribute(e, b"cmpd") {
418            self.set_compound_line_type(v);
419        }
420
421        set_string_from_xml!(self, e, alignment, "algn");
422
423        xml_read_loop!(
424            reader,
425            ref n @ (Event::Empty(ref e) | Event::Start(ref e)) => {
426                let is_empty = matches!(n, Event::Empty(_));
427                match e.name().into_inner() {
428                    b"a:solidFill" => {
429                        let mut solid_fill = SolidFill::default();
430                        solid_fill.set_attributes(reader, e);
431                        self.set_solid_fill(solid_fill);
432                    }
433                    b"a:gradFill" => {
434                        let mut obj = GradientFill::default();
435                        obj.set_attributes(reader, e);
436                        self.set_gradient_fill(obj);
437                    }
438                    b"a:tailEnd" => {
439                        let mut obj = TailEnd::default();
440                        obj.set_attributes(reader, e, is_empty);
441                        self.set_tail_end(obj);
442                    }
443                    b"a:noFill" => {
444                        let obj = NoFill::default();
445                        NoFill::set_attributes(reader, e, is_empty);
446                        self.set_no_fill(obj);
447                    }
448                    b"a:bevel" => {
449                        let obj = Bevel::default();
450                        Bevel::set_attributes(reader, e, is_empty);
451                        self.set_bevel(obj);
452                    }
453                    b"a:miter" => {
454                        let mut obj = Miter::default();
455                        obj.set_attributes(reader, e, is_empty);
456                        self.set_miter(obj);
457                    }
458                    b"a:prstDash" => {
459                        let mut obj = PresetDash::default();
460                        obj.set_attributes(reader, e, is_empty);
461                        self.set_preset_dash(obj);
462                    }
463                    b"a:round" => {
464                        let obj = Round::default();
465                        Round::set_attributes(reader, e, is_empty);
466                        self.set_round(obj);
467                    }
468                    b"a:sysClr" => {
469                        let mut obj = SystemColor::default();
470                        obj.set_attributes(reader, e, is_empty);
471                        self.set_system_color(obj);
472                    }
473                    _ => (),
474                }
475            },
476            Event::End(ref e) => {
477                if  e.name().into_inner() == b"a:ln" {
478                    return;
479                }
480            },
481            Event::Eof => panic!("Error: Could not find {} end element", "a:ln")
482        );
483    }
484
485    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
486        // a:ln
487        let mut attributes: crate::structs::AttrCollection = Vec::new();
488        let width = self.width.value_string();
489        if self.width.has_value() {
490            attributes.push(("w", &width).into());
491        }
492        if let Some(v) = self.cap_type.value() {
493            attributes.push(("cap", v).into());
494        }
495        if let Some(v) = self.compound_line_type.value() {
496            attributes.push(("cmpd", v).into());
497        }
498        if self.alignment.has_value() {
499            attributes.push(("algn", (self.alignment.value_string())).into());
500        }
501        write_start_tag(writer, "a:ln", attributes, false);
502
503        // a:solidFill
504        if let Some(v) = &self.solid_fill {
505            v.write_to(writer);
506        }
507
508        // a:gradFill
509        if let Some(v) = &self.gradient_fill {
510            v.write_to(writer);
511        }
512
513        // a:round
514        if self.round.is_some() {
515            Round::write_to(writer);
516        }
517
518        // a:tailEnd
519        if let Some(v) = &self.tail_end {
520            v.write_to(writer);
521        }
522
523        // a:noFill
524        if self.no_fill.is_some() {
525            NoFill::write_to(writer);
526        }
527
528        // a:bevel
529        if self.bevel.is_some() {
530            Bevel::write_to(writer);
531        }
532
533        // a:prstDash
534        if let Some(v) = &self.preset_dash {
535            v.write_to(writer);
536        }
537
538        // a:miter
539        if let Some(v) = &self.miter {
540            v.write_to(writer);
541        }
542
543        write_end_tag(writer, "a:ln");
544    }
545}