umya_spreadsheet/structs/drawing/
run_properties.rs1use std::io::Cursor;
2
3use quick_xml::{
4 Reader,
5 Writer,
6 events::{
7 BytesStart,
8 Event,
9 },
10};
11
12use super::{
13 super::{
14 EnumValue,
15 Int32Value,
16 },
17 EffectList,
18 GradientFill,
19 NoFill,
20 Outline,
21 SolidFill,
22 TextCapsValues,
23 TextFontType,
24};
25use crate::{
26 reader::driver::{
27 get_attribute,
28 xml_read_loop,
29 },
30 structs::StringValue,
31 writer::driver::{
32 write_end_tag,
33 write_start_tag,
34 },
35};
36
37#[derive(Clone, Default, Debug)]
38pub struct RunProperties {
39 text: Box<str>,
40 kumimoji: StringValue,
41 language: StringValue,
42 alternative_language: StringValue,
43 bold: StringValue,
44 sz: StringValue,
45 italic: StringValue,
46 capital: EnumValue<TextCapsValues>,
47 spacing: Int32Value,
48 strike: StringValue,
49 outline: Option<Box<Outline>>,
50 solid_fill: Option<Box<SolidFill>>,
51 latin_font: Option<Box<TextFontType>>,
52 east_asian_font: Option<Box<TextFontType>>,
53 complex_script_font: Option<Box<TextFontType>>,
54 gradient_fill: Option<Box<GradientFill>>,
55 no_fill: Option<NoFill>,
56 effect_list: Option<Box<EffectList>>,
57}
58
59impl RunProperties {
60 #[inline]
61 #[must_use]
62 pub fn text(&self) -> &str {
63 &self.text
64 }
65
66 #[inline]
67 #[must_use]
68 #[deprecated(since = "3.0.0", note = "Use text()")]
69 pub fn get_text(&self) -> &str {
70 self.text()
71 }
72
73 #[inline]
74 pub fn set_text<S: Into<String>>(&mut self, value: S) -> &mut Self {
75 self.text = value.into().into_boxed_str();
76 self
77 }
78
79 #[inline]
80 #[must_use]
81 pub fn kumimoji(&self) -> &str {
82 self.kumimoji.value_str()
83 }
84
85 #[inline]
86 #[must_use]
87 #[deprecated(since = "3.0.0", note = "Use kumimoji()")]
88 pub fn get_kumimoji(&self) -> &str {
89 self.kumimoji()
90 }
91
92 #[inline]
93 pub fn set_kumimoji<S: Into<String>>(&mut self, value: S) -> &mut Self {
94 self.kumimoji.set_value_string(value.into());
95 self
96 }
97
98 #[inline]
99 #[must_use]
100 pub fn language(&self) -> &str {
101 self.language.value_str()
102 }
103
104 #[inline]
105 #[must_use]
106 #[deprecated(since = "3.0.0", note = "Use language()")]
107 pub fn get_language(&self) -> &str {
108 self.language()
109 }
110
111 #[inline]
112 pub fn set_language<S: Into<String>>(&mut self, value: S) -> &mut Self {
113 self.language.set_value_string(value.into());
114 self
115 }
116
117 #[inline]
118 #[must_use]
119 pub fn alternative_language(&self) -> &str {
120 self.alternative_language.value_str()
121 }
122
123 #[inline]
124 #[must_use]
125 #[deprecated(since = "3.0.0", note = "Use alternative_language()")]
126 pub fn get_alternative_language(&self) -> &str {
127 self.alternative_language()
128 }
129
130 #[inline]
131 pub fn set_alternative_language<S: Into<String>>(&mut self, value: S) -> &mut Self {
132 self.alternative_language.set_value_string(value.into());
133 self
134 }
135
136 #[inline]
137 #[must_use]
138 pub fn bold(&self) -> &str {
139 self.bold.value_str()
140 }
141
142 #[inline]
143 #[must_use]
144 #[deprecated(since = "3.0.0", note = "Use bold()")]
145 pub fn get_bold(&self) -> &str {
146 self.bold()
147 }
148
149 #[inline]
150 pub fn set_bold<S: Into<String>>(&mut self, value: S) -> &mut Self {
151 self.bold.set_value_string(value.into());
152 self
153 }
154
155 #[inline]
156 #[must_use]
157 pub fn sz(&self) -> &str {
158 self.sz.value_str()
159 }
160
161 #[inline]
162 #[must_use]
163 #[deprecated(since = "3.0.0", note = "Use sz()")]
164 pub fn get_sz(&self) -> &str {
165 self.sz()
166 }
167
168 #[inline]
169 pub fn set_sz<S: Into<String>>(&mut self, value: S) -> &mut Self {
170 self.sz.set_value_string(value.into());
171 self
172 }
173
174 #[inline]
175 #[must_use]
176 pub fn italic(&self) -> &str {
177 self.italic.value_str()
178 }
179
180 #[inline]
181 #[must_use]
182 #[deprecated(since = "3.0.0", note = "Use italic()")]
183 pub fn get_italic(&self) -> &str {
184 self.italic()
185 }
186
187 #[inline]
188 pub fn set_italic<S: Into<String>>(&mut self, value: S) -> &mut Self {
189 self.italic.set_value_string(value.into());
190 self
191 }
192
193 #[inline]
194 #[must_use]
195 pub fn capital(&self) -> &TextCapsValues {
196 self.capital.value()
197 }
198
199 #[inline]
200 #[must_use]
201 #[deprecated(since = "3.0.0", note = "Use capital()")]
202 pub fn get_capital(&self) -> &TextCapsValues {
203 self.capital()
204 }
205
206 #[inline]
207 pub fn set_capital(&mut self, value: TextCapsValues) -> &mut Self {
208 self.capital.set_value(value);
209 self
210 }
211
212 #[inline]
213 #[must_use]
214 pub fn spacing(&self) -> i32 {
215 self.spacing.value()
216 }
217
218 #[inline]
219 #[must_use]
220 #[deprecated(since = "3.0.0", note = "Use spacing()")]
221 pub fn get_spacing(&self) -> i32 {
222 self.spacing()
223 }
224
225 #[inline]
226 pub fn set_spacing(&mut self, value: i32) -> &mut Self {
227 self.spacing.set_value(value);
228 self
229 }
230
231 #[inline]
232 #[must_use]
233 pub fn strike(&self) -> &str {
234 self.strike.value_str()
235 }
236
237 #[inline]
238 #[must_use]
239 #[deprecated(since = "3.0.0", note = "Use strike()")]
240 pub fn get_strike(&self) -> &str {
241 self.strike()
242 }
243
244 #[inline]
245 pub fn set_strike<S: Into<String>>(&mut self, value: S) -> &mut Self {
246 self.strike.set_value_string(value.into());
247 self
248 }
249
250 #[inline]
251 #[must_use]
252 pub fn solid_fill(&self) -> Option<&SolidFill> {
253 self.solid_fill.as_deref()
254 }
255
256 #[inline]
257 #[must_use]
258 #[deprecated(since = "3.0.0", note = "Use solid_fill()")]
259 pub fn get_solid_fill(&self) -> Option<&SolidFill> {
260 self.solid_fill()
261 }
262
263 #[inline]
264 pub fn solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
265 self.solid_fill.as_deref_mut()
266 }
267
268 #[inline]
269 #[deprecated(since = "3.0.0", note = "Use solid_fill_mut()")]
270 pub fn get_solid_fill_mut(&mut self) -> Option<&mut SolidFill> {
271 self.solid_fill_mut()
272 }
273
274 #[inline]
275 pub fn set_solid_fill(&mut self, value: SolidFill) -> &mut Self {
276 self.solid_fill = Some(Box::new(value));
277 self
278 }
279
280 #[inline]
281 #[must_use]
282 pub fn outline(&self) -> Option<&Outline> {
283 self.outline.as_deref()
284 }
285
286 #[inline]
287 #[must_use]
288 #[deprecated(since = "3.0.0", note = "Use outline()")]
289 pub fn get_outline(&self) -> Option<&Outline> {
290 self.outline()
291 }
292
293 #[inline]
294 pub fn outline_mut(&mut self) -> Option<&mut Outline> {
295 self.outline.as_deref_mut()
296 }
297
298 #[inline]
299 #[deprecated(since = "3.0.0", note = "Use outline_mut()")]
300 pub fn get_outline_mut(&mut self) -> Option<&mut Outline> {
301 self.outline_mut()
302 }
303
304 #[inline]
305 pub fn set_outline(&mut self, value: Outline) -> &mut Self {
306 self.outline = Some(Box::new(value));
307 self
308 }
309
310 #[inline]
311 #[must_use]
312 pub fn latin_font(&self) -> Option<&TextFontType> {
313 self.latin_font.as_deref()
314 }
315
316 #[inline]
317 #[must_use]
318 #[deprecated(since = "3.0.0", note = "Use latin_font()")]
319 pub fn get_latin_font(&self) -> Option<&TextFontType> {
320 self.latin_font()
321 }
322
323 #[inline]
324 pub fn latin_font_mut(&mut self) -> Option<&mut TextFontType> {
325 self.latin_font.as_deref_mut()
326 }
327
328 #[inline]
329 #[deprecated(since = "3.0.0", note = "Use latin_font_mut()")]
330 pub fn get_latin_font_mut(&mut self) -> Option<&mut TextFontType> {
331 self.latin_font_mut()
332 }
333
334 #[inline]
335 pub fn set_latin_font(&mut self, value: TextFontType) -> &mut Self {
336 self.latin_font = Some(Box::new(value));
337 self
338 }
339
340 #[inline]
341 #[must_use]
342 pub fn east_asian_font(&self) -> Option<&TextFontType> {
343 self.east_asian_font.as_deref()
344 }
345
346 #[inline]
347 #[must_use]
348 #[deprecated(since = "3.0.0", note = "Use east_asian_font()")]
349 pub fn get_east_asian_font(&self) -> Option<&TextFontType> {
350 self.east_asian_font()
351 }
352
353 #[inline]
354 pub fn east_asian_font_mut(&mut self) -> Option<&mut TextFontType> {
355 self.east_asian_font.as_deref_mut()
356 }
357
358 #[inline]
359 #[deprecated(since = "3.0.0", note = "Use east_asian_font_mut()")]
360 pub fn get_east_asian_font_mut(&mut self) -> Option<&mut TextFontType> {
361 self.east_asian_font_mut()
362 }
363
364 #[inline]
365 pub fn set_east_asian_font(&mut self, value: TextFontType) -> &mut Self {
366 self.east_asian_font = Some(Box::new(value));
367 self
368 }
369
370 #[inline]
371 #[must_use]
372 pub fn complex_script_font(&self) -> Option<&TextFontType> {
373 self.complex_script_font.as_deref()
374 }
375
376 #[inline]
377 #[must_use]
378 #[deprecated(since = "3.0.0", note = "Use complex_script_font()")]
379 pub fn get_complex_script_font(&self) -> Option<&TextFontType> {
380 self.complex_script_font()
381 }
382
383 #[inline]
384 pub fn complex_script_font_mut(&mut self) -> Option<&mut TextFontType> {
385 self.complex_script_font.as_deref_mut()
386 }
387
388 #[inline]
389 #[deprecated(since = "3.0.0", note = "Use complex_script_font_mut()")]
390 pub fn get_complex_script_font_mut(&mut self) -> Option<&mut TextFontType> {
391 self.complex_script_font_mut()
392 }
393
394 #[inline]
395 pub fn set_complex_script_font(&mut self, value: TextFontType) -> &mut Self {
396 self.complex_script_font = Some(Box::new(value));
397 self
398 }
399
400 #[inline]
401 #[must_use]
402 pub fn gradient_fill(&self) -> Option<&GradientFill> {
403 self.gradient_fill.as_deref()
404 }
405
406 #[inline]
407 #[must_use]
408 #[deprecated(since = "3.0.0", note = "Use gradient_fill()")]
409 pub fn get_gradient_fill(&self) -> Option<&GradientFill> {
410 self.gradient_fill()
411 }
412
413 #[inline]
414 pub fn gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
415 self.gradient_fill.as_deref_mut()
416 }
417
418 #[inline]
419 #[deprecated(since = "3.0.0", note = "Use gradient_fill_mut()")]
420 pub fn get_gradient_fill_mut(&mut self) -> Option<&mut GradientFill> {
421 self.gradient_fill_mut()
422 }
423
424 #[inline]
425 pub fn set_gradient_fill(&mut self, value: GradientFill) -> &mut Self {
426 self.gradient_fill = Some(Box::new(value));
427 self
428 }
429
430 #[inline]
431 #[must_use]
432 pub fn no_fill(&self) -> Option<&NoFill> {
433 self.no_fill.as_ref()
434 }
435
436 #[inline]
437 #[must_use]
438 #[deprecated(since = "3.0.0", note = "Use no_fill()")]
439 pub fn get_no_fill(&self) -> Option<&NoFill> {
440 self.no_fill()
441 }
442
443 #[inline]
444 pub fn no_fill_mut(&mut self) -> Option<&mut NoFill> {
445 self.no_fill.as_mut()
446 }
447
448 #[inline]
449 #[deprecated(since = "3.0.0", note = "Use no_fill_mut()")]
450 pub fn get_no_fill_mut(&mut self) -> Option<&mut NoFill> {
451 self.no_fill_mut()
452 }
453
454 #[inline]
455 pub fn set_no_fill(&mut self, value: NoFill) -> &mut Self {
456 self.no_fill = Some(value);
457 self
458 }
459
460 #[inline]
461 #[must_use]
462 pub fn effect_list(&self) -> Option<&EffectList> {
463 self.effect_list.as_deref()
464 }
465
466 #[inline]
467 #[must_use]
468 #[deprecated(since = "3.0.0", note = "Use effect_list()")]
469 pub fn get_effect_list(&self) -> Option<&EffectList> {
470 self.effect_list()
471 }
472
473 #[inline]
474 pub fn effect_list_mut(&mut self) -> Option<&mut EffectList> {
475 self.effect_list.as_deref_mut()
476 }
477
478 #[inline]
479 #[deprecated(since = "3.0.0", note = "Use effect_list_mut()")]
480 pub fn get_effect_list_mut(&mut self) -> Option<&mut EffectList> {
481 self.effect_list_mut()
482 }
483
484 #[inline]
485 pub fn set_effect_list(&mut self, value: EffectList) -> &mut Self {
486 self.effect_list = Some(Box::new(value));
487 self
488 }
489
490 pub(crate) fn set_attributes<R: std::io::BufRead>(
491 &mut self,
492 reader: &mut Reader<R>,
493 e: &BytesStart,
494 empty_flag: bool,
495 ) {
496 if let Some(v) = get_attribute(e, b"kumimoji") {
497 self.set_kumimoji(v);
498 }
499 if let Some(v) = get_attribute(e, b"lang") {
500 self.set_language(v);
501 }
502 if let Some(v) = get_attribute(e, b"altLang") {
503 self.set_alternative_language(v);
504 }
505 if let Some(v) = get_attribute(e, b"b") {
506 self.set_bold(v);
507 }
508 if let Some(v) = get_attribute(e, b"sz") {
509 self.set_sz(v);
510 }
511 if let Some(v) = get_attribute(e, b"strike") {
512 self.set_strike(v);
513 }
514 if let Some(v) = get_attribute(e, b"i") {
515 self.set_italic(v);
516 }
517 if let Some(v) = get_attribute(e, b"cap") {
518 self.capital.set_value_string(v);
519 }
520 if let Some(v) = get_attribute(e, b"spc") {
521 self.spacing.set_value_string(v);
522 }
523
524 if empty_flag {
525 return;
526 }
527
528 xml_read_loop!(
529 reader,
530 Event::Start(ref e) => {
531 match e.name().into_inner() {
532 b"a:solidFill" => {
533 let mut obj = SolidFill::default();
534 obj.set_attributes(reader, e);
535 self.set_solid_fill(obj);
536 }
537 b"a:ln" => {
538 let mut obj = Outline::default();
539 obj.set_attributes(reader, e);
540 self.set_outline(obj);
541 }
542 b"a:gradFill" => {
543 let mut obj = GradientFill::default();
544 obj.set_attributes(reader, e);
545 self.set_gradient_fill(obj);
546 }
547 b"a:effectLst" => {
548 let mut effect_list = EffectList::default();
549 effect_list.set_attributes(reader, e, false);
550 self.set_effect_list(effect_list);
551 }
552 _ => (),
553 }
554 },
555 Event::Empty(ref e) => {
556 match e.name().into_inner() {
557 b"a:latin" => {
558 let mut obj = TextFontType::default();
559 obj.set_attributes(reader, e, true);
560 self.set_latin_font(obj);
561 }
562 b"a:ea" => {
563 let mut obj = TextFontType::default();
564 obj.set_attributes(reader, e, true);
565 self.set_east_asian_font(obj);
566 }
567 b"a:cs" => {
568 let mut obj = TextFontType::default();
569 obj.set_attributes(reader, e, true);
570 self.set_complex_script_font(obj);
571 }
572 b"a:noFill" => {
573 let obj = NoFill::default();
574 NoFill::set_attributes(reader, e, true);
575 self.set_no_fill(obj);
576 }
577 b"a:effectLst" => {
578 let mut obj = EffectList::default();
579 obj.set_attributes(reader, e, true);
580 self.set_effect_list(obj);
581 }
582 _ => (),
583 }
584 },
585 Event::End(ref e) => {
586 match e.name().into_inner() {
587 b"a:rPr" | b"a:endParaRPr" | b"a:defRPr" => return,
588 _ => (),
589 }
590 },
591 Event::Eof => panic!(
592 "Error: Could not find {} end element",
593 "a:rPr, a:endParaRPr, a:defRPr"
594 )
595 );
596 }
597
598 #[inline]
599 pub(crate) fn write_to_rpr(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
600 self.write_to(writer, "a:rPr");
601 }
602
603 #[inline]
604 pub(crate) fn write_to_end_para_rpr(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
605 self.write_to(writer, "a:endParaRPr");
606 }
607
608 #[inline]
609 pub(crate) fn write_to_def_rpr(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
610 self.write_to(writer, "a:defRPr");
611 }
612
613 fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>, tag_name: &str) {
614 let mut attributes: crate::structs::AttrCollection = Vec::new();
615 if self.kumimoji.has_value() {
616 attributes.push(("kumimoji", self.kumimoji.value_str()).into());
617 }
618 if self.language.has_value() {
619 attributes.push(("lang", self.language.value_str()).into());
620 }
621 if self.alternative_language.has_value() {
622 attributes.push(("altLang", self.alternative_language.value_str()).into());
623 }
624 if self.sz.has_value() {
625 attributes.push(("sz", self.sz.value_str()).into());
626 }
627 if self.bold.has_value() {
628 attributes.push(("b", self.bold.value_str()).into());
629 }
630 if self.italic.has_value() {
631 attributes.push(("i", self.italic.value_str()).into());
632 }
633 if self.capital.has_value() {
634 attributes.push(("cap", self.capital.value_string()).into());
635 }
636 let spc = self.spacing.value_string();
637 if self.spacing.has_value() {
638 attributes.push(("spc", &spc).into());
639 }
640 if self.strike.has_value() {
641 attributes.push(("strike", self.strike.value_str()).into());
642 }
643 if self.solid_fill.is_some()
644 || self.outline.is_some()
645 || self.latin_font.is_some()
646 || self.east_asian_font.is_some()
647 || self.gradient_fill.is_some()
648 || self.effect_list.is_some()
649 {
650 write_start_tag(writer, tag_name, attributes, false);
651
652 if let Some(v) = &self.solid_fill {
654 v.write_to(writer);
655 }
656
657 if let Some(v) = &self.outline {
659 v.write_to(writer);
660 }
661
662 if let Some(v) = &self.latin_font {
664 v.write_to_latin(writer);
665 }
666
667 if let Some(v) = &self.east_asian_font {
669 v.write_to_ea(writer);
670 }
671
672 if let Some(v) = &self.complex_script_font {
674 v.write_to_cs(writer);
675 }
676
677 if let Some(v) = &self.gradient_fill {
679 v.write_to(writer);
680 }
681
682 if self.no_fill.is_some() {
684 NoFill::write_to(writer);
685 }
686
687 if let Some(v) = &self.effect_list {
689 v.write_to(writer);
690 }
691
692 write_end_tag(writer, tag_name);
693 } else {
694 write_start_tag(writer, tag_name, attributes, true);
695 }
696 }
697}