mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-25 02:30:15 -06:00
- Engine: slide_overlay (OverlaySettings in prefs.json, the new slideshow.overlays
command): identity plate (text, or a PNG/JPEG file with its transparency; size,
colour, opacity; render behind image), rating stars (own vector stars), up to 16
text overlays with tokens ({caption}, {exposure}, {file}, {date}, {focal}… plus
every rename token; unknown tags show as typed and are reported) and a drop
shadow, each at one of nine anchors of the slide or photo plus an offset, kept on
the slide; the export watermark on the photo. Sizes relative to the slide's
shorter side; validated and clamped.
- Drawn by the engine as a second pass over lightcraft_slideshow::compose_with
(new behind hook for "render behind image"); the watermark's text renderer moved
to engine text.rs (TextLayout, Inter + craft-fonts CJK) and is shared; glyphs
off the image are skipped so huge text stays cheap.
- rename::expand_tokens_with lets overlays add tokens without changing rename.
- Playback composes slides when overlays are on; slideshow.preview returns each
overlay's box. Settings > Slideshow > Overlays section with live preview.
- Docs: parity row (partial), whats-new, control/MCP docs, nine locale catalogs.
- Tests: tokens, nine anchors, star count, plate image opacity and missing file,
text shadow, resolution independence, hostile input, big-slide cost, CJK with
craft-fonts, prefs persistence, preview and headless playback pixel checks.
24 lines
1.5 KiB
Rust
24 lines
1.5 KiB
Rust
//! Slideshow slides for LightCraft: the settings of Lightroom Classic's Slideshow Layout, Options
|
||
//! and Backdrop panels ([`SlideSettings`]) and the CPU composer that draws one slide from a
|
||
//! rendered photo ([`compose`]).
|
||
//!
|
||
//! No UI and no catalog here: playback, the settings preview, the `slideshow.preview` command and
|
||
//! (later) slideshow export all call [`compose`], so every one of them draws the same pixels.
|
||
//!
|
||
//! **Resolution independence:** every length is relative to the slide: margins, the stroke width
|
||
//! and the shadow's offset and radius are fractions of the slide's *shorter side* (so linked
|
||
//! margins are equal in pixels, and a slide composed at two sizes has the same proportions).
|
||
//! Angles are degrees counter-clockwise from the right (−45° points down and to the right).
|
||
//!
|
||
//! **Never crash:** settings are validated by [`SlideSettings::merged`] (a wrong type is an error)
|
||
//! and clamped by [`SlideSettings::sanitized`] (NaN, ±∞, negative and huge values land in range);
|
||
//! [`compose`] accepts any size and any photo (an empty one draws the backdrop alone).
|
||
#![forbid(unsafe_code)]
|
||
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
||
|
||
mod compose;
|
||
mod settings;
|
||
|
||
pub use compose::{Layout, Rect, compose, compose_with, layout, photo_size};
|
||
pub use settings::{Aspect, MARGIN_MAX, MAX_SIDE, SHADOW_OFFSET_MAX, SHADOW_RADIUS_MAX, STROKE_MAX, SlideSettings, hex, parse_color};
|