umya_spreadsheet/structs/drawing/
run_properties.rs1use 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 if let Some(v) = &self.solid_fill {
445 v.write_to(writer);
446 }
447
448 if let Some(v) = &self.outline {
450 v.write_to(writer);
451 }
452
453 if let Some(v) = &self.latin_font {
455 v.write_to_latin(writer);
456 }
457
458 if let Some(v) = &self.east_asian_font {
460 v.write_to_ea(writer);
461 }
462
463 if let Some(v) = &self.complex_script_font {
465 v.write_to_cs(writer);
466 }
467
468 if let Some(v) = &self.gradient_fill {
470 v.write_to(writer);
471 }
472
473 if let Some(v) = &self.no_fill {
475 v.write_to(writer);
476 }
477
478 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}