summaryrefslogtreecommitdiffstats
path: root/libass
Commit message (Collapse)AuthorAgeFilesLines
* font: use library as a failure flagDr.Smile2020-10-111-2/+2
| | | | | | ass_font_clear() can now free family string even in a failure case. Fixes https://github.com/libass/libass/issues/414.
* outline: use labs() for FT_PosDr.Smile2020-10-101-1/+1
| | | | | | While FreeType uses FT_Pos for 32-bit values, the real underlying type is signed long, so labs() is more appropriate here.
* blur: fix styleDr.Smile2020-10-091-26/+26
|
* Simplify blur algorithmDr.Smile2020-10-095-1166/+470
| | | | | This commit removes prefilters altogether at the cost of enlarged main filter kernel.
* outline: fix overflows in outline processingDr.Smile2020-10-084-18/+65
| | | | | | | This commit enforces strict invariant on ASS_Outline to contain point coordinates into predetermined range. Fixes https://github.com/libass/libass/issues/431.
* Add more invisible characters to ass_shaper_skip_charactersOleg Oshmyan2020-09-191-1/+5
| | | | | | | | * Bidirectional isolates * Arabic letter mark * Invisible plus * Variation selectors * Mongolian control characters
* Ignore metrics of trimmable whitespace on nonblank linesOleg Oshmyan2020-09-192-8/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Use bool and true/false assignments for GlyphInfo::skipOleg Oshmyan2020-09-193-10/+11
|
* Don't halve nonempty line height even if wholly invisibleOleg Oshmyan2020-09-191-1/+1
| | | | | VSFilter compatibility: VSFilter does no special handling of invisible control characters and sees the line as nonempty.
* Revert "fontselect: expose the freetype-provided family as well"rcombs2020-09-191-7/+9
| | | | | | | | This reverts commit 6c2120a7cb4a6fd648ef37ad8f0d961cbd60f500. This turned out never to actually be necessary, wasn't actually consistent with vsfilter, and could result in script authors relying on accidentally-introduced deviations from vsfilter font matching.
* ass_parse: avoid UB and match vsfilter on negative-accel color animationrcombs2020-09-191-4/+25
| | | | | | | | | | | | | | | | | | | | Providing a negative acceleration to \t could result in undefined behavior due to overflow in float->int conversion. This codifies the same behavior we currently have on x86, which matches vsfilter's, without actually invoking UB. Additionally, vsfilter color animations work subtly differently than ours did. We used to lerp each individual color component's byte value, while vsfilter performs the lerp on the component _in place within a larger int_. This didn't result in major issues for most cases, but could probably result in subtle rounding errors, and gave vastly different results for \t with negative acceleration. Negative \t acceleration is probably completely useless, but our behavior was wacky in a different way from vsfilter's, and I'd rather have portable wackiness than libass-specific wackiness. It might still be possible to invoke UB in negative-acceleration \t using tags other than colors; we should fix those cases as well.
* ass_fontconfig: use FcWeightToOpenTypeDoublercombs2020-09-191-6/+10
| | | | | This provides higher precision in reported weights when using the fontconfig font provider.
* Skip fully parsing \t if there is no backslashOleg Oshmyan2020-09-191-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | The assertion in commit 66cef6774386d558e1e39096db926d677dad6882 fires on the following ASS code: \t(\t(foobar,) (where "foobar" is any nonblank sequence that does not contain a backslash) The outer \t is parsed as having a single argument "\t(foobar," including the comma. The inner \t is parsed as having a single argument "foobar" *excluding* the comma. As a result, in the inner parse_tags, args[cnt].end == end - 1 && nested, and the assert fires. This is because arguments that contain backslashes are parsed differently from arguments that do not. But if the argument to \t contains no backslashes, why bother parsing it at all? It clearly has no override tags and affects nothing. Rather than try to make the assert more clever (and more convoluted), this commit skips parsing the last \t argument if it has no backslash. The assert is now valid. This probably does not significantly affect parsing speed in either direction. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25796.
* Assert finite parse_tags recursionOleg Oshmyan2020-09-081-0/+1
| | | | | | | | | | | | | | | | | | Before commit 6835731c2fe4164a0c50bc91d12c43b2a2b4e799, parse_tags used to recurse for each nested \t(). The depth of this recursion was not limited, and each \t in \t(\t(\t(... added another level. This could lead to stack overflow. Since that commit, parse_tags still recurses, but at most once: it is called with nested=false at the top level and recurses with nested=true for the outermost \t() (except rare cases in which even this one level of recursion is avoided). Parsing stops at the closing ) both for the outermost \t() and for any inner \t() nested inside it, so the inner recursive call cannot recurse further. This was not immediately obvious when reading the code, and therefore it was not obvious that stack overflow is avoided. Make it so by adding an assertion.
* ass.h: Mark deprecated declarations as deprecatedOneric2020-09-081-3/+19
| | | | GCC, Clang and MSVC now issue a warning when deprecated API is used.
* ass_utils: make ass_strtod/strtoll wrappers inlineablercombs2020-08-302-35/+31
| | | | | Also makes a measurable difference on float-parse-heavy scripts, and it's not like these had a reason to not be in the header.
* ass_parse: improve performance of tag name comparisonsrcombs2020-08-301-5/+7
| | | | | | | | | | Yes, this actually makes a major difference on some tag-heavy scripts. This lets the whole function get inlined, rather than making a call out to the libc's strcmp implementation. The libc's version is likely much faster on longer strings, but we're only ever comparing against strings that are a few characters long, so that doesn't really matter. It also avoids making an extra pass for the strlen.
* render: match VSFilter's behavior when painting fill in shadow/borderrcombs2020-08-303-13/+33
| | | | | | | Some releases rely on this. See corresponding VSFilter code: https://github.com/Cyberbeing/xy-VSFilter/blob/cf8f5b27de77fe649341bfab0fdfd498e1ad2fa6/src/subtitles/RTS.cpp#L1270 https://github.com/Cyberbeing/xy-VSFilter/blob/cf8f5b27de77fe649341bfab0fdfd498e1ad2fa6/src/subtitles/RTS.cpp#L1291
* Disable bidi bracket matching unless enabled via ASS_FeatureOleg Oshmyan2020-07-146-16/+60
| | | | | | | | | | | | | | | | | | | | | Bracket matching is incompatible with VSFilter (even on modern Windows), so disable it by default. But as it's generally a good thing (and 100% more compliant with current Unicode), keep it available as an ASS_Feature. It can be toggled individually or enabled as part of the catch-all ASS_FEATURE_INCOMPATIBLE_EXTENSIONS feature. If libass is compiled against FriBidi older than 1.0, bracket matching is impossible. Signal this at runtime by failing to recognize the ASS_FEATURE_BIDI_BRACKETS feature. This way, clients who want to use bracket matching can set the feature without any compile-time checks for FriBidi and can be freely linked against libass that is itself compiled against any version of FriBidi; and yet they can detect at runtime whether the feature is actually enabled. Fixes https://github.com/libass/libass/issues/374.
* Extract struct parser_priv into separate header fileOleg Oshmyan2020-07-142-40/+65
|
* Take bool in ass_shaper_set_kerningOleg Oshmyan2020-07-142-3/+4
|
* shaper: drop prealloc parameter of ass_shaper_newOleg Oshmyan2020-07-123-7/+4
| | | | | | The only prealloc value actually used is 0, which is not useful and invokes implementation-defined (and potentially obsolescent as per C11 DR400) behavior.
* Ignore leading space of lines in parsingOneric2020-07-111-0/+1
| | | | | | This more forgiving behaviour resembles VSFilter's more closely and will fix #117 ; trailing whitespace should not be an issue. Though as pointed out in #19 VSFilter is still far more lenient.
* Perform 3D transforms relative to shadow positionOleg Oshmyan2020-07-081-2/+5
| | | | | | | | | | | | | | | | | | | | Fixes https://github.com/libass/libass/issues/141. Fixes https://github.com/libass/libass/issues/300. VSFilter's original intention with this seems to have been to transform the event as a whole, including the shadows as an integral part, as opposed to transforming the shadows separately: imagine the event being rasterized into a single image including the shadows, and then that image being transformed. Unfortunately, due to a caching bug, what actually ends up happening is that the shadow is transformed the intended way, but the main body is then simply shifted back by \shad from the transformed & rasterized shadow, instead of being transformed & rasterized on its own. The result seems sensible if you look at the shadow only but incomprehensible if you look at the main body. Transforms with \shad are actually used and this behavior is relied upon, as evidenced by https://github.com/libass/libass/issues/300 (in which the main body is made invisible and the shadow is used instead of it due to having \t-animatable position and full-area blur despite \bord).
* Change 'ScaledBorderAndShadow' default to '0'.Oneric2020-07-061-1/+1
| | | | This is *VSFilter compatible and fixes #287.
* Detect subs converted to ASS by ffmpeg/libavOneric2020-07-061-1/+71
| | | | | | | ffmpeg/libav did rely on *VSFilter incompatible libass defaults for years. Avoid breaking them when changing libass' default to match *VSFilter. To this end detection of the generated by ffmpeg signature is added.
* Default 'ScaledBorderAndShadow' to yes for custom format filesOneric2020-07-061-29/+95
| | | | | | | | Keeps backwards compatibility as libass is currently the only renderer accepting custom format lines and is currently defaulting SBAS to 'yes' (VSF incompatible) This commit also changes the default/fallback ASS Event format to use 'Name' instead of 'Actor'.
* Track which [Script Info] headers have been setOneric2020-07-061-0/+36
| | | | And warn about duplicate headers
* Take border into account during collision detectionOneric2020-07-052-8/+29
| | | | | | | | closes #304 With this commit the padding of the BorderStyle=4 box, given by \shad, is no longer measured from the text without borders, but from the border of the text. (Alternative description: padding changed from \shad to \shad+\bord)
* Refactor: Avoid code duplication in measure_textOneric2020-07-051-6/+11
|
* Match *VSF's shift direction for \an(4|5|6)Oneric2020-07-051-1/+1
| | | | | | closes #143 As libass doesn't support the 'Collsions' header, we are only concerned with the default stacking direction of *VSF here
* ass_shaper: fix harfbuzz deprecation warning; closes #320rcombs2020-07-051-7/+23
|
* Style-Nit: Adjust whitespacesOneric2020-07-056-20/+20
| | | | | | | - Convert tabs to spaces - Ensure one space between keywords and parenthesis - Ensure space between ')' and '{' - Trim trailing whitespace
* Supress -Wimplicit-fallthrough warnings for false positivesOneric2020-07-051-3/+3
|
* ass_font: fix typo in zero height checkOleg Oshmyan2020-07-051-1/+1
|
* font: simplify metrics handling; fixes #361rcombs2020-07-051-39/+26
| | | | | We used to do a lot of work to get freetype to imitate VSFilter's font-metrics handling. Instead, we now just duplicate its behavior directly early on.
* Fix incorrect collision detection coordinates with anamorphic videoOleg Oshmyan2020-07-051-1/+1
| | | | device_x is in anamorphic coordinates, the product of x2scr (not x2scr_scaled).
* renderer: fix default aspect ratio calculationOleg Oshmyan2020-07-051-4/+4
| | | | | | The ratio was accidentally flipped. Use the actual video size, not the screen size that includes margins.
* renderer: fix subtitles to full screen frame iff use_marginsOleg Oshmyan2020-07-053-54/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Based on a commit by wm4. Nowadays, margins are used by players such as mpv to implement video zoom & pan, although this was not expected when margins were first implemented in libass. This results in unpleasant rendering when panning too far, and it is argued that subtitles should not change size or move when panning and zooming at all. libass also makes an attempt to keep subtitles on screen even when the use of margins is disabled. This is unintuitive and prone to break. Fix this by strictly separating events which render as if they were part of the video, and events which should use margins. The latter will now use the entire screen as canvas, rather than using the video frame. This actually simplifies the various y2scr functions. To preserve scaling (mainly for styled subtitles where line breaks are carefully chosen based on font/video size ratio) and to avoid badly stretching out things like ASS Margins due to aspect ratio differences between video and screen, estimate the unpanned & unzoomed video size from the video aspect ratio and the screen size, and base all scaling on that. This means that if the user plays a video in letterboxed mode without extra margins, they get the same scaling as if they were playing the same video with the same video rectangle size without any margins at all (with some elements merely spaced out to make use of the black bars); and when they zoom & pan afterwards, the subtitles don't move or change size. This changes behavior even with ass_set_use_margins(_, 0). Before this, normal dialogue was forced into the visible video area (if negative margins were set); now it renders it as if it were part of the video. This also changes the behavior of left and right margins even with ass_set_use_margins(_, 1). Before this, normal dialogue was forced into the visible video width (with both positive and negative margins); now it renders across the entire width of the screen/window. For 4:3 video letterboxed on 16:9 screen, this means text will cross the edges of the video, which may look worse than before.
* renderer: remove bogus clip rect for unclipped subtitleswm42020-07-051-0/+6
| | | | | | | | | | | | | | Normal subtitles in use_margins mode, which do not have \clip tags or similar, were clipped in a nonsensical way. It was especially visible when moving subtitles up with ass_set_line_position(). This happened because state.clip_* is initialized with a clipping rectangle for the video area. Later it tries to translate the clipping rect accordingly, but this does not make much sense if you account for the margins. Just reset the clipping rect to the screen in these cases. explicit=0 is enough to know that the clipping rect was never explicitly set.
* Update names in copyright headersrcombs2020-05-294-4/+4
|
* ass_render: fix crash on parse_events failure after a drawingrcombs2020-05-271-1/+3
| | | | Closes #397
* render: silence a couple LLVM static analyzer warningsrcombs2020-05-261-4/+4
| | | | | | | | The while() checked the pointer for nullness, so the analyzer assumed it could potentially be null, and thus warned on the reference to it later. Using a do/while instead means we're only checking for subsequent linked-list entries, which was the intent here anyway, and avoids the warning.
* render: handle failure to realloc max_glyphsrcombs2020-05-261-10/+14
|
* render: handle more allocation failures in ass_renderer_initrcombs2020-05-261-12/+19
|
* render: allow passing null to ass_renderer_donercombs2020-05-261-0/+3
|
* render: reorder context fields to eliminate paddingrcombs2020-05-261-13/+14
|
* x86/cpuid: fix missing includercombs2020-05-261-0/+2
|
* fontselect: fix leak on errorrcombs2020-05-261-0/+1
|
* coretext: fix leak on errorrcombs2020-05-261-5/+6
|
* ass.c: add assert to silence analyzer warningrcombs2020-05-261-0/+1
|
* Fix libtool versionOleg Oshmyan2020-03-301-2/+2
|
* api: add ass_track_set_feature()wm42020-03-294-2/+46
| | | | | | | | Since C does not allow empty enums, there is an "example", which doesn't do anything. I think we might be able to make this change the default bidi direction or so. As if this commit, the flag set by it is also not available outside of ass.c, which should be solved by moving parser_priv to an internal header.
* API: clarify how new fields can be added to public typeswm42020-03-292-0/+5
| | | | | | | | This just gives a minor hint that all fields are frozen, but that the size of the structs are not part of the ABI. Most importantly, ASS_Style and ASS_Event are completely ABI-frozen, because ASS_Track has the "styles" and "events" arrays.
* ass_blur: check for memory allocation size overflowswm42020-03-061-1/+7
| | | | | | | | | Check for overflows that could happen with alignment and the multiplication. The INT_MAX / 4 is somewhat approximate and assumes that degenerate alignment values won't happen. This still assumes that a possibly overflowing end_w/end_h calculation doesn't make the compiler's optimizer destroy the overflow checks.
* parse: fix setting font size when no font is loaded; fixes #365rcombs2020-01-061-10/+1
|
* render: silence warningRodger Combs2019-11-071-1/+1
|
* coretext: move meta var into loop and zero-initializeRodger Combs2019-11-071-4/+1
| | | | | This makes it a bit clearer that the struct's contents won't be reused across multiple iterations
* fontselect: leave returned struct in a valid state on errorRodger Combs2019-11-071-0/+3
| | | | This fixes a double-free in be0d1613f79a95073d18d96a60e1394abf9316a2
* parse_tags: fix case where t==t1==t2Rodger Combs2019-11-071-1/+1
| | | | | This previously gave the pre-transition value; VSFilter's behavior is to give the post-transition value.
* coretext: fix error handling in get_font_fileMarvin Scholz2019-11-071-1/+7
| | | | | | | | Fixes a crash in case a font does not has kCTFontURLAttribute, which is the case for example on macOS 10.15.1 for the ".AppleSymbolsFB" font. Fix #358
* coretext: replace CT attr reads with freetype lookupsRodger Combs2019-09-261-112/+24
| | | | | This makes results much more consistent with other platforms, particularly around cases where fonts have multiple conflicting names.
* fontselect: add overflow checkRodger Combs2019-09-261-2/+2
|
* fontselect: expose the freetype-provided family as wellRodger Combs2019-09-261-9/+7
|
* fontselect: provide a way to use freetype to get font infoRodger Combs2019-09-26<