| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
The only prealloc value actually used is 0, which is not useful
and invokes implementation-defined (and potentially obsolescent
as per C11 DR400) behavior.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
|
|
|
|
|
|
|
| |
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)
|
| |
|
|
|
|
|
|
| |
closes #143
As libass doesn't support the 'Collsions' header, we are only concerned with the
default stacking direction of *VSF here
|
|
|
|
| |
device_x is in anamorphic coordinates, the product of x2scr (not x2scr_scaled).
|
|
|
|
|
|
| |
The ratio was accidentally flipped.
Use the actual video size, not the screen size that includes margins.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
Closes #397
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
shift_event() can change "bitmap" field of ASS_Image struct
so direct deallocation is no longer possible.
This commit introduces additional field "buffer"
into ASS_ImagePriv for that purpose.
Fixes https://github.com/libass/libass/issues/310.
|
|
|
|
| |
Found by Coverity Scan and -fsanitize=undefined
|
|
|
|
|
|
|
|
|
|
|
|
| |
Slow movement of one glyph looks like periodic jumps by quantization step.
In case of multiple glyphs at different subpixel shifts
jumps of individual glyphs occur at different frames.
That leads to performance penalty due to composite image
regeneration at every such jump.
This commit aligns glyphs in such a way that all jumps coincide
at the same frames, greatly improving performance of \move commands.
That optimization also helps in case of fast motion.
|
| |
|
|
|
|
|
|
|
|
|
| |
This also potentially improves performance by copying
and transforming in a single operation rather than
copying first and then transforming the result.
Also transformation function is specialized for case
where expensive perspective division is not necessary.
|
| |
|
|
|
|
|
|
| |
Render logic should depend only on input subs
and not on some internal state such as bitmap pointers.
That can prevent incorrect behavior in case of allocation failure.
|
|
|
|
| |
Fixes https://github.com/libass/libass/pull/309.
|
|
|
|
| |
Compatibility flag FILTER_DRAW_SHADOW has removed completely.
|
|
|
|
|
|
| |
Now ass_synth_blur() blurs one bitmap only.
Higher level decisions (to blur or not to blur)
have moved outside of that function.
|
|
|
|
|
| |
This allows to use Bitmap struct directly as cache value
and to remove bunch of unnecessary allocations.
|
| |
|
|
|
|
|
|
|
| |
Integral pixel shift is extracted in quantization function now,
taking account of full glyph transformation and not only translation
part of it. It makes program logic more straight and ensures that
subpixel shift from cache key never exceed full pixel.
|
|
|
|
|
| |
Accuracy of border outline calculation should depend on subsequent
transformation.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit defers all outline transformations until rasterization stage.
Combined transformation is then quantized and used as bitmap key.
That should improve performance of slow animations.
Also caching of initial and stroked outlines and bitmaps is now separate
in preparation to proper error estimation for stroker stage.
Note that Z-clipping for perspective transformations is now done
differently compared to VSFilter. That clipping is mostly safety feature
to protect from overflows and divisions by zero and is almost never
triggered in real-world subtitles.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit forces construction of cache values using only data
available in its companion keys. That ensures logical correctness:
keys are guaranteed to have all the necessary data, and prevents
accidental collisions.
Most fixes of cache logic correspond to minor problem
when rendering is done with double parameter but cache key stores
its approximate fixed-point representation. The only serious problem
is missing scale of clip drawing. Also this commit removes unused
scale parameters from glyph metrics cache key.
Due to missing scale clip shapes that differed only in scale
treated by cache system as identical. That can lead to incorrect reuse
of cached bitmap of different scale instead of correct one.
The only hack left is in glyph metrics cache with its
unicode >= VERTICAL_LOWER_BOUND check.
|
| |
|
|
|
|
|
| |
Leading newlines are now rendered, but still incorrectly:
at full height rather than at half-height as required.
|
|
|
|
|
| |
Note that return value is reversed in parse_events(),
ass_render_event() and ass_start_frame() functions.
|
|
|
|
| |
Purpose of this commit is to simplify logic behind drawing handling.
|
|
|
|
|
| |
Drawings always have advance.y = 0 and
FreeType guarantees that for horizontal writing.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Previously each \r triggered full rescan of event string.
After this commit such scanning is done once in init_render_context().
Additionally some lines have moved around to correctly account for
state.evt_type (calculated in apply_transition_effects) and
state.explicit (used in reset_render_context).
That should fix cases with incorrectly applied style overrides
for subs with banner scrolling effect before the first \r.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
\t with no parantheses inside \t() resets the animation parameters
of the \t() for subsequent tags, so they are animated as if the \t()
was the single-argument version regardless of the actual number
of arguments the \t() has.
Equivalently, you could say parentheses are implied for \t inside \t().
For example, \t(20,60,\frx0\t\fry0\frz0) animates \frx from 20 to 60 ms
and animates \fry and \frz for the whole duration of the line,
just like \t(20,60,\frx0)\t(\fry0\frz0) or \t(20,60,\frx0\t(\fry0\frz0)).
Technically, VSFilter simply resets the animation parameters for any \t
it encounters but parses the embedded tags only if the \t has the right
number of arguments. However, top-level animation parameters don't matter
because top-level tags are not animated, while any nested \t that has
parentheses terminates the containing \t because they share the closing
parenthesis, so the fact that a nested \t with empty parentheses or with
at least four arguments changes the animation parameters also doesn't
matter because the containing \t immediately ends and the changed
parameters have nothing to apply to. Thus the only situation where
this has a visible effect is a nested \t without parentheses.
Closes https://github.com/libass/libass/pull/296.
|
|
|
|
| |
This commit is mostly transparent to `git blame -w`.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
FT_Vector and FT_BBox types are based on FT_Pos, which is alias of long.
FreeType treats it as 32-bit integer, but on some platforms long can be
64-bit. That leads to wasted memory and suboptimal performance.
|
|
|
|
| |
Found by coverity scan.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Text background refers to the libass-only BorderStyle 4, which is
similar to 3, but isn't affected by outline/border size and doesn't
render shadow, so shadow offset can be used.
You can override the horizontal and vertical box size separately
with override tags, just like you can override the color with
shadow color.
Closes #270
|
|
|
|
|
|
|
| |
The value used to generate outline cache values is 26.6, so there
is no point in storing the more precise 16.16 in the cache key.
Indeed, this can only reduce the efficiency of the cache
and provide an extra opportunity for overflow.
|
|
|
|
|
|
|
|
|
| |
border_scale can change, e. g. when ass_render_frame is called twice with
the same renderer but different tracks. Glyphs with equal \bord tag values
but different border_scale values produce different border outlines and
hence should be distinguished in outline cache keys. To this end, store
scaled border widths (which are really used when generating the outlines)
in cache keys instead of \bord tag values.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
has_clips was a workaround for the case where a new image reused
the same memory address as another image used in the previous frame.
In case of such reuse, comparison by pointer address failed
to distinguish the different images in ass_detect_change().
After commit dd06ca30ea79ce50116a43cc5521d4eaf60a017e,
images in the previous frame are no longer freed before
the comparison with current frame. Thus no such reuse can occur,
and the workaround is redundant.
See https://github.com/libass/libass/pull/258.
|
|
|
|
|
|
|
|
| |
ASS_Images returned by libass are guaranteed to be clipped. Not doing
this will cause invalid memory accesses in applications which try to use
this guarantee.
Fixes #254.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Subtitle recommendations often include that multi line
subtitles should be left justified as this is easier for
the eyes. This is also the standard used by several television
companies.
This add the possibility to define how subtitles are to
be justified, independently of where they are aligned.
The most common way could be to set justify to left, and have
alignment to center. But you can, for example, have alignment
to left and justify to center, giving subtitles to the left but
justifed on the center (instead of normal left justified).
Using justify right and alignment of center, might be good
choice for Arabic.
If justify is not defined, all works like before.
If justify is defined, subtitles are aligned as defined
by alignment and justified as defined by justify.
ASS is not extended by this, justify can only be defined
by setting Justify to wanted justification.
|
| |
|