| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
This should help with potential combinatorial explosion.
|
|
|
|
| |
Fixes https://github.com/libass/libass/issues/410.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If static libass is linked into a binary defining functions
of the same name there will be issues. To avoid this use an
ass_ prefix for namespacing.
Before this commit we already did this for most but not yet
all internal API.
read_file is renamed to ass_load_file as ass_read_file
already exists as a public API function. All other functions
are simply prefixed with ass_.
Fixes: https://github.com/libass/libass/issues/222
Fixes: https://github.com/libass/libass/issues/654
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
\kt allows to set the karaoke timing offset to a value other than the
sum of preceeding karaoke durations. Notably this means multiple karaoke
sequences of one Event can be ative at the same time.
Like in VSFilter, \kt is available regardless of the format version.
Using \kt after a karaoke tag in the same override sequence
always makes the preceeding karaoke act as if already completed.
Using \kt within a run resets timing for the next karaoke run.
Addresses part of https://github.com/libass/libass/issues/461.
Further support for v4++ requires at least an ABI break.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Discovered by OSS-Fuzz.
For sufficiently large valued or numerous karaoke tags
the addition to effect_skip_timing can overflow.
Since the operands were signed, this was undefined behaviour.
For utmost VSFilter compatibility, we'd like to ideally emulate its
effective wraparound behaviour. Although the exact order pf calculation
differs, merely ensuring our values safely wraparound too should yield
the same end result.
To that end, we first change the types of the relevant members to
int32_t guaranteeing the same size as in VSFilter and complement-of-two
representation and then also cast one operand to uint32_t.
Through integer promotion both operands will be treated as unsigned,
so any overflow will be (perfectly defined) unsigend overflow.
The final implicit cast back to int32_t is technically implementation
defined and may raise an "implementation-defined signal", but due to
the complement-of-two semantics in pratice we just get a wraparound
matching the wraparaound expected for the original signed
complement-of-two overflow, but while avoiding UB.
Compilers appear to emit the same machine code on x86 with or without
the uint32_t cast, if any optimisations are enabled and otherwise
at most minor differences.
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47993
|
|
|
|
|
|
|
|
|
|
|
| |
font_scale_x is a PAR factor and applies to more than just font glyphs,
so par_scale_x is a more accurate and natural name.
orig_{width,height} can easily be confused with the video's
original (storage) resolution, when in fact it is the rendering
resolution (after any anamorphic desqueezing and other scaling etc)
of the video content area of the whole frame.
Thus rename to frame_content_*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
VSFilter scales several features based on width/PlayResX
but libass until now didn't. This affects:
- explicit vector drawing coordinates
- font spacing
- borders
- shadows
This list was obtained by checking against Cyberbeing/xy-VSFilter
code and searching forevery occurence of m_scalex.
This m_scalex factor is also used for the Banner effect,
to make the delay PlayRes-relative, but in libass the value
is PlayRes-relative by default without needing to be scaled.
Additionally, libass neglected to compensate anamorphic stretching
for some features which is also being fixed now.
Both omissions combined actually happened to cancel each other out
for some PlayRes-relative feature in specific but not unusual cases.
If subs for an anamorphic video use isotropically scaled storage
resolution as PlayRes, libass already rendered e.g. vector drawings
correctly. However, other features like e.g. \xshad used to only render
correctly if isotropically scaled display res was used. Thus, more
complex typesetting actually was never rendered correctly on anamorphic
video before this change.
Fixes https://github.com/libass/libass/issues/171.
|
|
|
|
|
|
|
|
| |
This won't change the movement speed, as the total movement
is recalculated every frame, so this shouldn't negatively affect
VSFilter compatibility; if anything this should slightly improve
compatibility since VSFilter works in a supersampled space.
In any case, it does improves visual quality.
|
|
|
|
|
|
|
|
|
| |
This avoids repeated checks for set storage size
and also makes our zero checks more consistent
instead of sometimes only checking one dimension.
The function will also come in handy outside ass_render.c
in the following commit, so add it to the internal API.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Setting this feature allows breaking lines according to the Unicode
Line Breaking Algorithm and is incompatible with VSFilter.
This is useful for non-ASS renderers utilising libass, especially for
languages typically not using ASCII-spaces to separate words, but
also to correctly break on punctuation even in languages that do. It
does not allow breaking words apart, so line overflow might still occur.
For this to work a new optional dependency on libunibrak is added.
We assume FriBidi's and libunibreak's utf32/glyph type match.
This is based on an earlier patch by GitHub user siikamiika.
|
|
|
|
|
|
|
|
|
| |
And fix reallocation; previously when encountering a line
longer than two times the current max_glyphs, the code would
always underallocate and go to failure handling, even if enough
space could have been allocated.
Prepares Unicode Line Breaking.
|
|
|
|
|
|
|
|
|
|
|
| |
Previously only both only worked when ass_set_fonts was called after all
embedded and memory fonts were already added. Especially for embedded
fonts this meant it won't work for most users, except mpv, including our
own utilities, even if extract_fonts was set.
Now that it works, enable extract_fonts in our utilities.
GitHub: fixes #266
|
|
|
|
| |
That eliminates most uses of strdup() in the rendering process.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Our effect_timing is currently used as a coordinate relative to a weird origin:
take each glyph's center within the run, apply 3D transforms, pick the leftmost
one, and round it down a little. This makes no sense and is the result of an
unrelated code change. But if I recall correctly, \kf positioning was already
incorrect before that last change (but in a different manner).
To fix this and hopefully to prevent this kind of error from occurring again,
convert effect_timing to absolute screen coordinate.
Start the fill at the glyph run's leftmost post-transform control point.
This matches VSFilter and allows karaoke to work in vertical text (unlike,
for example, starting the fill at the first glyph's pre-transform origin).
Fixes https://github.com/libass/libass/issues/216.
Fixes https://github.com/libass/libass/issues/357.
|
| |
|
|
|
|
|
|
|
|
|
| |
Contrary to what the comments suggest Segment does not use one
absolute reference point and relative offsets, but two absolute points,
making it practically identical to the previously defined Rect with
a <-> y0, b <-> y1, ha <-> x0, hb <-> x1
For simplicity replace Segment with Rect.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The "bitmap runs" that are currently used only when combining bitmaps
are also relevant at other stages, mainly for VSFilter compatibility.
They are not currently used because this information is not available
until bitmap combining (except during shaping, which has its own "shape
runs" that duplicate a good chunk of the "bitmap run" logic).
Move some code around to compute run boundaries as early as possible.
This lays the foundation for future commits that will make use this
information in more places where it can simplify code or improve
VSFilter compatibility.
For VSFilter compatibility, rather than break runs immediately upon line
breaks, break runs after line-leading whitespace, even in the first line.
These runs correspond to VSFilter's CWord instances.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
| |
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)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
Purpose of this commit is to simplify logic behind drawing handling.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
Previously was possible to set only bitmap_max_size,
now requested memory amount is divided between
bitmap_max_size and composite_max_size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
| |
That resources can be cached composite bitmap or raw bitmap buffer.
Consequently, free lists are no longer needed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Advantages over the old algorithm consist of the following.
* There are no glitches due to full cache clearing.
Items are arranged into linked list ordered by time of last use.
Only the oldest items get deleted at the clearing event.
* Each item now keeps track of number of references.
Referenced cache values are immune to clearing.
* Reduced amount of total cache memory for the same performance.
* Reduced number of memory allocations per cache item.
|
| |
|
| |
|
|
|
|
|
|
|
| |
Implement a simple font sorter (FontSelector) and an interface to deal
with multiple font sources (FontProvider). Unfinished business,
but works for the most part. Currently the only implemented FontProvider
uses fontconfig.
|