pdf_writer/
transitions.rs

1use super::*;
2
3/// Writer for a _transition dictionary_.
4///
5/// This struct is created by [`Page::transition`].
6pub struct Transition<'a> {
7    dict: Dict<'a>,
8}
9
10writer!(Transition: |obj| {
11    let mut dict = obj.dict();
12    dict.pair(Name(b"Type"), Name(b"Trans"));
13    Self { dict }
14});
15
16impl Transition<'_> {
17    /// Write the `/S` attribute to set the transition style.
18    pub fn style(&mut self, kind: TransitionStyle) -> &mut Self {
19        self.pair(Name(b"S"), kind.to_name());
20        self
21    }
22
23    /// Write the `/D` attribute to set the transition duration.
24    pub fn duration(&mut self, seconds: f32) -> &mut Self {
25        self.pair(Name(b"D"), seconds);
26        self
27    }
28
29    /// Write the `/Dm` attribute to set the transition direction. Will be
30    /// horizontal if the argument is `false`.
31    pub fn dimension(&mut self, vertical: bool) -> &mut Self {
32        let name = if vertical { Name(b"V") } else { Name(b"H") };
33        self.pair(Name(b"Dm"), name);
34        self
35    }
36
37    /// Write the `/M` attribute to set the transition direction. Will be
38    /// inwards if the argument is `false`.
39    pub fn direction(&mut self, outward: bool) -> &mut Self {
40        let name = if outward { Name(b"O") } else { Name(b"I") };
41        self.pair(Name(b"M"), name);
42        self
43    }
44
45    /// Write the `/Di` attribute to set the transition angle.
46    pub fn angle(&mut self, angle: TransitionAngle) -> &mut Self {
47        angle.write_to_obj(self.insert(Name(b"Di")));
48        self
49    }
50
51    /// Write the `/SS` attribute to set the scale for the `Fly` transition.
52    /// PDF 1.5+.
53    pub fn scale(&mut self, scale: f32) -> &mut Self {
54        self.pair(Name(b"SS"), scale);
55        self
56    }
57
58    /// Write the `/B` attribute for the `Fly` transition. PDF 1.5+.
59    pub fn opaque(&mut self, opaque: f32) -> &mut Self {
60        self.pair(Name(b"F"), opaque);
61        self
62    }
63}
64
65deref!('a, Transition<'a> => Dict<'a>, dict);
66
67/// A kind of page transition.
68#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
69pub enum TransitionStyle {
70    /// Split the slide down the middle.
71    Split,
72    /// Multiple lines roll up the slide.
73    Blinds,
74    /// The new slide is revealed in a growing box.
75    Box,
76    /// Single line that sweeps across the slide.
77    Wipe,
78    /// Slide dissolves gradually.
79    Dissolve,
80    /// Like dissolve, but starts on one side.
81    Glitter,
82    /// No effect.
83    #[default]
84    R,
85    /// Changes are flown in. PDF 1.5+.
86    Fly,
87    /// Old page slides out, new page slides in. PDF 1.5+.
88    Push,
89    /// New page slides in to cover the old one. PDF 1.5+.
90    Cover,
91    /// Old page slides out to uncover the new one. PDF 1.5+.
92    Uncover,
93    /// A cross-fade. PDF 1.5+.
94    Fade,
95}
96
97impl TransitionStyle {
98    pub(crate) fn to_name(self) -> Name<'static> {
99        match self {
100            Self::Split => Name(b"Split"),
101            Self::Blinds => Name(b"Blinds"),
102            Self::Box => Name(b"Box"),
103            Self::Wipe => Name(b"Wipe"),
104            Self::Dissolve => Name(b"Dissolve"),
105            Self::Glitter => Name(b"Glitter"),
106            Self::R => Name(b"R"),
107            Self::Fly => Name(b"Fly"),
108            Self::Push => Name(b"Push"),
109            Self::Cover => Name(b"Cover"),
110            Self::Uncover => Name(b"Uncover"),
111            Self::Fade => Name(b"Fade"),
112        }
113    }
114}
115
116/// From where to where a page transition plays.
117#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash)]
118#[allow(missing_docs)]
119pub enum TransitionAngle {
120    #[default]
121    LeftToRight,
122    BottomToTop,
123    RightToLeft,
124    TopToBottom,
125    TopLeftToBottomRight,
126    /// No direction. Only allowed if the transition style is `Fly`.
127    None,
128}
129
130impl TransitionAngle {
131    fn write_to_obj(&self, obj: Obj<'_>) {
132        match self {
133            Self::LeftToRight => obj.primitive(0),
134            Self::BottomToTop => obj.primitive(90),
135            Self::RightToLeft => obj.primitive(180),
136            Self::TopToBottom => obj.primitive(270),
137            Self::TopLeftToBottomRight => obj.primitive(315),
138            Self::None => obj.primitive(Name(b"None")),
139        }
140    }
141}