1use super::*;
2use crate::object::TextStrLike;
3use crate::types::{ArtifactSubtype, ArtifactType};
4
5pub struct Attributes<'a> {
11 dict: Dict<'a>,
12}
13
14writer!(Attributes: |obj| Self { dict: obj.dict() });
15
16impl<'a> Attributes<'a> {
17 pub fn owner(&mut self, owner: AttributeOwner, iso32000_2_2020: bool) -> &mut Self {
25 self.pair(Name(b"O"), owner.to_name(iso32000_2_2020));
26 self
27 }
28
29 pub fn user(&mut self) -> TypedArray<'_, UserProperty<'_>> {
32 self.pair(Name(b"O"), AttributeOwner::User.to_name(false));
33 self.insert(Name(b"P")).array().typed()
34 }
35
36 pub fn layout(self) -> LayoutAttributes<'a> {
38 LayoutAttributes::start_with_dict(self.dict)
39 }
40
41 pub fn list(self) -> ListAttributes<'a> {
43 ListAttributes::start_with_dict(self.dict)
44 }
45
46 pub fn field(self) -> FieldAttributes<'a> {
49 FieldAttributes::start_with_dict(self.dict)
50 }
51
52 pub fn table(self) -> TableAttributes<'a> {
54 TableAttributes::start_with_dict(self.dict)
55 }
56
57 pub fn artifact(self) -> ArtifactAttributes<'a> {
60 ArtifactAttributes::start_with_dict(self.dict)
61 }
62
63 pub fn note(self) -> FENoteAttributes<'a> {
66 FENoteAttributes::start_with_dict(self.dict)
67 }
68
69 pub fn namespace(self, ns: Ref) -> Dict<'a> {
73 let mut dict = self.dict;
74 dict.pair(Name(b"O"), AttributeOwner::NSO.to_name(true));
75 dict.pair(Name(b"NS"), ns);
76 dict
77 }
78}
79
80deref!('a, Attributes<'a> => Dict<'a>, dict);
81
82pub struct UserProperty<'a> {
86 dict: Dict<'a>,
87}
88
89writer!(UserProperty: |obj| Self { dict: obj.dict() });
90
91impl UserProperty<'_> {
92 pub fn name(&mut self, name: impl TextStrLike) -> &mut Self {
94 self.dict.pair(Name(b"N"), name);
95 self
96 }
97
98 pub fn value(&mut self) -> Obj<'_> {
100 self.dict.insert(Name(b"V"))
101 }
102
103 pub fn format(&mut self, format: impl TextStrLike) -> &mut Self {
105 self.dict.pair(Name(b"F"), format);
106 self
107 }
108
109 pub fn hidden(&mut self, hide: bool) -> &mut Self {
112 self.dict.pair(Name(b"H"), hide);
113 self
114 }
115}
116
117deref!('a, UserProperty<'a> => Dict<'a>, dict);
118
119pub struct LayoutAttributes<'a> {
123 dict: Dict<'a>,
124}
125
126writer!(LayoutAttributes: |obj| Self::start_with_dict(obj.dict()));
127
128impl<'a> LayoutAttributes<'a> {
130 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
131 dict.pair(Name(b"O"), AttributeOwner::Layout.to_name(false));
132 Self { dict }
133 }
134
135 pub fn placement(&mut self, placement: Placement) -> &mut Self {
137 self.dict.pair(Name(b"Placement"), placement.to_name());
138 self
139 }
140
141 pub fn writing_mode(&mut self, mode: WritingMode) -> &mut Self {
143 self.dict.pair(Name(b"WritingMode"), mode.to_name());
144 self
145 }
146
147 pub fn background_color(&mut self, color: [f32; 3]) -> &mut Self {
150 self.dict
151 .insert(Name(b"BackgroundColor"))
152 .array()
153 .typed()
154 .items(color);
155 self
156 }
157
158 pub fn border_color(&mut self, color: Sides<[f32; 3]>) -> &mut Self {
160 let obj = self.dict.insert(Name(b"BorderColor"));
161 color.write_iter(obj);
162 self
163 }
164
165 pub fn border_style(&mut self, style: Sides<LayoutBorderStyle>) -> &mut Self {
167 let obj = self.dict.insert(Name(b"BorderStyle"));
168 style.write_map_primitive(obj, LayoutBorderStyle::to_name);
169 self
170 }
171
172 pub fn border_thickness(&mut self, thickness: Sides<f32>) -> &mut Self {
174 let obj = self.dict.insert(Name(b"BorderThickness"));
175 thickness.write_primitive(obj);
176 self
177 }
178
179 pub fn padding(&mut self, padding: Sides<f32>) -> &mut Self {
181 let obj = self.dict.insert(Name(b"Padding"));
182 padding.write_primitive(obj);
183 self
184 }
185
186 pub fn color(&mut self, color: [f32; 3]) -> &mut Self {
188 self.dict.insert(Name(b"Color")).array().typed().items(color);
189 self
190 }
191}
192
193#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
195pub struct Sides<T> {
196 pub before: T,
199 pub after: T,
202 pub start: T,
205 pub end: T,
208}
209
210impl<T> Sides<T> {
211 pub fn new(before: T, after: T, start: T, end: T) -> Self {
213 Self { before, after, start, end }
214 }
215
216 pub fn from_array(array: [T; 4]) -> Self {
219 let [before, after, start, end] = array;
220 Self { before, after, start, end }
221 }
222
223 pub fn uniform(value: T) -> Self
225 where
226 T: Clone,
227 {
228 Self {
229 before: value.clone(),
230 after: value.clone(),
231 start: value.clone(),
232 end: value,
233 }
234 }
235
236 fn is_uniform(&self) -> bool
238 where
239 T: PartialEq,
240 {
241 self.before == self.after && self.before == self.start && self.before == self.end
242 }
243
244 fn into_array(self) -> [T; 4] {
246 [self.before, self.after, self.start, self.end]
247 }
248
249 fn write_primitive(self, obj: Obj<'_>)
251 where
252 T: Primitive + PartialEq,
253 {
254 self.write_map_primitive(obj, |side| side);
255 }
256
257 fn write_map_primitive<P>(self, obj: Obj<'_>, mut to_primitive: impl FnMut(T) -> P)
260 where
261 T: PartialEq,
262 P: Primitive,
263 {
264 if self.is_uniform() {
265 obj.primitive(to_primitive(self.before));
266 } else {
267 let mut array = obj.array();
268 for side in self.into_array() {
269 array.push().primitive(to_primitive(side));
270 }
271 }
272 }
273
274 fn write_iter<P>(self, obj: Obj<'_>)
276 where
277 T: IntoIterator<Item = P> + PartialEq,
278 P: Primitive,
279 {
280 if self.is_uniform() {
281 obj.array().typed().items(self.before);
282 } else {
283 let mut array = obj.array();
284 for side in self.into_array() {
285 array.push().array().typed().items(side);
286 }
287 }
288 }
289}
290
291#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
293pub enum Placement {
294 Block,
296 Inline,
298 Before,
301 Start,
304 End,
307}
308
309impl Placement {
310 pub(crate) fn to_name(self) -> Name<'static> {
311 match self {
312 Self::Block => Name(b"Block"),
313 Self::Inline => Name(b"Inline"),
314 Self::Before => Name(b"Before"),
315 Self::Start => Name(b"Start"),
316 Self::End => Name(b"End"),
317 }
318 }
319}
320
321#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
323pub enum WritingMode {
324 #[default]
326 LtrTtb,
327 RtlTtb,
329 TtbRtl,
331}
332
333impl WritingMode {
334 pub(crate) fn to_name(self) -> Name<'static> {
335 match self {
336 Self::LtrTtb => Name(b"LrTb"),
337 Self::RtlTtb => Name(b"RlTb"),
338 Self::TtbRtl => Name(b"TbRl"),
339 }
340 }
341}
342
343#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
345pub enum LayoutBorderStyle {
346 #[default]
348 None,
349 Hidden,
351 Solid,
353 Dashed,
355 Dotted,
357 Double,
359 Groove,
361 Ridge,
363 Inset,
365 Outset,
367}
368
369impl LayoutBorderStyle {
370 pub(crate) fn to_name(self) -> Name<'static> {
371 match self {
372 Self::None => Name(b"None"),
373 Self::Hidden => Name(b"Hidden"),
374 Self::Solid => Name(b"Solid"),
375 Self::Dashed => Name(b"Dashed"),
376 Self::Dotted => Name(b"Dotted"),
377 Self::Double => Name(b"Double"),
378 Self::Groove => Name(b"Groove"),
379 Self::Ridge => Name(b"Ridge"),
380 Self::Inset => Name(b"Inset"),
381 Self::Outset => Name(b"Outset"),
382 }
383 }
384}
385
386impl LayoutAttributes<'_> {
388 pub fn space_before(&mut self, space: f32) -> &mut Self {
390 self.dict.pair(Name(b"SpaceBefore"), space);
391 self
392 }
393
394 pub fn space_after(&mut self, space: f32) -> &mut Self {
396 self.dict.pair(Name(b"SpaceAfter"), space);
397 self
398 }
399
400 pub fn start_indent(&mut self, indent: f32) -> &mut Self {
402 self.dict.pair(Name(b"StartIndent"), indent);
403 self
404 }
405
406 pub fn end_indent(&mut self, indent: f32) -> &mut Self {
408 self.dict.pair(Name(b"EndIndent"), indent);
409 self
410 }
411
412 pub fn text_indent(&mut self, indent: f32) -> &mut Self {
414 self.dict.pair(Name(b"TextIndent"), indent);
415 self
416 }
417
418 pub fn text_align(&mut self, align: TextAlign) -> &mut Self {
420 self.dict.pair(Name(b"TextAlign"), align.to_name());
421 self
422 }
423
424 pub fn width(&mut self, width: f32) -> &mut Self {
427 self.dict.pair(Name(b"Width"), width);
428 self
429 }
430
431 pub fn height(&mut self, height: f32) -> &mut Self {
434 self.dict.pair(Name(b"Height"), height);
435 self
436 }
437}
438
439#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
441pub enum TextAlign {
442 #[default]
444 Start,
445 Center,
447 End,
449 Justify,
451}
452
453impl TextAlign {
454 pub(crate) fn to_name(self) -> Name<'static> {
455 match self {
456 Self::Start => Name(b"Start"),
457 Self::Center => Name(b"Center"),
458 Self::End => Name(b"End"),
459 Self::Justify => Name(b"Justify"),
460 }
461 }
462}
463
464impl LayoutAttributes<'_> {
466 pub fn bbox(&mut self, bbox: Rect) -> &mut Self {
468 self.dict.pair(Name(b"BBox"), bbox);
469 self
470 }
471}
472
473impl LayoutAttributes<'_> {
475 pub fn block_align(&mut self, align: BlockAlign) -> &mut Self {
477 self.dict.pair(Name(b"BlockAlign"), align.to_name());
478 self
479 }
480
481 pub fn inline_align(&mut self, align: InlineAlign) -> &mut Self {
483 self.dict.pair(Name(b"InlineAlign"), align.to_name());
484 self
485 }
486
487 pub fn table_border_style(&mut self, style: Sides<LayoutBorderStyle>) -> &mut Self {
489 let obj = self.dict.insert(Name(b"TBorderStyle"));
490 style.write_map_primitive(obj, LayoutBorderStyle::to_name);
491 self
492 }
493
494 pub fn table_padding(&mut self, padding: Sides<f32>) -> &mut Self {
496 let obj = self.dict.insert(Name(b"TPadding"));
497 padding.write_primitive(obj);
498 self
499 }
500}
501
502#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
504pub enum BlockAlign {
505 #[default]
507 Before,
508 Middle,
510 After,
512 Justify,
514}
515
516impl BlockAlign {
517 pub(crate) fn to_name(self) -> Name<'static> {
518 match self {
519 Self::Before => Name(b"Before"),
520 Self::Middle => Name(b"Middle"),
521 Self::After => Name(b"After"),
522 Self::Justify => Name(b"Justify"),
523 }
524 }
525}
526
527impl LayoutAttributes<'_> {
529 pub fn column_count(&mut self, count: i32) -> &mut Self {
531 self.dict.pair(Name(b"ColumnCount"), count);
532 self
533 }
534
535 pub fn column_widths(&mut self) -> TrackSizes<'_> {
537 TrackSizes::start(self.dict.insert(Name(b"ColumnWidths")))
538 }
539
540 pub fn column_gap(&mut self) -> TrackSizes<'_> {
542 TrackSizes::start(self.dict.insert(Name(b"ColumnGap")))
543 }
544}
545
546pub struct TrackSizes<'a> {
551 obj: Obj<'a>,
552}
553
554writer!(TrackSizes: |obj| Self { obj });
555
556impl<'a> TrackSizes<'a> {
557 pub fn uniform(self, value: f32) {
559 self.obj.primitive(value);
560 }
561
562 pub fn individual(self) -> TypedArray<'a, f32> {
566 self.obj.array().typed()
567 }
568}
569
570deref!('a, TrackSizes<'a> => Obj<'a>, obj);
571
572#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
574pub enum InlineAlign {
575 #[default]
577 Start,
578 Center,
580 End,
582}
583
584impl InlineAlign {
585 pub(crate) fn to_name(self) -> Name<'static> {
586 match self {
587 Self::Start => Name(b"Start"),
588 Self::Center => Name(b"Center"),
589 Self::End => Name(b"End"),
590 }
591 }
592}
593
594impl LayoutAttributes<'_> {
596 pub fn line_height(&mut self, height: LineHeight) -> &mut Self {
598 height.write(self.dict.insert(Name(b"LineHeight")));
599 self
600 }
601
602 pub fn baseline_shift(&mut self, shift: f32) -> &mut Self {
604 self.dict.pair(Name(b"BaselineShift"), shift);
605 self
606 }
607
608 pub fn text_position(&mut self, position: LayoutTextPosition) -> &mut Self {
610 self.dict.pair(Name(b"TextPosition"), position.to_name());
611 self
612 }
613
614 pub fn text_decoration_type(&mut self, decoration: TextDecorationType) -> &mut Self {
616 self.dict.pair(Name(b"TextDecorationType"), decoration.to_name());
617 self
618 }
619
620 pub fn text_decoration_color(&mut self, color: [f32; 3]) -> &mut Self {
622 self.dict
623 .insert(Name(b"TextDecorationColor"))
624 .array()
625 .typed()
626 .items(color);
627 self
628 }
629
630 pub fn text_decoration_thickness(&mut self, thickness: f32) -> &mut Self {
632 self.dict.pair(Name(b"TextDecorationThickness"), thickness);
633 self
634 }
635}
636
637#[derive(Debug, Copy, Clone, Default, PartialEq)]
639pub enum LineHeight {
640 #[default]
643 Normal,
644 Auto,
646 Custom(f32),
648}
649
650impl LineHeight {
651 pub(crate) fn write(self, obj: Obj) {
652 match self {
653 Self::Normal => obj.primitive(Name(b"Normal")),
654 Self::Auto => obj.primitive(Name(b"Auto")),
655 Self::Custom(height) => obj.primitive(height),
656 }
657 }
658}
659
660#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
662pub enum LayoutTextPosition {
663 #[default]
665 Normal,
666 Superscript,
668 Subscript,
670}
671
672impl LayoutTextPosition {
673 pub(crate) fn to_name(self) -> Name<'static> {
674 match self {
675 Self::Normal => Name(b"Normal"),
676 Self::Superscript => Name(b"Sup"),
677 Self::Subscript => Name(b"Sub"),
678 }
679 }
680}
681
682#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
684pub enum TextDecorationType {
685 #[default]
687 None,
688 Underline,
690 Overline,
692 LineThrough,
694}
695
696impl TextDecorationType {
697 pub(crate) fn to_name(self) -> Name<'static> {
698 match self {
699 Self::None => Name(b"None"),
700 Self::Underline => Name(b"Underline"),
701 Self::Overline => Name(b"Overline"),
702 Self::LineThrough => Name(b"LineThrough"),
703 }
704 }
705}
706
707#[derive(Debug, Copy, Clone, Default, PartialEq)]
710pub enum GlyphOrientationVertical {
711 #[default]
713 Auto,
714 Angle(i32),
716}
717
718impl GlyphOrientationVertical {
719 pub(crate) fn write(self, obj: Obj) {
720 match self {
721 Self::Auto => obj.primitive(Name(b"Auto")),
722 Self::Angle(angle) => obj.primitive(angle),
723 }
724 }
725}
726
727impl LayoutAttributes<'_> {
729 pub fn glyph_orientation_vertical(
731 &mut self,
732 orientation: GlyphOrientationVertical,
733 ) -> &mut Self {
734 orientation.write(self.dict.insert(Name(b"GlyphOrientationVertical")));
735 self
736 }
737}
738
739impl LayoutAttributes<'_> {
741 pub fn ruby_align(&mut self, align: RubyAlign) -> &mut Self {
743 self.dict.pair(Name(b"RubyAlign"), align.to_name());
744 self
745 }
746
747 pub fn ruby_position(&mut self, position: RubyPosition) -> &mut Self {
749 self.dict.pair(Name(b"RubyPosition"), position.to_name());
750 self
751 }
752}
753
754#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
756pub enum RubyAlign {
757 Start,
759 Center,
761 End,
763 Justify,
765 #[default]
767 Distribute,
768}
769
770impl RubyAlign {
771 pub(crate) fn to_name(self) -> Name<'static> {
772 match self {
773 Self::Start => Name(b"Start"),
774 Self::Center => Name(b"Center"),
775 Self::End => Name(b"End"),
776 Self::Justify => Name(b"Justify"),
777 Self::Distribute => Name(b"Distribute"),
778 }
779 }
780}
781
782#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
784pub enum RubyPosition {
785 #[default]
787 Before,
788 After,
790 Warichu,
792 Inline,
794}
795
796impl RubyPosition {
797 pub(crate) fn to_name(self) -> Name<'static> {
798 match self {
799 Self::Before => Name(b"Before"),
800 Self::After => Name(b"After"),
801 Self::Warichu => Name(b"Warichu"),
802 Self::Inline => Name(b"Inline"),
803 }
804 }
805}
806
807deref!('a, LayoutAttributes<'a> => Dict<'a>, dict);
808
809pub struct ListAttributes<'a> {
813 dict: Dict<'a>,
814}
815
816writer!(ListAttributes: |obj| Self::start_with_dict(obj.dict()));
817
818impl<'a> ListAttributes<'a> {
819 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
820 dict.pair(Name(b"O"), AttributeOwner::List.to_name(false));
821 Self { dict }
822 }
823
824 pub fn list_numbering(&mut self, numbering: ListNumbering) -> &mut Self {
826 self.dict.pair(Name(b"ListNumbering"), numbering.to_name());
827 self
828 }
829
830 pub fn continued_list(&mut self, continued: bool) -> &mut Self {
836 self.dict.pair(Name(b"ContinuedList"), continued);
837 self
838 }
839
840 pub fn continued_from(&mut self, id: Str) -> &mut Self {
844 self.dict.pair(Name(b"ContinuedFrom"), id);
845 self
846 }
847}
848
849deref!('a, ListAttributes<'a> => Dict<'a>, dict);
850
851#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
853pub enum ListNumbering {
854 #[default]
856 None,
857 Unordered,
859 Ordered,
861 Description,
863 Disc,
865 Circle,
867 Square,
869 Decimal,
871 LowerRoman,
873 UpperRoman,
875 LowerAlpha,
877 UpperAlpha,
879}
880
881impl ListNumbering {
882 pub(crate) fn to_name(self) -> Name<'static> {
883 match self {
884 Self::None => Name(b"None"),
885 Self::Unordered => Name(b"Unordered"),
886 Self::Ordered => Name(b"Ordered"),
887 Self::Description => Name(b"Description"),
888 Self::Disc => Name(b"Disc"),
889 Self::Circle => Name(b"Circle"),
890 Self::Square => Name(b"Square"),
891 Self::Decimal => Name(b"Decimal"),
892 Self::LowerRoman => Name(b"LowerRoman"),
893 Self::UpperRoman => Name(b"UpperRoman"),
894 Self::LowerAlpha => Name(b"LowerAlpha"),
895 Self::UpperAlpha => Name(b"UpperAlpha"),
896 }
897 }
898}
899
900pub struct FieldAttributes<'a> {
904 dict: Dict<'a>,
905}
906
907writer!(FieldAttributes: |obj| Self::start_with_dict(obj.dict()));
908
909impl<'a> FieldAttributes<'a> {
910 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
911 dict.pair(Name(b"O"), AttributeOwner::PrintField.to_name(false));
912 Self { dict }
913 }
914
915 pub fn role(&mut self, role: FieldRole) -> &mut Self {
917 self.dict.pair(Name(b"Role"), role.to_name());
918 self
919 }
920
921 pub fn checked(&mut self, checked: FieldState, pdf2: bool) -> &mut Self {
928 self.dict
929 .pair(Name(if pdf2 { b"Checked" } else { b"checked" }), checked.to_name());
930 self
931 }
932
933 pub fn description(&mut self, desc: impl TextStrLike) -> &mut Self {
935 self.dict.pair(Name(b"Desc"), desc);
936 self
937 }
938}
939
940deref!('a, FieldAttributes<'a> => Dict<'a>, dict);
941
942#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
944pub enum FieldRole {
945 Button,
947 CheckBox,
949 RadioButton,
951 TextField,
953 ListBox,
955}
956
957impl FieldRole {
958 pub(crate) fn to_name(self) -> Name<'static> {
959 match self {
960 Self::Button => Name(b"pb"),
961 Self::CheckBox => Name(b"cb"),
962 Self::RadioButton => Name(b"rb"),
963 Self::TextField => Name(b"tv"),
964 Self::ListBox => Name(b"lb"),
965 }
966 }
967}
968
969#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
971pub enum FieldState {
972 #[default]
974 Unchecked,
975 Checked,
977 Neutral,
979}
980
981impl FieldState {
982 pub(crate) fn to_name(self) -> Name<'static> {
983 match self {
984 Self::Unchecked => Name(b"off"),
985 Self::Checked => Name(b"on"),
986 Self::Neutral => Name(b"neutral"),
987 }
988 }
989}
990
991pub struct TableAttributes<'a> {
995 dict: Dict<'a>,
996}
997
998writer!(TableAttributes: |obj| Self::start_with_dict(obj.dict()));
999
1000impl<'a> TableAttributes<'a> {
1001 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
1002 dict.pair(Name(b"O"), AttributeOwner::Table.to_name(false));
1003 Self { dict }
1004 }
1005
1006 pub fn row_span(&mut self, row_span: i32) -> &mut Self {
1009 self.dict.pair(Name(b"RowSpan"), row_span);
1010 self
1011 }
1012
1013 pub fn col_span(&mut self, col_span: i32) -> &mut Self {
1016 self.dict.pair(Name(b"ColSpan"), col_span);
1017 self
1018 }
1019
1020 pub fn headers(&mut self) -> TypedArray<'_, Str<'_>> {
1023 self.dict.insert(Name(b"Headers")).array().typed()
1024 }
1025
1026 pub fn scope(&mut self, scope: TableHeaderScope) -> &mut Self {
1029 self.dict.pair(Name(b"Scope"), scope.to_name());
1030 self
1031 }
1032
1033 pub fn summary(&mut self, summary: impl TextStrLike) -> &mut Self {
1036 self.dict.pair(Name(b"Summary"), summary);
1037 self
1038 }
1039
1040 pub fn short(&mut self, short: impl TextStrLike) -> &mut Self {
1043 self.dict.pair(Name(b"Short"), short);
1044 self
1045 }
1046}
1047
1048deref!('a, TableAttributes<'a> => Dict<'a>, dict);
1049
1050#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
1052pub enum TableHeaderScope {
1053 Row,
1055 Column,
1057 Both,
1059}
1060
1061impl TableHeaderScope {
1062 pub(crate) fn to_name(self) -> Name<'static> {
1063 match self {
1064 Self::Row => Name(b"Row"),
1065 Self::Column => Name(b"Column"),
1066 Self::Both => Name(b"Both"),
1067 }
1068 }
1069}
1070
1071pub struct ArtifactAttributes<'a> {
1075 dict: Dict<'a>,
1076}
1077
1078writer!(ArtifactAttributes: |obj| Self::start_with_dict(obj.dict()));
1079
1080impl<'a> ArtifactAttributes<'a> {
1081 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
1082 dict.pair(Name(b"O"), AttributeOwner::Artifact.to_name(true));
1083 Self { dict }
1084 }
1085
1086 pub fn artifact_type(&mut self, artifact_type: ArtifactType) -> &mut Self {
1088 self.dict.pair(Name(b"Type"), artifact_type.to_name());
1089 self
1090 }
1091
1092 pub fn bbox(&mut self, bbox: Rect) -> &mut Self {
1094 self.dict.pair(Name(b"BBox"), bbox);
1095 self
1096 }
1097
1098 pub fn subtype(&mut self, subtype: ArtifactSubtype) -> &mut Self {
1101 self.dict.pair(Name(b"Subtype"), subtype.to_name());
1102 self
1103 }
1104}
1105
1106deref!('a, ArtifactAttributes<'a> => Dict<'a>, dict);
1107
1108pub struct FENoteAttributes<'a> {
1112 dict: Dict<'a>,
1113}
1114
1115writer!(FENoteAttributes: |obj| Self::start_with_dict(obj.dict()));
1116
1117impl<'a> FENoteAttributes<'a> {
1118 pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
1119 dict.pair(Name(b"O"), AttributeOwner::FENote.to_name(true));
1120 Self { dict }
1121 }
1122
1123 pub fn note_type(&mut self, note_type: NoteType) -> &mut Self {
1125 self.dict.pair(Name(b"NoteType"), note_type.to_name());
1126 self
1127 }
1128}
1129
1130deref!('a, FENoteAttributes<'a> => Dict<'a>, dict);
1131
1132#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
1134pub enum NoteType {
1135 Footnote,
1137 Endnote,
1139 None,
1141}
1142
1143impl NoteType {
1144 pub(crate) fn to_name(self) -> Name<'static> {
1145 match self {
1146 Self::Footnote => Name(b"Footnote"),
1147 Self::Endnote => Name(b"Endnote"),
1148 Self::None => Name(b"None"),
1149 }
1150 }
1151}
1152
1153#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
1155pub enum AttributeOwner {
1156 Layout,
1158 List,
1160 PrintField,
1162 Table,
1164 Artifact,
1166 Xml,
1168 Html3_2,
1170 Html4,
1172 Html5,
1174 Oeb,
1176 Rtf1_05,
1178 Css1,
1180 Css2,
1182 Css3,
1184 Rdfa1_1,
1186 Aria1_1,
1188 FENote,
1190 NSO,
1192 User,
1195}
1196
1197impl AttributeOwner {
1198 pub(crate) fn to_name(self, iso32000_2_2020: bool) -> Name<'static> {
1204 match self {
1205 Self::Layout => Name(b"Layout"),
1206 Self::List => Name(b"List"),
1207 Self::PrintField => Name(b"PrintField"),
1208 Self::Table => Name(b"Table"),
1209 Self::Artifact => Name(b"Artifact"),
1210 Self::Xml => Name(b"XML-1.00"),
1211 Self::Html3_2 => Name(b"HTML-3.20"),
1212 Self::Html4 => Name(b"HTML-4.01"),
1213 Self::Html5 => Name(b"HTML-5.00"),
1214 Self::Oeb => Name(b"OEB-1.00"),
1215 Self::Rtf1_05 => Name(b"RTF-1.05"),
1216 Self::Css1 if iso32000_2_2020 => Name(b"CSS-1"),
1217 Self::Css2 if iso32000_2_2020 => Name(b"CSS-2"),
1218 Self::Css1 => Name(b"CSS-1.00"),
1219 Self::Css2 => Name(b"CSS-2.00"),
1220 Self::Css3 => Name(b"CSS-3"),
1221 Self::Rdfa1_1 => Name(b"RDFa-1.10"),
1222 Self::Aria1_1 => Name(b"ARIA-1.1"),
1223 Self::FENote => Name(b"FENote"),
1224 Self::NSO => Name(b"NSO"),
1225 Self::User => Name(b"UserProperties"),
1226 }
1227 }
1228}