| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
| |
This previously gave the pre-transition value; VSFilter's behavior is to give
the post-transition value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
\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 fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4892
(stack overflow on deeply nested \t()).
This is possible because parentheses do not nest and the first ')'
terminates the whole tag. Thus something like \t(\t(\t(\t(\t() can be
read in a simple loop with no recursion required. Recursion is also
not required if the ')' is missing entirely and the outermost \t(...
never ends.
See https://github.com/libass/libass/pull/296 for more backstory.
|
|
|
|
| |
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.
|
| |
|
| |
|
|
|
|
|
| |
This did not cause any problems, but it's nicer
to guarantee that the return value is <= end.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When parse_tag is invoked recursively to handle the animated tags inside
a \t tag, the `end` argument is taken from the `end` field of a struct arg
in the enclosing parse_tag. When struct arg is filled by push_arg, this
field is always right-trimmed using rskip_spaces. Ultimately, the inner
parse_tag invokation sees its `end` argument point not to the ')' or '}'
of the \t as it expects but rather to the spaces preceding the ')' or '}'.
At this point, when parse_tag calls skip_spaces, which is ignorant of the
end pointer, it happily skips over the spaces preceding the ')', moving the
pointer past `end`. Subsequent `pointer != end` comparisons in parse_tag
fail (as in fact `pointer > end`), and parse_tag thinks it is still inside
the substring to be parsed.
This is harmless in many cases, but given either of the following inputs,
parse_tag reads past the end of the actual buffer that stores the string:
{\t(\ }
{\t(\ )(}
After this commit, parse_tag knows that `end` can point to a sequence of
spaces and avoids calling skip_spaces on `end`, thus avoiding the overread.
Discovered by OSS-Fuzz.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=194.
|
| |
|
|
|
|
|
|
|
|
|
| |
As before, this does not add any build system support:
a config.h file and a project must still be manually created
(or the compiler can be run manually instead of using a project).
Signed-off-by: Grigori Goronzy <greg@kinoho.net>
Signed-off-by: Oleg Oshmyan <chortos@inbox.lv>
|
|
|
|
|
| |
Also move the argument parsing part to the top of the function. IT's
easier to read this way.
|
|
|
|
| |
The constants were swapped. In some cases this lead to incorrect matching.
|
|
|
|
|
|
|
|
|
|
| |
fontconfig uses an unusual scale from 0-215 for the font weight. It
looks like it is somewhat derived from the typographic scale some font
families use, but is still rather nonstandard. Nowadays the TrueType
scale from 100-900 seems to be standard. CSS uses it, for example.
However, most importantly, VSFilter also uses the TrueType scale. So
let's use it in libass, too.
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Allow exactly one of these prefixes in header values:
0x, 0X, &h, &H. Note that "0x0xFFFFFF" is a correct value,
as the first 0x is consumed by the parser and the second by
the string-to-number conversion following strtol semantics.
* Allow arbitrary numbers of leading & and H
(and not h) in any order in override tag values.
* Reduce header values modulo 2**32 instead
of saturating them to LLONG_MIN/MAX.
* Saturate override tag values to INT32_MIN/MAX
rather than to LLONG_MIN/MAX.
* Don't fiddle with bytes in alpha override tag values.
(They can be outside of the 0..255 range.)
Also change the byte swapping code to be more sensible.
Fixes #80.
Fixes #145.
Fixes #178.
Also fixes our behavior in the case described in
https://code.google.com/p/xy-vsfilter/issues/detail?id=80.
|
|
|
|
|
|
|
| |
Somewhat stolen from:
https://github.com/Cyberbeing/xy-VSFilter/blob/xy_sub_filter_rc3/src/subtitles/RTS.cpp#L2004
(xy-VSFilter started work on this in commit 014da6d9766417d7886eb867c9f2c14038f2a226)
|
|
|
|
|
|
|
|
|
|
| |
Use strndup() instead of malloc+copy.
Make all code deal with the possibility that ASS_Drawing.text can be
NULL (which can happen on allocation failure).
Skip fix_collisions() on malloc failure - the lines will overlap, but at
least libass won't crash.
|
| |
|
|
|
|
| |
Fallout from the previous commits.
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
Like VSFilter. '{' without a following '}' is just text, though
in vector drawing mode it still delimits individual drawings.
This also lets us nicely avoid '\0' hacks
in the \t override tag handler in parse_tag.
|
| |
|
|
|
|
|
| |
Also replace strtocolor in ass_utils with string2color
from ass.c, because that is more useful everywhere now.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds 2 new API functions:
ass_set_selective_style_override()
ass_set_selective_style_override_enabled()
They can be used to force dialog text to use a specific ASS_Style. It
uses a fuzzy heuristic for that, and the quality of results may vary.
It does style overriding selectively and tries not to override things
that need explicit styling. The heuristic for that isn't set in stone
either, and can change with future libass versions.
Closes libass#88.
|
|
|
|
| |
Reset to the initial color's alpha component, not red.
|
|
|
|
|
|
|
|
| |
Prior to this fix, both of the following:
\iclip(0,0,9999,9999)\clip(0,0,9999,9999)
\iclip(0,0,0,0)\clip(0,0,9999,9999)
hid the whole picture in libass. The correct behavior
in both cases is to display the whole picture.
|
|
|
|
|
|
|
| |
VSFilter has supported this since version 2.39.
Use the raw floating-point value of the \be argument in the animation
formula, like xy-VSFilter has done since version 3.0.0.45 (404301a3).
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
These aren't very useful for debugging due to the high volume of the log
output in problem cases. In fact, all they do is making the code slower
(the message callback can easily appear in the profiler output, even if
the callback doesn't actually print the messages).
|
|
|
|
|
|
|
|
| |
Times in \fade(,,,-1,fadein,fadeout,-1)
are interpreted as in \fad(fadein,fadeout).
Make sure we check the times in the same
order as VSFilter in case they are not sorted.
|
|
|
|
|
| |
The end time is reset to line duration if and only if it is zero.
Negative accelerations are allowed (and can cause overflow later).
|
|
|
|
| |
Confirmed with VSFilter. This complements the previous commit.
|
|
|
|
| |
Obtained by reading the xy-VSFilter source code.
|
|
|
|
| |
The argument is a relative amount. The unit is: \fs+1 = +10%.
|
|
|
|
| |
Unlike what the cc635086 message says, VSFilter does not animate them.
|
| |
|
| |
|
|
|
|
|
| |
Make \rSTYLENAME with an invalid STYLENAME fall back to
line style rather than to Default. This fixes issue #104.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This fixes: {\clip(1,1,20,20)\clip\alpha&H1E&\c&HC7E5C0&}X
libass tries to interpret the second \clip, which has no arguments.
Since the parsing code doesn't require a starting '(', the parser will
skip over the other tags (treating them as junk) and interpret the
numbers that happen to be in the rest of the string. The result is a
bogus drawing command, which happens to rasterize an extremely wide
glyph, which takes several seconds to finish.
Make the '(' required. Neither the aegisub manual nor the vsfilter
source code have any indication that \clip without starting '(' is
allowed, so this should not break anything.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Normally, junk between tags is ignored. But unlike vsfilter, libass
doesn't do that inside \t tags. So the following fails and will never
actually switch the color: {\t(1000,1000,(\c&HFF0000&))} (The '(' and
')' are junk, and are not covered by any ASS documentation.)
Instead expecting that the last parameter to \t (the parameter that
takes nested tags) starts with '\', turn it around and assume that the
first parameter that's not a number is the last parameter. (This
parsing is kind of awkward because we don't do any lookahead.)
Likewise, let the nested tag parsing terminate on ')' instead of
checking whether a tag is started with '\'. This allows skipping
junk in the middle of the nested tag, without terminating too early.
(Check '}' and '\0' in case the tag is not properly terminated.)
|
|
|
|
| |
Fixes issue 90 (both cases).
|
|
|
|
|
|
|
|
|
| |
It appears VSFilter generally accepts the tag anyway if closing ')' are
missing in tags like \pos(1,2). Since they're not strictly needed
anyway, make the last ')' optional in order to make parsing more
tolerant against broken subs.
Fixes issue #79.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The parsing code allowed override tags after \p0 to affect the drawing.
This is incorrect. Finish the drawing object as soon as \p0 is
encountered instead.
This requires moving the code executing the style overrides from
get_next_char() in ass_parse.c to the main render loop in
ass_renderer.c, because we have to re-enter the rendering loop
inside of a tag. The old code was simply executing all tags until
a new character could be returned to the renderer loop, mutating up
the state (RenderContext fields) for the drawing after the drawing
was closed, but before it was rendered.
This fixes libass issue #47.
|
|
|
|
|
|
|
|
|
| |
With \rSTYLE, it is possible to change the border style within the same
subtitle event. You can do this by setting a different BorderStyle value
in the newly requested style. VSFilter handles this as expected, while
libass uses a single border style for the whole subtitle event.
This fixes libass issue #56.
|
|
|
|
|
| |
Make sure to update the border appropriately in the second pass, after
parsing.
|
|
|
|
|
| |
This allows to reset to a certain style, instead of the default style
for the current line. For some reason, this was completely missing.
|
|
|
|
|
|
|
|
|
|
| |
Typical greater vs. greater-or-equal case. This especially fixes fades
with zero delays. A zero delay in the two-argument form means no fade at
all, but previously this faded over a single frame, since the code used
"greater" semantics, while "greater or equal" is required here.
Notably, this avoids blinking/flickering in some tightly timed karaoke
scripts.
|
|
|
|
|
|
|
|
|
|
| |
ASS specifies a "font encoding", both in the styles as well as with
the \fe override tag. This font encoding is very Windows-specific
and libass doesn't use it for charmap matching or anything like
that. However, it can be useful for hinting the base direction of
text. Make Hebrew and Arabic encodings switch to RTL base direction,
other languages to LTR and use neutral base direction for the
autodetect setting.
|
|
|
|
|
|
| |
Split up the combined event parsing and layout loop into two passes.
State information needed for layout are duplicated in GlyphInfo
structures.
|
|
|
|
|
|
|
|
| |
Prepare for run-based rendering. In the parser, increment a run id
according to relevant style changes (color, border, shadow, etc.) to
mark the points where a new bitmap needs to be started. Modify the line
wrapper to increment the run ids of each glyph after a break.
Add functions to calculate the render size of runs for rasterization.
|
|
|
|
|
|
|
| |
This finally gets rid of the nasty hack that manipulated a glyph
we somehow got from FreeType. Simplifies drawing handling a bit and
decouples drawing code from all font handling and related (fontconfig,
etc.) code.
|
| |
|
|
|
|
|
| |
Track if we already parsed a fade or a alignment tag and ignore all
further tags.
|
|
|
|
|
|
|
| |
These forms can be used to add or subtract a value from the
current font size instead of setting a new font size. Animations
are supported, but not recommended, as they won't be fluid due to
grid-fitting/hinting.
|