Skip to main content

inset_embedder/
caption_style.rs

1//! The user's caption style: how the system's settings say subtitles and captions are to look,
2//! read beside the cues a player hands out, which carry the media's own styling alone ([`Cue`]).
3//! The systems that keep caption settings give the same ones, and tell when the user changes
4//! them: Apple's `MACaptionAppearance`, Android's `CaptioningManager` with its `CaptionStyle`, and
5//! Windows' `ClosedCaptionProperties`, which Chromium's `ui/native_theme/caption_style` reads on
6//! Windows and macOS. Linux and the web keep none, and a platform there answers no
7//! [`CaptionSettings`].
8//!
9//! Each setting says whether it applies always, over what the media says, or only where the media
10//! says nothing, as Apple's `MACaptionAppearanceBehavior` says of each of its settings: Chromium's
11//! and WebKit's cue style sheets make the first `!important` and leave the second for the media's
12//! own style to override. A setting the system gives no value for is `None`, as Android's
13//! `hasForegroundColor` false and Windows' `Default` say.
14//!
15//! The app merges the style into each cue as it draws it, as Media3's `SubtitleView` applies its
16//! `CaptionStyleCompat`; the host merges nothing.
17//!
18//! [`Cue`]: crate::Cue
19
20use crate::{Color, CueTextEdge, MediaChangeFuture};
21
22/// The user's system-wide caption settings: Apple's `MACaptionAppearance`, Android's
23/// `CaptioningManager`, Windows' `ClosedCaptionProperties`.
24pub trait CaptionSettings {
25    /// The style the user set, each setting saying whether it applies always or only where the
26    /// media says nothing.
27    fn style(&self) -> CaptionStyle;
28
29    /// Resolves at the next change of the style, as a player's `changed()` does.
30    fn changed(&self) -> MediaChangeFuture;
31}
32
33/// What the system's settings say of how subtitles and captions look.
34#[derive(Clone, Debug, Default, PartialEq)]
35pub struct CaptionStyle {
36    /// The text's colour, opaque: Apple's foreground colour, Android's `foregroundColor`,
37    /// Windows' `FontColor`.
38    pub foreground_color: Option<CaptionSetting<Color>>,
39    /// The text's opacity, from `0.0` to `1.0`: Apple's foreground opacity, the alpha of Android's
40    /// `foregroundColor`, Windows' `FontOpacity`.
41    pub foreground_opacity: Option<CaptionSetting<f64>>,
42    /// The colour behind each character, opaque: Apple's background colour, Android's
43    /// `backgroundColor`, Windows' `BackgroundColor`.
44    pub background_color: Option<CaptionSetting<Color>>,
45    /// The opacity behind each character: Apple's background opacity, the alpha of Android's
46    /// `backgroundColor`, Windows' `BackgroundOpacity`.
47    pub background_opacity: Option<CaptionSetting<f64>>,
48    /// The colour of the box behind a whole cue, opaque: Apple's window colour, Android's
49    /// `windowColor`, Windows' `RegionColor`.
50    pub window_color: Option<CaptionSetting<Color>>,
51    /// The opacity of the box behind a whole cue: Apple's window opacity, the alpha of Android's
52    /// `windowColor`, Windows' `RegionOpacity`.
53    pub window_opacity: Option<CaptionSetting<f64>>,
54    /// The radius the box's corners are rounded by, in logical pixels: Apple's window rounded
55    /// corner radius, which Chromium and WebKit read as the cue's `border-radius`.
56    pub window_corner_radius: Option<CaptionSetting<f64>>,
57    /// What is drawn round the characters: Apple's text edge style, Android's `edgeType`, Windows'
58    /// `FontEffect`.
59    pub edge: Option<CaptionSetting<CueTextEdge>>,
60    /// The colour of the edge, with its opacity: Android's `edgeColor`. Apple and Windows give
61    /// none.
62    pub edge_color: Option<CaptionSetting<Color>>,
63    /// The font: Apple's font for its default style, Android's typeface, Windows' `FontStyle`.
64    pub typeface: Option<CaptionSetting<CaptionTypeface>>,
65    /// How many times its own size text is drawn at: Apple's relative character size, Android's
66    /// `getFontScale`, Windows' `FontSize` as a fraction.
67    pub text_scale: Option<CaptionSetting<f64>>,
68}
69
70/// One of the user's caption settings, and whether it applies over what the media says.
71#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72pub struct CaptionSetting<T> {
73    pub value: T,
74    pub behavior: CaptionBehavior,
75}
76
77impl<T> CaptionSetting<T> {
78    /// `value`, applied over what the media says.
79    pub fn always(value: T) -> CaptionSetting<T> {
80        CaptionSetting {
81            value,
82            behavior: CaptionBehavior::Always,
83        }
84    }
85
86    /// `value`, applied where the media says nothing.
87    pub fn where_media_says_nothing(value: T) -> CaptionSetting<T> {
88        CaptionSetting {
89            value,
90            behavior: CaptionBehavior::WhereMediaSaysNothing,
91        }
92    }
93}
94
95/// When a caption setting applies: Apple's `MACaptionAppearanceBehavior`.
96#[derive(Clone, Copy, Debug, PartialEq, Eq)]
97pub enum CaptionBehavior {
98    /// Over what the media says: Apple's `UseValue`, a setting Chromium's and WebKit's cue style
99    /// sheets mark `!important`.
100    Always,
101    /// Only where the media says nothing: Apple's `UseContentIfAvailable`, and every setting of
102    /// Android's, which Media3 draws beneath a cue's embedded styles.
103    WhereMediaSaysNothing,
104}
105
106/// The font captions are drawn in.
107#[derive(Clone, Debug, PartialEq, Eq)]
108pub enum CaptionTypeface {
109    /// A font family by name: the family of the font Apple's settings give for their default
110    /// style, or Android's typeface by its family name, such as `serif-monospace`.
111    Family(String),
112    /// A kind of font, as caption standards (CEA-708) name them and Windows gives the user's
113    /// choice.
114    Generic(GenericCaptionFont),
115}
116
117/// The kinds of font caption standards name: Windows' `ClosedCaptionStyle` and Apple's
118/// `MACaptionAppearanceFontStyle`, their defaults aside.
119#[derive(Clone, Copy, Debug, PartialEq, Eq)]
120pub enum GenericCaptionFont {
121    MonospacedWithSerifs,
122    ProportionalWithSerifs,
123    MonospacedWithoutSerifs,
124    ProportionalWithoutSerifs,
125    Casual,
126    Cursive,
127    SmallCapitals,
128}