after-effects 0.4.0

High level bindings for the Adobe After Effects® SDK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
use crate::*;
use bitflags::bitflags;
use std::{
    fmt::Debug,
    marker::PhantomData,
};

mod command;    pub use command::*;
mod events;     pub use events::*;
mod gpu;        pub use gpu::*;
mod handles;    pub use handles::*;
mod in_data;    pub use in_data::*;
mod layer;      pub use layer::*;
mod out_data;   pub use out_data::*;
mod parameters; pub use parameters::*;
mod pixel;      pub use pixel::*;
mod render;     pub use render::*;
mod effect;     pub use effect::*;
mod interact_callbacks;    pub use interact_callbacks::*;
mod util_callbacks;        pub use util_callbacks::*;
mod external_dependencies; pub use external_dependencies::*;

pub mod suites {
    pub(crate) mod adv_item;              pub use adv_item            ::AdvItemSuite               as AdvItem;
    pub(crate) mod background_frame;      pub use background_frame    ::BackgroundFrameSuite       as BackgroundFrame;
    pub(crate) mod cache_on_load;         pub use cache_on_load       ::CacheOnLoadSuite           as CacheOnLoad;
    pub(crate) mod channel;               pub use channel             ::ChannelSuite               as Channel;
    pub(crate) mod color_callbacks;       pub use color_callbacks     ::{ ColorCallbacksSuite      as ColorCallbacks,
                                                                          ColorCallbacks16Suite    as ColorCallbacks16,
                                                                          ColorCallbacksFloatSuite as ColorCallbacksFloat };
    pub(crate) mod effect_sequence_data;  pub use effect_sequence_data::EffectSequenceDataSuite    as EffectSequenceData;
    pub(crate) mod effect_ui;             pub use effect_ui           ::EffectUISuite              as EffectUI;
    pub(crate) mod app;                   pub use app                 ::{ AppSuite                 as App,
                                                                          AdvAppSuite              as AdvApp };
    pub(crate) mod custom_ui;             pub use custom_ui           ::{ EffectCustomUISuite      as EffectCustomUI,
                                                                          EffectCustomUIOverlayThemeSuite as EffectCustomUIOverlayTheme };
    pub(crate) mod iterate;               pub use iterate             ::{ Iterate8Suite            as Iterate8,
                                                                          Iterate16Suite           as Iterate16,
                                                                          IterateFloatSuite        as IterateFloat };
    pub(crate) mod pixel_data;            pub use pixel_data          ::PixelDataSuite             as PixelData;
    pub(crate) mod pixel_format;          pub use pixel_format        ::PixelFormatSuite           as PixelFormat;
    pub(crate) mod source_settings;       pub use source_settings     ::SourceSettingsSuite        as SourceSettings;
    pub(crate) mod transition;            pub use transition          ::TransitionSuite            as Transition;
    pub(crate) mod utility;               pub use utility             ::UtilitySuite               as Utility;
    pub(crate) mod world;                 pub use world               ::WorldSuite                 as World;
    pub(crate) mod world_transform;       pub use world_transform     ::WorldTransformSuite        as WorldTransform;
    pub(crate) mod handle;                pub use handle              ::HandleSuite                as Handle;
    pub(crate) mod helper;                pub use helper              ::{ HelperSuite              as Helper,
                                                                          HelperSuite2             as Helper2 };
    pub(crate) mod param_utils;           pub use param_utils         ::{ ParamUtilsSuite          as ParamUtils,
                                                                          AngleParamSuite          as AngleParam,
                                                                          ColorParamSuite          as ColorParam,
                                                                          PointParamSuite          as PointParam };
    pub(crate) mod gpu_device;            pub use gpu_device          ::GPUDeviceSuite             as GPUDevice;
    pub(crate) mod fill_matte;            pub use fill_matte          ::FillMatteSuite             as FillMatte;
    pub(crate) mod path;                  pub use path                ::{ PathQuerySuite           as PathQuery,
                                                                          PathDataSuite            as PathData };
}

pub use suites::adv_item::Step;
pub use suites::app::{
    AppColorType,
    AppPersonalTextInfo,
    AppProgressDialog,
    CursorType,
    EyeDropperSampleMode,
    FontStyleSheet,
};
pub use suites::custom_ui::{
    ContextHandle,
    CustomUIInfo,
};
pub use suites::channel::{
    DataType,
    ChannelType,
};
pub use suites::helper::{
    SuiteTool,
    ExtendedSuiteTool
};
pub use suites::param_utils::{
    PARAM_INDEX_NONE,
    PARAM_INDEX_CHECK_ALL,
    PARAM_INDEX_CHECK_ALL_EXCEPT_LAYER_PARAMS,
    PARAM_INDEX_CHECK_ALL_HONOR_EXCLUDE,
    TimeDir,
};
pub use suites::pixel_format::PixelFormat;
pub use suites::path::{
    MaskMode,
    PathOutline,
    PathSegPrep,
};

define_enum! {
    ae_sys::PF_XferMode,
    TransferMode {
        None                 = ae_sys::PF_Xfer_NONE,
        Copy                 = ae_sys::PF_Xfer_COPY,
        Behind               = ae_sys::PF_Xfer_BEHIND,
        InFront              = ae_sys::PF_Xfer_IN_FRONT,
        Dissolve             = ae_sys::PF_Xfer_DISSOLVE,
        Add                  = ae_sys::PF_Xfer_ADD,
        Mulitply             = ae_sys::PF_Xfer_MULTIPLY,
        Screen               = ae_sys::PF_Xfer_SCREEN,
        Overlay              = ae_sys::PF_Xfer_OVERLAY,
        SoftLight            = ae_sys::PF_Xfer_SOFT_LIGHT,
        HardLight            = ae_sys::PF_Xfer_HARD_LIGHT,
        Darken               = ae_sys::PF_Xfer_DARKEN,
        Lighten              = ae_sys::PF_Xfer_LIGHTEN,
        Difference           = ae_sys::PF_Xfer_DIFFERENCE,
        Hue                  = ae_sys::PF_Xfer_HUE,
        Saturation           = ae_sys::PF_Xfer_SATURATION,
        Color                = ae_sys::PF_Xfer_COLOR,
        Luminosity           = ae_sys::PF_Xfer_LUMINOSITY,
        MultiplyAlpha        = ae_sys::PF_Xfer_MULTIPLY_ALPHA,
        MultiplyAlphaLuma    = ae_sys::PF_Xfer_MULTIPLY_ALPHA_LUMA,
        MultiplyNotAlpha     = ae_sys::PF_Xfer_MULTIPLY_NOT_ALPHA,
        MultiplyNotAlphaLuma = ae_sys::PF_Xfer_MULTIPLY_NOT_ALPHA_LUMA,
        AddiditivePremul     = ae_sys::PF_Xfer_ADDITIVE_PREMUL,
        AlphaAdd             = ae_sys::PF_Xfer_ALPHA_ADD,
        ColorDodge           = ae_sys::PF_Xfer_COLOR_DODGE,
        ColorBurn            = ae_sys::PF_Xfer_COLOR_BURN,
        Exclusion            = ae_sys::PF_Xfer_EXCLUSION,
        Difference2          = ae_sys::PF_Xfer_DIFFERENCE2,
        ColorDodge2          = ae_sys::PF_Xfer_COLOR_DODGE2,
        ColorBurn2           = ae_sys::PF_Xfer_COLOR_BURN2,
        LinearDodge          = ae_sys::PF_Xfer_LINEAR_DODGE,
        LinearBurn           = ae_sys::PF_Xfer_LINEAR_BURN,
        LinearLight          = ae_sys::PF_Xfer_LINEAR_LIGHT,
        VividLight           = ae_sys::PF_Xfer_VIVID_LIGHT,
        PinLight             = ae_sys::PF_Xfer_PIN_LIGHT,
        HardMix              = ae_sys::PF_Xfer_HARD_MIX,
        LighterColor         = ae_sys::PF_Xfer_LIGHTER_COLOR,
        DarkerColor          = ae_sys::PF_Xfer_DARKER_COLOR,
        Subtract             = ae_sys::PF_Xfer_SUBTRACT,
        Divide               = ae_sys::PF_Xfer_DIVIDE,
        Reserved0            = ae_sys::PF_Xfer_RESERVED0,
        Reserved1            = ae_sys::PF_Xfer_RESERVED1,
        NumModes             = ae_sys::PF_Xfer_NUM_MODES,
    }
}

pub type XferMode = TransferMode;

#[derive(Debug, Copy, Clone, Hash)]
pub struct CompositeMode {
    pub xfer: TransferMode,
    /// For TransferMode::DissolveRandomized.
    pub rand_seed: i32,
    /// 0-255.
    pub opacity: u8,
    /// Ignored TransferMode::MutiplyAlpha* modes.
    pub rgb_only: bool,
    /// For deep color only.
    pub opacity_su: u16,
}

impl Default for CompositeMode {
    fn default() -> Self {
        Self {
            xfer: TransferMode::None,
            rand_seed: 0,
            opacity: 255,
            rgb_only: false,
            opacity_su: MAX_CHANNEL16 as _,
        }
    }
}

impl From<ae_sys::PF_CompositeMode> for CompositeMode {
    fn from(mode: ae_sys::PF_CompositeMode) -> Self {
        Self {
            xfer: mode.xfer.into(),
            rand_seed: mode.rand_seed,
            opacity: mode.opacity,
            rgb_only: mode.rgb_only != 0,
            opacity_su: mode.opacitySu,
        }
    }
}
impl From<CompositeMode> for ae_sys::PF_CompositeMode {
    fn from(mode: CompositeMode) -> Self {
        Self {
            xfer: mode.xfer.into(),
            rand_seed: mode.rand_seed,
            opacity: mode.opacity,
            rgb_only: mode.rgb_only as _,
            opacitySu: mode.opacity_su,
        }
    }
}

define_struct! {
    ae_sys::PF_Point,
    #[derive(Eq)]
    Point {
        h: i32,
        v: i32,
    }
}
impl Point {
    pub fn empty() -> Self {
        Self { h: 0, v: 0 }
    }
}

define_struct! {
    ae_sys::PF_RationalScale,
    #[derive(Eq)]
    RationalScale {
        num: i32,
        den: u32,
    }
}
impl RationalScale {
    pub fn inv(&self) -> RationalScale {
        RationalScale { num: self.den as _, den: self.num as _ }
    }
}

impl From<RationalScale> for f64 {
    #[inline]
    fn from(ratio: RationalScale) -> Self {
        debug_assert!(
            ratio.den != 0,
            "Denominator is zero. This would lead to a division by zero."
        );
        ratio.num as Self / ratio.den as Self
    }
}

impl From<RationalScale> for f32 {
    #[inline]
    fn from(ratio: RationalScale) -> Self {
        debug_assert!(
            ratio.den != 0,
            "Denominator is zero. This would lead to a division by zero."
        );
        ratio.num as Self / ratio.den as Self
    }
}
define_enum! {
    ae_sys::PF_MaskFlags,
    MaskFlags {
        None      = ae_sys::PF_MaskFlag_NONE,
        Inverted  = ae_sys::PF_MaskFlag_INVERTED,
        Luminance = ae_sys::PF_MaskFlag_LUMINANCE,
    }
}

#[derive(Debug)]
pub struct MaskWorld {
    pub mask: ae_sys::PF_EffectWorld,
    pub offset: Point,
    pub what_is_mask: MaskFlags,
}
impl From<ae_sys::PF_MaskWorld> for MaskWorld {
    fn from(mask: ae_sys::PF_MaskWorld) -> Self {
        Self {
            mask: mask.mask,
            offset: Point {
                v: mask.offset.v,
                h: mask.offset.h,
            },
            what_is_mask: mask.what_is_mask.into(),
        }
    }
}
impl From<MaskWorld> for ae_sys::PF_MaskWorld {
    fn from(mask: MaskWorld) -> Self {
        Self {
            mask: mask.mask,
            offset: ae_sys::PF_Point {
                v: mask.offset.v,
                h: mask.offset.h,
            },
            what_is_mask: mask.what_is_mask.into(),
        }
    }
}

define_enum! {
    ae_sys::PF_Quality,
    Quality {
        DrawingAudio = ae_sys::PF_Quality_DRAWING_AUDIO,
        Lo           = ae_sys::PF_Quality_LO,
        Hi           = ae_sys::PF_Quality_HI,
    }
}

define_enum! {
    ae_sys::PF_ModeFlags,
    ModeFlags {
        AlphaPremul   = ae_sys::PF_MF_Alpha_PREMUL,
        AlphaStraight = ae_sys::PF_MF_Alpha_STRAIGHT,
    }
}

define_enum! {
    ae_sys::PF_Field,
    Field {
        Frame = ae_sys::PF_Field_FRAME,
        Upper = ae_sys::PF_Field_UPPER,
        Lower = ae_sys::PF_Field_LOWER,
    }
}
define_enum! {
    ae_sys::PF_TimeDisplay,
    TimeDisplay {
        Fps24        = ae_sys::PF_TimeDisplay_24,
        Fps25        = ae_sys::PF_TimeDisplay_25,
        Fps30Drop    = ae_sys::PF_TimeDisplay_30Drop,
        Fps30NonDrop = ae_sys::PF_TimeDisplay_30NonDrop,
        Fps50        = ae_sys::PF_TimeDisplay_50,
        Fps60Drop    = ae_sys::PF_TimeDisplay_60Drop,
        Fps60NonDrop = ae_sys::PF_TimeDisplay_60NonDrop,
        NonStandard  = ae_sys::PF_TimeDisplay_NonStandard,
        Invalid      = ae_sys::PF_TimeDisplay_Invalid,
    }
}

define_handle_wrapper!(EffectBlendingTables, PF_EffectBlendingTables);

define_enum! {
    ae_sys::PF_ParamIndex,
    ParamIndex {
        None                      = ae_sys::PF_ParamIndex_NONE,
        CheckAll                  = ae_sys::PF_ParamIndex_CHECK_ALL,
        CheckAllExceptLayerParams = ae_sys::PF_ParamIndex_CHECK_ALL_EXCEPT_LAYER_PARAMS,
        CheckAllHonorExclude      = ae_sys::PF_ParamIndex_CHECK_ALL_HONOR_EXCLUDE,
    }
}

pub type ProgPtr = ae_sys::PF_ProgPtr;

bitflags! {
    #[derive(Copy, Clone, Debug)]
    pub struct CustomEventFlags: ae_sys::A_long {
        const NONE    = ae_sys::PF_CustomEFlag_NONE    as ae_sys::A_long;
        const COMP    = ae_sys::PF_CustomEFlag_COMP    as ae_sys::A_long;
        const LAYER   = ae_sys::PF_CustomEFlag_LAYER   as ae_sys::A_long;
        const EFFECT  = ae_sys::PF_CustomEFlag_EFFECT  as ae_sys::A_long;
        const PREVIEW = ae_sys::PF_CustomEFlag_PREVIEW as ae_sys::A_long;
    }
}

bitflags! {
    #[derive(Copy, Clone, Debug)]
    struct _UIAlignment: ae_sys::A_long {
        // No values other than PF_UIAlignment_NONE are honored, in Ae or PPro.
        const NONE   = ae_sys::PF_UIAlignment_NONE   as ae_sys::A_long;
        const TOP    = ae_sys::PF_UIAlignment_TOP    as ae_sys::A_long;
        const LEFT   = ae_sys::PF_UIAlignment_LEFT   as ae_sys::A_long;
        const BOTTOM = ae_sys::PF_UIAlignment_BOTTOM as ae_sys::A_long;
        const RIGHT  = ae_sys::PF_UIAlignment_RIGHT  as ae_sys::A_long;
    }
}

bitflags! {
    #[derive(Copy, Clone, Debug)]
    pub struct Modifiers: ae_sys::A_long {
        const NONE            = ae_sys::PF_Mod_NONE            as ae_sys::A_long;
        /// Cmd on macOS, Ctrl on Windows.
        const CMD_CTRL_KEY    = ae_sys::PF_Mod_CMD_CTRL_KEY    as ae_sys::A_long;
        const SHIFT_KEY       = ae_sys::PF_Mod_SHIFT_KEY       as ae_sys::A_long;
        const CAPS_LOCK_KEY   = ae_sys::PF_Mod_CAPS_LOCK_KEY   as ae_sys::A_long;
        /// Option on macOS, alt on Windows.
        const OPT_ALT_KEY     = ae_sys::PF_Mod_OPT_ALT_KEY     as ae_sys::A_long;
        /// Mac control key only
        const MAC_CONTROL_KEY = ae_sys::PF_Mod_MAC_CONTROL_KEY as ae_sys::A_long;
    }
}

bitflags! {
    #[derive(Copy, Clone, Debug)]
    pub struct WorldFlags: ae_sys::A_long {
        const DEEP        = ae_sys::PF_WorldFlag_DEEP as ae_sys::A_long;
        const WRITEABLE   = ae_sys::PF_WorldFlag_WRITEABLE   as ae_sys::A_long;
        const RESERVED0   = ae_sys::PF_WorldFlag_RESERVED0   as ae_sys::A_long;
        const RESERVED1   = ae_sys::PF_WorldFlag_RESERVED1   as ae_sys::A_long;
        const RESERVED2   = ae_sys::PF_WorldFlag_RESERVED2   as ae_sys::A_long;
        const RESERVED3   = ae_sys::PF_WorldFlag_RESERVED3   as ae_sys::A_long;
        const RESERVED4   = ae_sys::PF_WorldFlag_RESERVED4   as ae_sys::A_long;
        const RESERVED5   = ae_sys::PF_WorldFlag_RESERVED5   as ae_sys::A_long;
        const RESERVED6   = ae_sys::PF_WorldFlag_RESERVED6   as ae_sys::A_long;
        const RESERVED    = ae_sys::PF_WorldFlag_RESERVED    as ae_sys::A_long;
    }
}

#[derive(Default)]
#[repr(transparent)]
pub struct Fixed(ae_sys::PF_Fixed);
impl Fixed {
    pub const ONE: Self = Self(0x00010000);
    pub const HALF: Self = Self(0x00008000);

    pub fn to_int(self) -> i32 {
        self.0 as ae_sys::A_long >> 16
    }
    pub fn to_int_rounded(self) -> i32 {
        (self.0 as ae_sys::A_long + 32768) >> 16
    }
    pub fn from_int(value: i32) -> Self {
        Self(value << 16)
    }
    pub fn as_f32(&self) -> f32 {
        self.0 as f32 / 65536.0
    }

    pub fn as_fixed(&self) -> ae_sys::PF_Fixed {
        self.0
    }
    pub fn from_fixed(value: ae_sys::PF_Fixed) -> Self {
        Self(value)
    }
}
impl From<f32> for Fixed {
    fn from(value: f32) -> Self {
        Fixed((value * 65536.0 + (if value < 0.0 { -0.5 } else { 0.5 })) as _)
    }
}
impl From<Fixed> for f32 {
    fn from(val: Fixed) -> Self {
        val.0 as f32 / 65536.0
    }
}
impl From<Fixed> for f64 {
    fn from(val: Fixed) -> Self {
        val.0 as f64 / 65536.0
    }
}