Metadata-Version: 2.4
Name: typemotion
Version: 0.1.0a0
Summary: Lightweight Python text animation engine for transparent video overlays.
Author: aistoy
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Multimedia :: Video
Requires-Python: >=3.11
Requires-Dist: cairocffi>=1.7
Requires-Dist: numpy>=1.26
Requires-Dist: pangocairocffi>=0.7
Requires-Dist: pangocffi>=0.13
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml>=6
Requires-Dist: regex>=2024.0
Description-Content-Type: text/markdown

# typemotion

`typemotion` is a lightweight Python text animation engine for transparent
video overlays. It uses Pango/Cairo for text layout and drawing, plus FFmpeg for
encoding ProRes 4444 MOV output.

This repository is in alpha development. See `engine_design.md`
for the product and architecture design.

## Installation

```bash
pip install typemotion
```

typemotion wraps Pango/Cairo (text layout/drawing) and FFmpeg (encoding). The
Python wheels install via pip, but the **native C libraries are not
pip-managed** — install them once for your OS, then verify with
`typemotion doctor`:

```bash
# macOS
brew install pango cairo glib libffi pkg-config ffmpeg

# Debian / Ubuntu
sudo apt-get install libpango-1.0-0 libpangocairo-1.0-0 libcairo2 libglib2.0-0 ffmpeg

# Fedora
sudo dnf install pango cairo glib2 ffmpeg

# Windows: use WSL (Ubuntu) and the Debian/Ubuntu line above.
```

## Quick start

```bash
typemotion doctor
typemotion render examples/specs/caption.yaml -o /tmp/caption.mov
typemotion render --text "Hello\nTypemotion" --animation char-pop --style caption -o /tmp/text.mov
typemotion preview examples/specs/caption.yaml -o /tmp/caption-preview.mp4 --background "#20242a"
typemotion preview examples/specs/glow-slide.yaml -o /tmp/glow-preview.mp4
typemotion render examples/specs/gradient-title.yaml -o /tmp/gradient.mov
typemotion render examples/specs/keyword-highlight.yaml -o /tmp/keyword.mov
typemotion render examples/specs/highlight-sweep.yaml -o /tmp/highlight-sweep.mov
typemotion render examples/specs/karaoke.yaml -o /tmp/karaoke.mov
typemotion render examples/specs/word-karaoke.yaml -o /tmp/word-karaoke.mov
typemotion preview examples/specs/timeline-segments.yaml -o /tmp/timeline-preview.mp4
typemotion render --preset-file examples/presets/brand-presets.yaml \
  --text "Brand" --style brand_caption --animation brand_pop -o /tmp/brand.mov

# spring easing, metallic (inner glow + shadow), decode, motion blur, bloom, wave warp
typemotion preview examples/specs/spring-pop.yaml    -o /tmp/spring.mp4    --background "#12151a"
typemotion preview examples/specs/metallic-title.yaml -o /tmp/metallic.mp4  --background "#12151a"
typemotion preview examples/specs/decode-title.yaml  -o /tmp/decode.mp4    --background "#12151a"
typemotion preview examples/specs/motion-blur.yaml   -o /tmp/motionblur.mp4 --background "#12151a"
typemotion preview examples/specs/bloom-neon.yaml    -o /tmp/bloom.mp4      --background "#12151a"
typemotion preview examples/specs/wave-text.yaml     -o /tmp/wave.mp4       --background "#12151a"
```

### Layout item source (`self` vs `native`)

`layout.item_source` controls how animated items (char / word / line scope)
are sourced from the text:

- `self` (default): each unit is laid out as an independent Pango layout.
  Cheap, easy to animate per-unit, but loses cross-character shaping and
  ignores `line_spacing` on the char path.
- `native`: one fully-shaped Pango block layout, walked via `LayoutIter` to
  read each cluster/line geometry. Preserves font fallback, complex-script
  shaping, native wrapping and `line_spacing`. Use for complex scripts or
  when typographic fidelity matters.

```bash
typemotion render examples/specs/native-char-pop.yaml -o /tmp/native-char-pop.mov
```

### Style effects are pure Cairo (no Pillow)

The fancy-text effect pipeline (shadow, glow, gradient, image-texture fill) is
implemented entirely with Cairo + numpy — no Pillow dependency.

- **shadow / glow**: the text mask is rasterized to a Cairo surface and blurred
  with a numpy separable box blur (3 passes ≈ Gaussian), then composited via
  `ctx.mask`. No Cairo↔Pillow round-trip.
- **gradient**: native `cairo.LinearGradient` clipped to the text path.
- **texture** (PNG image fill): native `cairo.SurfacePattern` with `EXTEND_REPEAT`
  / `REFLECT`, clipped to the text path. Fills text with a gold-foil / pattern /
  photo texture.

```bash
typemotion render examples/specs/texture-title.yaml -o /tmp/texture.mov
```

```yaml
style:
  preset: outline-bold
  texture: { path: "../assets/gold-texture.png", extend: reflect, scale: 1.0 }
```

### Blend modes, inner styles & post-composite FX

Beyond the core pipeline, typemotion supports AE-style layer compositing and
frame-level effects (all Cairo + numpy, no new dependencies):

- **Blend modes** on glow / shadow / gradient / inner styles — `screen`, `add`,
  `multiply`, `overlay`, `softLight`, … (Cairo native operators). The `neon` preset
  uses `screen` glow for additive light.
- **Inner styles** (`inner_glow`, `inner_shadow`) for depth / metallic titles.
- **Parametric spring** easing (`springSoft` / `springSnappy` / `springBouncy`, or
  `{spring:{zeta,omega}}`) plus the full standard set (elastic, bounce, back, expo, …).
- **Text-animator selectors** (`animation.selector`): range (wave reveal) and wiggly
  (additive float), and **character offset / decode** (`animation.decode`).
- **Post-composite FX** applied to the finished frame: `motion_blur` (directional, or
  sub-frame `accumulate` for scale/rotation/per-char motion), `bloom`, `distortion`
  (wave / bulge / twirl), `grade` (tritone). Compositions take these under a top-level
  `effects:` block.

```yaml
animation:
  keyframes:
    - { t: 0, scale: 0.3 }
    - { t: 1, scale: 1, easing: { spring: { zeta: 0.32, omega: 13 } } }
  motion_blur: { mode: accumulate, samples: 6, shutter_deg: 360 }
  bloom:       { threshold: 0.55, radius: 18, intensity: 0.85 }
```

Preset files can define `styles` and `animations`. A preset may use `extends` to
inherit from a builtin preset and override only the fields that need to change.
Animations can also use declarative timeline tracks or `enter` / `emphasis` /
`exit` segments; see `examples/specs/timeline-segments.yaml`.

For the full YAML format reference (all style/animation fields, the animatable
property surface, keyframe/modifier/stagger syntax, and worked examples), see
[`docs/yaml_reference.md`](docs/yaml_reference.md).
