summaryrefslogtreecommitdiffstats
path: root/libass/ass_render.h
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2020-08-17 00:07:33 +0300
committerOleg Oshmyan <chortos@inbox.lv>2020-09-19 17:51:11 +0300
commit236bc18d39c080853d1145c7b978fb8f47e31deb (patch)
treebe1026775f8c4cd073a74b26cd99b38c3fbd51a4 /libass/ass_render.h
parent014cbcc3801a498151c7559662d9ce85d41e4948 (diff)
downloadlibass-236bc18d39c080853d1145c7b978fb8f47e31deb.tar.bz2
libass-236bc18d39c080853d1145c7b978fb8f47e31deb.tar.xz
Ignore metrics of trimmable whitespace on nonblank lines
Fixes https://github.com/libass/libass/issues/418. Fixes https://github.com/libass/libass/issues/427. Fixes https://github.com/mpv-player/mpv/issues/7712. A longstanding problem we had was that we ignored leading line breaks in events. We somewhat accidentally assigned line breaks zero height, and the code in `measure_text` that halved the height of empty lines explicitly ignored leading empty lines for some reason. #285 fixed both of these things: the former in e8d98dafb8d4d1fd80e9d398cfbef7db1e2ccb73, the latter in 5d03af99c6d8f43be973cb6dacb5d6dd0ada33b1. But life is not so simple! It turns out that VSFilter [discards metrics of the line break and leading/trailing spaces for lines that stay nonempty after whitespace trimming][1]. So we actually handled nonblank (trimmable-space-less) lines correctly *before* #285 and have been *mishandling* them since #285 landed, adding the line break's metrics when they should be ignored. This is not noticeable in plain text, but it affects cases when a line's contents have a different height from the line breaks: {\fs96}foo\N{\p1}m 0 0 l 0 1 1 1 1 0{\p0}\Nbar {\fs96}foo\N{\fs1}bar{\fs96}\Nbaz (the middle line should be 1px high, not 96px) [1]: https://github.com/Cyberbeing/xy-VSFilter/blob/3.0.0.306/src/subtitles/RTS.cpp#L1401-L1422 More complicated cases with trimmable spaces have never been handled correctly, but this is nevertheless a regression. To fix this: * move the `trim_whitespace` call before the `measure_text` call (they seem independent, so this is easy), * mark trimmed whitespace with a new dedicated flag in addition to `.skip` so it can be distinguished from invisible glyphs, * clear accumulated (line-leading-whitespace) metrics when each line's first non-trimmed-whitespace glyph is found, * skip trimmed-whitespace glyphs when the line is already proven nonblank, because they are certainly line-trailing whitespace. Note: line breaks themselves do have `.skip` and `.is_trimmed_whitespace`. Note: our `.linebreak` is set on the glyph *after* the line break. As a result, a nonblank line will include the metrics only of the glyphs that (would) remain after trimming leading and trailing whitespace (including the line break), while a blank line includes the metrics of all glyphs from its first in-line glyph up to and including the terminating line break (if any). At the same time, line height is only halved for lines that are truly empty and don't even contain any whitespace. (Before the halving, the line height comes from the line break glyph.) This matches VSFilter.
Diffstat (limited to 'libass/ass_render.h')
-rw-r--r--libass/ass_render.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/libass/ass_render.h b/libass/ass_render.h
index 3cb0e1c..93f661a 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -124,6 +124,7 @@ typedef struct {
typedef struct glyph_info {
unsigned symbol;
bool skip; // skip glyph when layouting text
+ bool is_trimmed_whitespace;
ASS_Font *font;
int face_index;
int glyph_index;