mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
fix(core,player,app): styled subtitles keep their size and place unless restyled
mpv's default sub-ass-override, `scale`, hands an ASS track sub-scale, and sub-pos reaches it under every mode but `no`. So with "Restyle styled subtitles" off, the subtitle size and position settings still resized and moved typeset dialogue and signs. The override is now `yes` when restyling is off, which keeps sub-scale off ASS. A styled track also ignores the style's position, and moves only to stay clear of the player's controls. A frame from an ASS track rendered with every other option changed now matches the untouched one pixel for pixel. Plain (SRT) tracks still take the whole style.
This commit is contained in:
1 parent
69d961d7b8
commit
ffd6e959bb
6 files changed
+78
-29
No files matched your search
@@ -302,6 +302,11 @@ impl Playback {
|
||||
} else {
|
||||
100.0
|
||||
};
|
||||
self.place_subtitles();
|
||||
}
|
||||
|
||||
/// Move subtitles to [`Self::subtitle_position`], when that has changed.
|
||||
fn place_subtitles(&mut self) {
|
||||
let position = self.subtitle_position();
|
||||
if position != self.subtitle_position {
|
||||
self.subtitle_position = position;
|
||||
@@ -311,8 +316,21 @@ impl Playback {
|
||||
|
||||
/// Where subtitles go: where the style puts them, unless the controls
|
||||
/// would cover that, in which case just above the controls.
|
||||
///
|
||||
/// A styled track ignores the style's position unless it is restyled:
|
||||
/// mpv applies `sub-pos` to it either way, and its signs were placed by
|
||||
/// hand. The lift still applies, because a line under the seek bar cannot
|
||||
/// be read however carefully it was placed.
|
||||
fn subtitle_position(&self) -> f64 {
|
||||
self.subtitle_style.position.min(self.lifted_position)
|
||||
let styled = self
|
||||
.selected_track(TrackKind::Subtitle)
|
||||
.is_some_and(|track| is_styled(track.codec.as_deref()));
|
||||
let position = if styled && !self.subtitle_style.restyle_styled {
|
||||
100.0
|
||||
} else {
|
||||
self.subtitle_style.position
|
||||
};
|
||||
position.min(self.lifted_position)
|
||||
}
|
||||
|
||||
/// Restyle the subtitles of this file, now.
|
||||
@@ -409,7 +427,11 @@ impl Playback {
|
||||
PlayerEvent::FileLoaded => self.loaded = true,
|
||||
PlayerEvent::Volume(volume) => self.volume = *volume,
|
||||
PlayerEvent::Muted(muted) => self.muted = *muted,
|
||||
PlayerEvent::Tracks(tracks) => self.tracks = tracks.clone(),
|
||||
PlayerEvent::Tracks(tracks) => {
|
||||
self.tracks = tracks.clone();
|
||||
// A switch between a plain and a styled track moves the line.
|
||||
self.place_subtitles();
|
||||
}
|
||||
PlayerEvent::Chapters(chapters) => {
|
||||
self.chapters = chapters.clone();
|
||||
self.reclassify();
|
||||
@@ -516,6 +538,11 @@ fn build_player(
|
||||
Ok((Arc::new(player), None))
|
||||
}
|
||||
|
||||
/// Whether a subtitle codec carries its own styling, as mpv names them.
|
||||
fn is_styled(codec: Option<&str>) -> bool {
|
||||
matches!(codec, Some("ass" | "ssa"))
|
||||
}
|
||||
|
||||
/// The player defaults with the viewer's preferences folded in.
|
||||
fn from_prefs(
|
||||
prefs: &PlaybackPrefs,
|
||||
@@ -863,3 +890,17 @@ fn save(
|
||||
watch_state(position, duration, watched),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn only_ass_and_ssa_tracks_count_as_styled() {
|
||||
assert!(is_styled(Some("ass")));
|
||||
assert!(is_styled(Some("ssa")));
|
||||
assert!(!is_styled(Some("subrip")));
|
||||
assert!(!is_styled(Some("hdmv_pgs_subtitle")));
|
||||
assert!(!is_styled(None));
|
||||
}
|
||||
}
|
||||
@@ -432,14 +432,14 @@ fn languages(ui: &mut egui::Ui, playback: &PlaybackPrefs, actions: &mut Vec<Acti
|
||||
/// How subtitles look, with a sample line to judge it by.
|
||||
///
|
||||
/// Every change reaches a playing file as it is made, so the film itself is
|
||||
/// the other preview. A styled track takes only the size and the position
|
||||
/// unless it is asked to take the rest; see [`SubtitleStyle`].
|
||||
/// the other preview. A styled track takes none of it unless it is asked to;
|
||||
/// see [`SubtitleStyle`].
|
||||
fn subtitle_form(ui: &mut egui::Ui, style: &SubtitleStyle, actions: &mut Vec<Action>) {
|
||||
ui::widgets::settings_group(
|
||||
ui,
|
||||
"Subtitles",
|
||||
Some(
|
||||
"Changes show on the playing video straight away. Plain subtitles (SRT) take all of this; styled ones (ASS) only the size and the position, unless you restyle them below.",
|
||||
"Changes show on the playing video straight away. Plain subtitles (SRT) take all of this; styled ones (ASS) keep their own look unless you restyle them below.",
|
||||
),
|
||||
|ui| {
|
||||
let mut chosen = style.clone();
|
||||
@@ -532,7 +532,7 @@ fn subtitle_form(ui: &mut egui::Ui, style: &SubtitleStyle, actions: &mut Vec<Act
|
||||
ui,
|
||||
"Restyle styled subtitles",
|
||||
Some(
|
||||
"Repaint styled (ASS) dialogue in this style too. Signs, songs and karaoke can come out wrong.",
|
||||
"Draw styled (ASS) dialogue in this style too, size and position included. Signs, songs and karaoke can come out wrong.",
|
||||
),
|
||||
|ui| {
|
||||
ui::widgets::toggle(ui, &mut chosen.restyle_styled, "");
|
||||
|
||||
Reference in new issue
Block a user