use super::*;
pub struct Attributes<'a> {
dict: Dict<'a>,
}
writer!(Attributes: |obj| Self { dict: obj.dict() });
impl<'a> Attributes<'a> {
pub fn owner(&mut self, owner: AttributeOwner) -> &mut Self {
self.pair(Name(b"O"), owner.to_name());
self
}
pub fn user(&mut self) -> TypedArray<'_, UserProperty> {
self.pair(Name(b"O"), AttributeOwner::User.to_name());
self.insert(Name(b"P")).array().typed()
}
pub fn layout(self) -> LayoutAttributes<'a> {
LayoutAttributes::start_with_dict(self.dict)
}
pub fn list(self) -> ListAttributes<'a> {
ListAttributes::start_with_dict(self.dict)
}
pub fn field(self) -> FieldAttributes<'a> {
FieldAttributes::start_with_dict(self.dict)
}
pub fn table(self) -> TableAttributes<'a> {
TableAttributes::start_with_dict(self.dict)
}
}
deref!('a, Attributes<'a> => Dict<'a>, dict);
pub struct UserProperty<'a> {
dict: Dict<'a>,
}
writer!(UserProperty: |obj| Self { dict: obj.dict() });
impl<'a> UserProperty<'a> {
pub fn name(&mut self, name: TextStr) -> &mut Self {
self.dict.pair(Name(b"N"), name);
self
}
pub fn value(&mut self) -> Obj<'_> {
self.dict.insert(Name(b"V"))
}
pub fn format(&mut self, format: TextStr) -> &mut Self {
self.dict.pair(Name(b"F"), format);
self
}
pub fn hidden(&mut self, hide: bool) -> &mut Self {
self.dict.pair(Name(b"H"), hide);
self
}
}
deref!('a, UserProperty<'a> => Dict<'a>, dict);
pub struct LayoutAttributes<'a> {
dict: Dict<'a>,
}
writer!(LayoutAttributes: |obj| Self::start_with_dict(obj.dict()));
impl<'a> LayoutAttributes<'a> {
pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
dict.pair(Name(b"O"), AttributeOwner::Layout.to_name());
Self { dict }
}
pub fn placement(&mut self, placement: Placement) -> &mut Self {
self.dict.pair(Name(b"Placement"), placement.to_name());
self
}
pub fn writing_mode(&mut self, mode: WritingMode) -> &mut Self {
self.dict.pair(Name(b"WritingMode"), mode.to_name());
self
}
pub fn background_color(&mut self, color: [f32; 3]) -> &mut Self {
self.dict
.insert(Name(b"BackgroundColor"))
.array()
.typed()
.items(color);
self
}
pub fn border_color(&mut self, color: [f32; 3]) -> &mut Self {
self.dict.insert(Name(b"BorderColor")).array().typed().items(color);
self
}
pub fn border_style(&mut self, style: [LayoutBorderStyle; 4]) -> &mut Self {
self.dict
.insert(Name(b"BorderStyle"))
.array()
.typed()
.items(style.into_iter().map(LayoutBorderStyle::to_name));
self
}
pub fn border_thickness(&mut self, thickness: [f32; 4]) -> &mut Self {
self.dict
.insert(Name(b"BorderThickness"))
.array()
.typed()
.items(thickness);
self
}
pub fn padding(&mut self, padding: [f32; 4]) -> &mut Self {
self.dict.insert(Name(b"Padding")).array().typed().items(padding);
self
}
pub fn color(&mut self, color: [f32; 3]) -> &mut Self {
self.dict.insert(Name(b"Color")).array().typed().items(color);
self
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Placement {
Block,
Inline,
Before,
Start,
End,
}
impl Placement {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Block => Name(b"Block"),
Self::Inline => Name(b"Inline"),
Self::Before => Name(b"Before"),
Self::Start => Name(b"Start"),
Self::End => Name(b"End"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum WritingMode {
LtrTtb,
RtlTtb,
TtbRtl,
}
impl WritingMode {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::LtrTtb => Name(b"LrTb"),
Self::RtlTtb => Name(b"RlTb"),
Self::TtbRtl => Name(b"TbRl"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum LayoutBorderStyle {
None,
Hidden,
Solid,
Dashed,
Dotted,
Double,
Groove,
Ridge,
Inset,
Outset,
}
impl LayoutBorderStyle {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::None => Name(b"None"),
Self::Hidden => Name(b"Hidden"),
Self::Solid => Name(b"Solid"),
Self::Dashed => Name(b"Dashed"),
Self::Dotted => Name(b"Dotted"),
Self::Double => Name(b"Double"),
Self::Groove => Name(b"Groove"),
Self::Ridge => Name(b"Ridge"),
Self::Inset => Name(b"Inset"),
Self::Outset => Name(b"Outset"),
}
}
}
impl LayoutAttributes<'_> {
pub fn space_before(&mut self, space: f32) -> &mut Self {
self.dict.pair(Name(b"SpaceBefore"), space);
self
}
pub fn space_after(&mut self, space: f32) -> &mut Self {
self.dict.pair(Name(b"SpaceAfter"), space);
self
}
pub fn start_indent(&mut self, indent: f32) -> &mut Self {
self.dict.pair(Name(b"StartIndent"), indent);
self
}
pub fn end_indent(&mut self, indent: f32) -> &mut Self {
self.dict.pair(Name(b"EndIndent"), indent);
self
}
pub fn text_indent(&mut self, indent: f32) -> &mut Self {
self.dict.pair(Name(b"TextIndent"), indent);
self
}
pub fn text_align(&mut self, align: TextAlign) -> &mut Self {
self.dict.pair(Name(b"TextAlign"), align.to_name());
self
}
pub fn width(&mut self, width: f32) -> &mut Self {
self.dict.pair(Name(b"Width"), width);
self
}
pub fn height(&mut self, height: f32) -> &mut Self {
self.dict.pair(Name(b"Height"), height);
self
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum TextAlign {
Start,
Center,
End,
Justify,
}
impl TextAlign {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Start => Name(b"Start"),
Self::Center => Name(b"Center"),
Self::End => Name(b"End"),
Self::Justify => Name(b"Justify"),
}
}
}
impl LayoutAttributes<'_> {
pub fn bbox(&mut self, bbox: Rect) -> &mut Self {
self.dict.pair(Name(b"BBox"), bbox);
self
}
}
impl LayoutAttributes<'_> {
pub fn block_align(&mut self, align: BlockAlign) -> &mut Self {
self.dict.pair(Name(b"BlockAlign"), align.to_name());
self
}
pub fn inline_align(&mut self, align: InlineAlign) -> &mut Self {
self.dict.pair(Name(b"InlineAlign"), align.to_name());
self
}
pub fn table_border_style(&mut self, style: [LayoutBorderStyle; 4]) -> &mut Self {
self.dict
.insert(Name(b"TBorderStyle"))
.array()
.typed()
.items(style.into_iter().map(LayoutBorderStyle::to_name));
self
}
pub fn table_padding(&mut self, padding: f32) -> &mut Self {
self.dict.pair(Name(b"TPadding"), padding);
self
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum BlockAlign {
Begin,
Middle,
After,
Justify,
}
impl BlockAlign {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Begin => Name(b"Begin"),
Self::Middle => Name(b"Middle"),
Self::After => Name(b"After"),
Self::Justify => Name(b"Justify"),
}
}
}
impl<'a> LayoutAttributes<'a> {
pub fn column_count(&mut self, count: i32) -> &mut Self {
self.dict.pair(Name(b"ColumnCount"), count);
self
}
pub fn column_widths(&mut self) -> TypedArray<'_, f32> {
self.dict.insert(Name(b"ColumnWidths")).array().typed()
}
pub fn column_gap(&mut self) -> TypedArray<'_, f32> {
self.dict.insert(Name(b"ColumnGap")).array().typed()
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum InlineAlign {
Start,
Center,
End,
}
impl InlineAlign {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Start => Name(b"Start"),
Self::Center => Name(b"Center"),
Self::End => Name(b"End"),
}
}
}
impl LayoutAttributes<'_> {
pub fn line_height(&mut self, height: LineHeight) -> &mut Self {
height.write(self.dict.insert(Name(b"LineHeight")));
self
}
pub fn baseline_shift(&mut self, shift: f32) -> &mut Self {
self.dict.pair(Name(b"BaselineShift"), shift);
self
}
pub fn text_decoration_type(&mut self, decoration: TextDecorationType) -> &mut Self {
self.dict.pair(Name(b"TextDecorationType"), decoration.to_name());
self
}
pub fn text_decoration_color(&mut self, color: [f32; 3]) -> &mut Self {
self.dict
.insert(Name(b"TextDecorationColor"))
.array()
.typed()
.items(color);
self
}
pub fn text_decoration_thickness(&mut self, thickness: f32) -> &mut Self {
self.dict.pair(Name(b"TextDecorationThickness"), thickness);
self
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum LineHeight {
Normal,
Auto,
Custom(f32),
}
impl LineHeight {
pub(crate) fn write(self, obj: Obj) {
match self {
Self::Normal => obj.primitive(Name(b"Normal")),
Self::Auto => obj.primitive(Name(b"Auto")),
Self::Custom(height) => obj.primitive(height),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum TextDecorationType {
None,
Underline,
Overline,
LineThrough,
}
impl TextDecorationType {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::None => Name(b"None"),
Self::Underline => Name(b"Underline"),
Self::Overline => Name(b"Overline"),
Self::LineThrough => Name(b"LineThrough"),
}
}
}
impl LayoutAttributes<'_> {
pub fn glyph_orientation_vertical(&mut self, angle: f32) -> &mut Self {
self.dict.pair(Name(b"GlyphOrientationVertical"), angle);
self
}
}
impl LayoutAttributes<'_> {
pub fn ruby_align(&mut self, align: RubyAlign) -> &mut Self {
self.dict.pair(Name(b"RubyAlign"), align.to_name());
self
}
pub fn ruby_position(&mut self, position: RubyPosition) -> &mut Self {
self.dict.pair(Name(b"RubyPosition"), position.to_name());
self
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum RubyAlign {
Start,
Center,
End,
Justify,
Distribute,
}
impl RubyAlign {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Start => Name(b"Start"),
Self::Center => Name(b"Center"),
Self::End => Name(b"End"),
Self::Justify => Name(b"Justify"),
Self::Distribute => Name(b"Distribute"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum RubyPosition {
Before,
After,
Warichu,
Inline,
}
impl RubyPosition {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Before => Name(b"Before"),
Self::After => Name(b"After"),
Self::Warichu => Name(b"Warichu"),
Self::Inline => Name(b"Inline"),
}
}
}
deref!('a, LayoutAttributes<'a> => Dict<'a>, dict);
pub struct ListAttributes<'a> {
dict: Dict<'a>,
}
writer!(ListAttributes: |obj| Self::start_with_dict(obj.dict()));
impl<'a> ListAttributes<'a> {
pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
dict.pair(Name(b"O"), AttributeOwner::List.to_name());
Self { dict }
}
pub fn list_numbering(&mut self, numbering: ListNumbering) -> &mut Self {
self.dict.pair(Name(b"ListNumbering"), numbering.to_name());
self
}
}
deref!('a, ListAttributes<'a> => Dict<'a>, dict);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ListNumbering {
None,
Disc,
Circle,
Square,
Decimal,
LowerRoman,
UpperRoman,
LowerAlpha,
UpperAlpha,
}
impl ListNumbering {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::None => Name(b"None"),
Self::Disc => Name(b"Disc"),
Self::Circle => Name(b"Circle"),
Self::Square => Name(b"Square"),
Self::Decimal => Name(b"Decimal"),
Self::LowerRoman => Name(b"LowerRoman"),
Self::UpperRoman => Name(b"UpperRoman"),
Self::LowerAlpha => Name(b"LowerAlpha"),
Self::UpperAlpha => Name(b"UpperAlpha"),
}
}
}
pub struct FieldAttributes<'a> {
dict: Dict<'a>,
}
writer!(FieldAttributes: |obj| Self::start_with_dict(obj.dict()));
impl<'a> FieldAttributes<'a> {
pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
dict.pair(Name(b"O"), AttributeOwner::PrintField.to_name());
Self { dict }
}
pub fn role(&mut self, role: FieldRole) -> &mut Self {
self.dict.pair(Name(b"Role"), role.to_name());
self
}
pub fn checked(&mut self, checked: FieldState) -> &mut Self {
self.dict.pair(Name(b"checked"), checked.to_name());
self
}
pub fn description(&mut self, desc: TextStr) -> &mut Self {
self.dict.pair(Name(b"Desc"), desc);
self
}
}
deref!('a, FieldAttributes<'a> => Dict<'a>, dict);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FieldRole {
Button,
CheckBox,
RadioButton,
TextField,
}
impl FieldRole {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Button => Name(b"pb"),
Self::CheckBox => Name(b"cb"),
Self::RadioButton => Name(b"rb"),
Self::TextField => Name(b"tv"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FieldState {
Unchecked,
Checked,
Neutral,
}
impl FieldState {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Unchecked => Name(b"off"),
Self::Checked => Name(b"on"),
Self::Neutral => Name(b"neutral"),
}
}
}
pub struct TableAttributes<'a> {
dict: Dict<'a>,
}
writer!(TableAttributes: |obj| Self::start_with_dict(obj.dict()));
impl<'a> TableAttributes<'a> {
pub(crate) fn start_with_dict(mut dict: Dict<'a>) -> Self {
dict.pair(Name(b"O"), AttributeOwner::Table.to_name());
Self { dict }
}
pub fn row_span(&mut self, row_span: i32) -> &mut Self {
self.dict.pair(Name(b"RowSpan"), row_span);
self
}
pub fn col_span(&mut self, col_span: i32) -> &mut Self {
self.dict.pair(Name(b"ColSpan"), col_span);
self
}
pub fn headers(&mut self) -> TypedArray<'_, Str> {
self.dict.insert(Name(b"Headers")).array().typed()
}
pub fn scope(&mut self, scope: TableHeaderScope) -> &mut Self {
self.dict.pair(Name(b"Scope"), scope.to_name());
self
}
pub fn summary(&mut self, summary: TextStr) -> &mut Self {
self.dict.pair(Name(b"Summary"), summary);
self
}
}
deref!('a, TableAttributes<'a> => Dict<'a>, dict);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum TableHeaderScope {
Row,
Column,
Both,
}
impl TableHeaderScope {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Row => Name(b"Row"),
Self::Column => Name(b"Column"),
Self::Both => Name(b"Both"),
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum AttributeOwner {
Layout,
List,
PrintField,
Table,
Xml,
Html3_2,
Html4,
Oeb,
Rtf1_05,
Css1,
Css2,
User,
}
impl AttributeOwner {
pub(crate) fn to_name(self) -> Name<'static> {
match self {
Self::Layout => Name(b"Layout"),
Self::List => Name(b"List"),
Self::PrintField => Name(b"PrintField"),
Self::Table => Name(b"Table"),
Self::Xml => Name(b"XML-1.00"),
Self::Html3_2 => Name(b"HTML-3.20"),
Self::Html4 => Name(b"HTML-4.01"),
Self::Oeb => Name(b"OEB-1.00"),
Self::Rtf1_05 => Name(b"RTF-1.05"),
Self::Css1 => Name(b"CSS-1.00"),
Self::Css2 => Name(b"CSS-2.00"),
Self::User => Name(b"UserDefined"),
}
}
}