1use super::*;
2
3pub struct Attributes<'a> {
9 dict: Dict<'a>,
10}
11
12writer!(Attributes: |obj| Self { dict: obj.dict() });
13
14impl<'a> Attributes<'a> {
15 pub fn owner(&mut self, owner: AttributeOwner) -> &mut Self {
19 self.pair(Name(b"O"), owner.to_name());
20 self
21 }
22
23 pub fn user(&mut self) -> TypedArray<'_, UserProperty> {
26 self.pair(Name(b"O"), AttributeOwner::User.to_name());
27 self.insert(Name(b"P")).array().typed()
28 }
29
30 pub fn layout(self) -> LayoutAttributes<'a> {
32 LayoutAttributes::start_with_dict(self.dict)
33 }
34
35 pub fn list(self) -> ListAttributes<'a> {
37 ListAttributes::start_with_dict(self.dict)
38 }
39
40 pub fn field(self) -> FieldAttributes<'a> {
43 FieldAttributes::start_with_dict(self.dict)
44 }
45
46 pub fn table(self) -> TableAttributes<'a> {
48 TableAttributes::start_with_dict(self.dict)
49 }
50}
51
52deref!('a, Attributes<'a> => Dict<'a>, dict);
53
54pub struct UserProperty<'a> {
58 dict: Dict<'a>,
59}
60
61writer!(UserProperty: |obj| Self { dict: obj.dict() });
62
63impl UserProperty<'_> {
64 pub fn name(&mut self, name: TextStr) -> &mut Self {
66 self.dict.pair(Name(b"N"), name);
67 self
68 }
69
70 pub fn value(&mut self) -> Obj<'_> {
72 self.dict.insert(Name(b"V"))
73 }
74
75 pub fn format(&mut self, format: TextStr) -> &mut Self {
77 self.dict.pair(Name(b"F"), format);
78 self
79 }
80
81 pub fn hidden(&mut self, hide: bool) -> &mut Self {
83 self.dict.pair(Name(b"H"), hide);
84 self
85 }
86}
87
88deref!('a, UserProperty<'a> => Dict<'a>, dict);
89
90pub struct LayoutAttributes<'a> {
94 dict: Dict<'a>,
95}
96
97writer!(LayoutAttributes: |obj| Self::start_with_dict(obj.dict()));
98
99impl<'a> LayoutAttributes<'a> {
101 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
102 dict.pair(Name(b"O"), AttributeOwner::Layout.to_name());
103 Self { dict }
104 }
105
106 pub fn placement(&mut self, placement: Placement) -> &mut Self {
108 self.dict.pair(Name(b"Placement"), placement.to_name());
109 self
110 }
111
112 pub fn writing_mode(&mut self, mode: WritingMode) -> &mut Self {
114 self.dict.pair(Name(b"WritingMode"), mode.to_name());
115 self
116 }
117
118 pub fn background_color(&mut self, color: [f32; 3]) -> &mut Self {
121 self.dict
122 .insert(Name(b"BackgroundColor"))
123 .array()
124 .typed()
125 .items(color);
126 self
127 }
128
129 pub fn border_color(&mut self, color: [f32; 3]) -> &mut Self {
131 self.dict.insert(Name(b"BorderColor")).array().typed().items(color);
132 self
133 }
134
135 pub fn border_style(&mut self, style: [LayoutBorderStyle; 4]) -> &mut Self {
137 self.dict
138 .insert(Name(b"BorderStyle"))
139 .array()
140 .typed()
141 .items(style.into_iter().map(LayoutBorderStyle::to_name));
142 self
143 }
144
145 pub fn border_thickness(&mut self, thickness: [f32; 4]) -> &mut Self {
147 self.dict
148 .insert(Name(b"BorderThickness"))
149 .array()
150 .typed()
151 .items(thickness);
152 self
153 }
154
155 pub fn padding(&mut self, padding: [f32; 4]) -> &mut Self {
157 self.dict.insert(Name(b"Padding")).array().typed().items(padding);
158 self
159 }
160
161 pub fn color(&mut self, color: [f32; 3]) -> &mut Self {
163 self.dict.insert(Name(b"Color")).array().typed().items(color);
164 self
165 }
166}
167
168#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
170pub enum Placement {
171 Block,
173 Inline,
175 Before,
178 Start,
181 End,
184}
185
186impl Placement {
187 pub(crate) fn to_name(self) -> Name<'static> {
188 match self {
189 Self::Block => Name(b"Block"),
190 Self::Inline => Name(b"Inline"),
191 Self::Before => Name(b"Before"),
192 Self::Start => Name(b"Start"),
193 Self::End => Name(b"End"),
194 }
195 }
196}
197
198#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
200pub enum WritingMode {
201 LtrTtb,
203 RtlTtb,
205 TtbRtl,
207}
208
209impl WritingMode {
210 pub(crate) fn to_name(self) -> Name<'static> {
211 match self {
212 Self::LtrTtb => Name(b"LrTb"),
213 Self::RtlTtb => Name(b"RlTb"),
214 Self::TtbRtl => Name(b"TbRl"),
215 }
216 }
217}
218
219#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
221pub enum LayoutBorderStyle {
222 None,
224 Hidden,
226 Solid,
228 Dashed,
230 Dotted,
232 Double,
234 Groove,
236 Ridge,
238 Inset,
240 Outset,
242}
243
244impl LayoutBorderStyle {
245 pub(crate) fn to_name(self) -> Name<'static> {
246 match self {
247 Self::None => Name(b"None"),
248 Self::Hidden => Name(b"Hidden"),
249 Self::Solid => Name(b"Solid"),
250 Self::Dashed => Name(b"Dashed"),
251 Self::Dotted => Name(b"Dotted"),
252 Self::Double => Name(b"Double"),
253 Self::Groove => Name(b"Groove"),
254 Self::Ridge => Name(b"Ridge"),
255 Self::Inset => Name(b"Inset"),
256 Self::Outset => Name(b"Outset"),
257 }
258 }
259}
260
261impl LayoutAttributes<'_> {
263 pub fn space_before(&mut self, space: f32) -> &mut Self {
265 self.dict.pair(Name(b"SpaceBefore"), space);
266 self
267 }
268
269 pub fn space_after(&mut self, space: f32) -> &mut Self {
271 self.dict.pair(Name(b"SpaceAfter"), space);
272 self
273 }
274
275 pub fn start_indent(&mut self, indent: f32) -> &mut Self {
277 self.dict.pair(Name(b"StartIndent"), indent);
278 self
279 }
280
281 pub fn end_indent(&mut self, indent: f32) -> &mut Self {
283 self.dict.pair(Name(b"EndIndent"), indent);
284 self
285 }
286
287 pub fn text_indent(&mut self, indent: f32) -> &mut Self {
289 self.dict.pair(Name(b"TextIndent"), indent);
290 self
291 }
292
293 pub fn text_align(&mut self, align: TextAlign) -> &mut Self {
295 self.dict.pair(Name(b"TextAlign"), align.to_name());
296 self
297 }
298
299 pub fn width(&mut self, width: f32) -> &mut Self {
302 self.dict.pair(Name(b"Width"), width);
303 self
304 }
305
306 pub fn height(&mut self, height: f32) -> &mut Self {
309 self.dict.pair(Name(b"Height"), height);
310 self
311 }
312}
313
314#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
316pub enum TextAlign {
317 Start,
319 Center,
321 End,
323 Justify,
325}
326
327impl TextAlign {
328 pub(crate) fn to_name(self) -> Name<'static> {
329 match self {
330 Self::Start => Name(b"Start"),
331 Self::Center => Name(b"Center"),
332 Self::End => Name(b"End"),
333 Self::Justify => Name(b"Justify"),
334 }
335 }
336}
337
338impl LayoutAttributes<'_> {
340 pub fn bbox(&mut self, bbox: Rect) -> &mut Self {
342 self.dict.pair(Name(b"BBox"), bbox);
343 self
344 }
345}
346
347impl LayoutAttributes<'_> {
349 pub fn block_align(&mut self, align: BlockAlign) -> &mut Self {
351 self.dict.pair(Name(b"BlockAlign"), align.to_name());
352 self
353 }
354
355 pub fn inline_align(&mut self, align: InlineAlign) -> &mut Self {
357 self.dict.pair(Name(b"InlineAlign"), align.to_name());
358 self
359 }
360
361 pub fn table_border_style(&mut self, style: [LayoutBorderStyle; 4]) -> &mut Self {
363 self.dict
364 .insert(Name(b"TBorderStyle"))
365 .array()
366 .typed()
367 .items(style.into_iter().map(LayoutBorderStyle::to_name));
368 self
369 }
370
371 pub fn table_padding(&mut self, padding: f32) -> &mut Self {
373 self.dict.pair(Name(b"TPadding"), padding);
374 self
375 }
376}
377
378#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
380pub enum BlockAlign {
381 Begin,
383 Middle,
385 After,
387 Justify,
389}
390
391impl BlockAlign {
392 pub(crate) fn to_name(self) -> Name<'static> {
393 match self {
394 Self::Begin => Name(b"Begin"),
395 Self::Middle => Name(b"Middle"),
396 Self::After => Name(b"After"),
397 Self::Justify => Name(b"Justify"),
398 }
399 }
400}
401
402impl LayoutAttributes<'_> {
404 pub fn column_count(&mut self, count: i32) -> &mut Self {
406 self.dict.pair(Name(b"ColumnCount"), count);
407 self
408 }
409
410 pub fn column_widths(&mut self) -> TypedArray<'_, f32> {
413 self.dict.insert(Name(b"ColumnWidths")).array().typed()
414 }
415
416 pub fn column_gap(&mut self) -> TypedArray<'_, f32> {
419 self.dict.insert(Name(b"ColumnGap")).array().typed()
420 }
421}
422
423#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
425pub enum InlineAlign {
426 Start,
428 Center,
430 End,
432}
433
434impl InlineAlign {
435 pub(crate) fn to_name(self) -> Name<'static> {
436 match self {
437 Self::Start => Name(b"Start"),
438 Self::Center => Name(b"Center"),
439 Self::End => Name(b"End"),
440 }
441 }
442}
443
444impl LayoutAttributes<'_> {
446 pub fn line_height(&mut self, height: LineHeight) -> &mut Self {
448 height.write(self.dict.insert(Name(b"LineHeight")));
449 self
450 }
451
452 pub fn baseline_shift(&mut self, shift: f32) -> &mut Self {
454 self.dict.pair(Name(b"BaselineShift"), shift);
455 self
456 }
457
458 pub fn text_decoration_type(&mut self, decoration: TextDecorationType) -> &mut Self {
460 self.dict.pair(Name(b"TextDecorationType"), decoration.to_name());
461 self
462 }
463
464 pub fn text_decoration_color(&mut self, color: [f32; 3]) -> &mut Self {
466 self.dict
467 .insert(Name(b"TextDecorationColor"))
468 .array()
469 .typed()
470 .items(color);
471 self
472 }
473
474 pub fn text_decoration_thickness(&mut self, thickness: f32) -> &mut Self {
476 self.dict.pair(Name(b"TextDecorationThickness"), thickness);
477 self
478 }
479}
480
481#[derive(Debug, Copy, Clone, PartialEq)]
483pub enum LineHeight {
484 Normal,
487 Auto,
489 Custom(f32),
491}
492
493impl LineHeight {
494 pub(crate) fn write(self, obj: Obj) {
495 match self {
496 Self::Normal => obj.primitive(Name(b"Normal")),
497 Self::Auto => obj.primitive(Name(b"Auto")),
498 Self::Custom(height) => obj.primitive(height),
499 }
500 }
501}
502
503#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
505pub enum TextDecorationType {
506 None,
508 Underline,
510 Overline,
512 LineThrough,
514}
515
516impl TextDecorationType {
517 pub(crate) fn to_name(self) -> Name<'static> {
518 match self {
519 Self::None => Name(b"None"),
520 Self::Underline => Name(b"Underline"),
521 Self::Overline => Name(b"Overline"),
522 Self::LineThrough => Name(b"LineThrough"),
523 }
524 }
525}
526
527impl LayoutAttributes<'_> {
529 pub fn glyph_orientation_vertical(&mut self, angle: f32) -> &mut Self {
532 self.dict.pair(Name(b"GlyphOrientationVertical"), angle);
533 self
534 }
535}
536
537impl LayoutAttributes<'_> {
539 pub fn ruby_align(&mut self, align: RubyAlign) -> &mut Self {
541 self.dict.pair(Name(b"RubyAlign"), align.to_name());
542 self
543 }
544
545 pub fn ruby_position(&mut self, position: RubyPosition) -> &mut Self {
547 self.dict.pair(Name(b"RubyPosition"), position.to_name());
548 self
549 }
550}
551
552#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
554pub enum RubyAlign {
555 Start,
557 Center,
559 End,
561 Justify,
563 Distribute,
565}
566
567impl RubyAlign {
568 pub(crate) fn to_name(self) -> Name<'static> {
569 match self {
570 Self::Start => Name(b"Start"),
571 Self::Center => Name(b"Center"),
572 Self::End => Name(b"End"),
573 Self::Justify => Name(b"Justify"),
574 Self::Distribute => Name(b"Distribute"),
575 }
576 }
577}
578
579#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
581pub enum RubyPosition {
582 Before,
584 After,
586 Warichu,
588 Inline,
590}
591
592impl RubyPosition {
593 pub(crate) fn to_name(self) -> Name<'static> {
594 match self {
595 Self::Before => Name(b"Before"),
596 Self::After => Name(b"After"),
597 Self::Warichu => Name(b"Warichu"),
598 Self::Inline => Name(b"Inline"),
599 }
600 }
601}
602
603deref!('a, LayoutAttributes<'a> => Dict<'a>, dict);
604
605pub struct ListAttributes<'a> {
609 dict: Dict<'a>,
610}
611
612writer!(ListAttributes: |obj| Self::start_with_dict(obj.dict()));
613
614impl<'a> ListAttributes<'a> {
615 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
616 dict.pair(Name(b"O"), AttributeOwner::List.to_name());
617 Self { dict }
618 }
619
620 pub fn list_numbering(&mut self, numbering: ListNumbering) -> &mut Self {
622 self.dict.pair(Name(b"ListNumbering"), numbering.to_name());
623 self
624 }
625}
626
627deref!('a, ListAttributes<'a> => Dict<'a>, dict);
628
629#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
631pub enum ListNumbering {
632 None,
634 Disc,
636 Circle,
638 Square,
640 Decimal,
642 LowerRoman,
644 UpperRoman,
646 LowerAlpha,
648 UpperAlpha,
650}
651
652impl ListNumbering {
653 pub(crate) fn to_name(self) -> Name<'static> {
654 match self {
655 Self::None => Name(b"None"),
656 Self::Disc => Name(b"Disc"),
657 Self::Circle => Name(b"Circle"),
658 Self::Square => Name(b"Square"),
659 Self::Decimal => Name(b"Decimal"),
660 Self::LowerRoman => Name(b"LowerRoman"),
661 Self::UpperRoman => Name(b"UpperRoman"),
662 Self::LowerAlpha => Name(b"LowerAlpha"),
663 Self::UpperAlpha => Name(b"UpperAlpha"),
664 }
665 }
666}
667
668pub struct FieldAttributes<'a> {
672 dict: Dict<'a>,
673}
674
675writer!(FieldAttributes: |obj| Self::start_with_dict(obj.dict()));
676
677impl<'a> FieldAttributes<'a> {
678 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
679 dict.pair(Name(b"O"), AttributeOwner::PrintField.to_name());
680 Self { dict }
681 }
682
683 pub fn role(&mut self, role: FieldRole) -> &mut Self {
685 self.dict.pair(Name(b"Role"), role.to_name());
686 self
687 }
688
689 pub fn checked(&mut self, checked: FieldState) -> &mut Self {
692 self.dict.pair(Name(b"checked"), checked.to_name());
693 self
694 }
695
696 pub fn description(&mut self, desc: TextStr) -> &mut Self {
698 self.dict.pair(Name(b"Desc"), desc);
699 self
700 }
701}
702
703deref!('a, FieldAttributes<'a> => Dict<'a>, dict);
704
705#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
707pub enum FieldRole {
708 Button,
710 CheckBox,
712 RadioButton,
714 TextField,
716}
717
718impl FieldRole {
719 pub(crate) fn to_name(self) -> Name<'static> {
720 match self {
721 Self::Button => Name(b"pb"),
722 Self::CheckBox => Name(b"cb"),
723 Self::RadioButton => Name(b"rb"),
724 Self::TextField => Name(b"tv"),
725 }
726 }
727}
728
729#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
731pub enum FieldState {
732 Unchecked,
734 Checked,
736 Neutral,
738}
739
740impl FieldState {
741 pub(crate) fn to_name(self) -> Name<'static> {
742 match self {
743 Self::Unchecked => Name(b"off"),
744 Self::Checked => Name(b"on"),
745 Self::Neutral => Name(b"neutral"),
746 }
747 }
748}
749
750pub struct TableAttributes<'a> {
754 dict: Dict<'a>,
755}
756
757writer!(TableAttributes: |obj| Self::start_with_dict(obj.dict()));
758
759impl<'a> TableAttributes<'a> {
760 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
761 dict.pair(Name(b"O"), AttributeOwner::Table.to_name());
762 Self { dict }
763 }
764
765 pub fn row_span(&mut self, row_span: i32) -> &mut Self {
768 self.dict.pair(Name(b"RowSpan"), row_span);
769 self
770 }
771
772 pub fn col_span(&mut self, col_span: i32) -> &mut Self {
775 self.dict.pair(Name(b"ColSpan"), col_span);
776 self
777 }
778
779 pub fn headers(&mut self) -> TypedArray<'_, Str> {
782 self.dict.insert(Name(b"Headers")).array().typed()
783 }
784
785 pub fn scope(&mut self, scope: TableHeaderScope) -> &mut Self {
788 self.dict.pair(Name(b"Scope"), scope.to_name());
789 self
790 }
791
792 pub fn summary(&mut self, summary: TextStr) -> &mut Self {
795 self.dict.pair(Name(b"Summary"), summary);
796 self
797 }
798}
799
800deref!('a, TableAttributes<'a> => Dict<'a>, dict);
801
802#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
804pub enum TableHeaderScope {
805 Row,
807 Column,
809 Both,
811}
812
813impl TableHeaderScope {
814 pub(crate) fn to_name(self) -> Name<'static> {
815 match self {
816 Self::Row => Name(b"Row"),
817 Self::Column => Name(b"Column"),
818 Self::Both => Name(b"Both"),
819 }
820 }
821}
822
823#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
825pub enum AttributeOwner {
826 Layout,
828 List,
830 PrintField,
832 Table,
834 Xml,
836 Html3_2,
838 Html4,
840 Oeb,
842 Rtf1_05,
844 Css1,
846 Css2,
848 User,
851}
852
853impl AttributeOwner {
854 pub(crate) fn to_name(self) -> Name<'static> {
855 match self {
856 Self::Layout => Name(b"Layout"),
857 Self::List => Name(b"List"),
858 Self::PrintField => Name(b"PrintField"),
859 Self::Table => Name(b"Table"),
860 Self::Xml => Name(b"XML-1.00"),
861 Self::Html3_2 => Name(b"HTML-3.20"),
862 Self::Html4 => Name(b"HTML-4.01"),
863 Self::Oeb => Name(b"OEB-1.00"),
864 Self::Rtf1_05 => Name(b"RTF-1.05"),
865 Self::Css1 => Name(b"CSS-1.00"),
866 Self::Css2 => Name(b"CSS-2.00"),
867 Self::User => Name(b"UserDefined"),
868 }
869 }
870}