summaryrefslogtreecommitdiffstats
path: root/libass/ass_parse.c
Commit message (Collapse)AuthorAgeFilesLines
* cache: construct cache values only from corresponding keysDr.Smile2019-05-191-4/+1
| | | | | | | | | | | | | | | | | | | | 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.
* drawing: separate drawing text reading from outline constructionDr.Smile2019-05-191-20/+11
| | | | Purpose of this commit is to simplify logic behind drawing handling.
* parse_tags: handle argumentless \t inside \t() like VSFilterOleg Oshmyan2018-01-081-5/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | \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.
* parse_tags: don't recurse for nested \t()Oleg Oshmyan2018-01-081-1/+11
| | | | | | | | | | | | | 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.
* Move parse_tag loop into parse_tag itself, now called parse_tagsOleg Oshmyan2018-01-051-586/+586
| | | | This commit is mostly transparent to `git blame -w`.
* Replace FreeType types with libass native typesDr.Smile2017-09-171-4/+3
| | | | | | 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.
* stroker: implement fast two-outline strokerDr.Smile2017-07-311-35/+0
|
* Reuse numpad2align in parse_tagOleg Oshmyan2017-02-141-8/+3
|
* parse_tag: don't consume *end == ')' when called recursivelyOleg Oshmyan2016-12-291-1/+1
| | | | | This did not cause any problems, but it's nicer to guarantee that the return value is <= end.
* Fix buffer overread in parse_tag when end points to a spaceOleg Oshmyan2016-12-291-3/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* cache: keep ref_count of all active objects nonzeroDr.Smile2016-06-301-1/+1
|
* Fully fix compilation with MSVC/ICLOleg Oshmyan2015-09-171-0/+1
| | | | | | | | | 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>
* ass_parse: add check against ass_drawing_new() failurewm42015-09-071-8/+9
| | | | | Also move the argument parsing part to the top of the function. IT's easier to read this way.
* fontselect: fix oblique/italic mixupGrigori Goronzy2015-07-101-1/+1
| | | | The constants were swapped. In some cases this lead to incorrect matching.
* Use TrueType font weight scaleGrigori Goronzy2015-07-101-3/+3
| | | | | | | | | | 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.
* Custom font matching and font sourcesGrigori Goronzy2015-07-101-2/+1
| | | | | | | 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.
* Simplify change_alpha and change_colorOleg Oshmyan2015-05-251-6/+4
|
* Apply fade only when the fade alpha is positive (like VSFilter)Oleg Oshmyan2015-05-251-3/+3
|
* parse_tag: split \[1-4][ac]Oleg Oshmyan2015-05-251-47/+49
|
* Parse and animate all colors and alpha values like VSFilterOleg Oshmyan2015-05-251-26/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Refine list of tags that prevent selective style overrideswm42015-03-061-4/+7
| | | | | | | 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)
* More malloc checkingwm42014-11-171-3/+1
| | | | | | | | | | 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.
* Fix \fade(7-argument version) parseMaks Naumov2014-08-231-2/+2
|
* ass_parse: remove 2 unused variableswm42014-06-091-2/+0
| | | | Fallout from the previous commits.
* Simplify drawing text assignmentOleg Oshmyan2014-06-061-1/+1
|
* parse_tag: remove unnecessary mallocOleg Oshmyan2014-06-061-8/+2
|
* Require closing '}' for override tagsOleg Oshmyan2014-06-061-12/+9
| | | | | | | | 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.
* Introduce ass_drawing_add_chars for adding a whole string at onceOleg Oshmyan2014-06-061-4/+3
|
* Parse override tag arguments exactly like VSFilter 2.38Oleg Oshmyan2014-06-061-236/+308
| | | | | Also replace strtocolor in ass_utils with string2color from ass.c, because that is more useful everywhere now.
* parse_tag: merge \fs+, \fs-, \fsOleg Oshmyan2014-06-061-18/+7
|
* parse_tag: split \fscx, \fscy, \fscOleg Oshmyan2014-06-061-23/+20
|
* Add a mechanism for selective style overrideswm42014-06-051-0/+26
| | | | | | | | | | | | | | | 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.
* Fix \1a, \2a, \3a, \4a with invalid argumentOleg Oshmyan2014-05-121-0/+2
| | | | Reset to the initial color's alpha component, not red.
* Reset clipping mode on every rectangle \clipOleg Oshmyan2014-05-121-0/+1
| | | | | | | | 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.
* Make \be animatableOleg Oshmyan2014-05-121-2/+5
| | | | | | | 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).
* Fix corner case: \move with identical start and end timesOleg Oshmyan2014-05-121-2/+2
|
* Parser: don't increment render_priv->state.bm_run_id (unnecessary)11rcombs2014-01-251-14/+0
|
* Combine bitmaps before applying blur and shadow11rcombs2014-01-251-0/+1
|
* Start \k, \ko at exact start time, not right after itOleg Oshmyan2014-01-241-1/+1
|
* Remove some ass_msg() callswm42014-01-241-12/+0
| | | | | | | 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).
* Fix \fade corner casesOleg Oshmyan2014-01-151-9/+14
| | | | | | | | 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.
* Fix \t corner casesOleg Oshmyan2014-01-151-20/+17
| | | | | The end time is reset to line duration if and only if it is zero. Negative accelerations are allowed (and can cause overflow later).
* Do not reset \pbo and \p values after each drawingOleg Oshmyan2014-01-081-4/+3
| | | | Confirmed with VSFilter. This complements the previous commit.
* A whole bunch of parsing and default value fixesOleg Oshmyan2014-01-071-116/+111
| | | | Obtained by reading the xy-VSFilter source code.
* Fix \fs+ and \fs-Oleg Oshmyan2014-01-071-2/+2
| | | | The argument is a relative amount. The unit is: \fs+1 = +10%.
* Stop animating \b and \iOleg Oshmyan2014-01-071-12/+8
| | | | Unlike what the cc635086 message says, VSFilter does not animate them.
* Stop misparsing and add support for \fscOleg Oshmyan2014-01-071-0/+4
|
* Support fractional \org argumentsOleg Oshmyan2014-01-071-4/+4
|
* Fix \r style lookupOleg Oshmyan2013-06-221-1/+1
| | | | | Make \rSTYLENAME with an invalid STYLENAME fall back to line style rather than to Default. This fixes issue #104.
* Clip tag arguments are not optionalwm42013-04-121-2/+2
| | | | | | | | | | | | | | | 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.
* Ignore junk in nested \t tagswm42013-03-311-3/+2
| | | | | | | | | | | | | | | | 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.)
* Fix crazy VSFilter behavior for \move tagwm42013-03-201-1/+9
| | | | Fixes issue 90 (both cases).
* Make closing ')' optional for some ASS tagswm42013-01-121-5/+5
| | | | | | | | | 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.
* Fix a wrong condition.Xidorn Quan2012-12-141-1/+1
|
* Terminate drawings immediately on a \p0 tagwm42012-09-291-20/+2
| | | | | | | | | | | | | | | | 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.
* Fix resetting border style with \rSTYLEwm42012-09-291-2/+2
| | | | | | | | | 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.
* Refactor and fix border generationGrigori Goronzy2012-04-211-19/+30
| | | | | Make sure to update the border appropriately in the second pass, after parsing.
* Support \rSTYLENAME syntaxGrigori Goronzy2012-03-111-1/+12
| | | | | This allows to reset to a certain style, instead of the default style for the current line. For some reason, this was completely missing.
* Fix off-by-one error in \fad, \fadeGrigori Goronzy2011-08-291-4/+5
| | | | | | | | | | 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.
* Use the "font encoding" property as a base direction hintGrigori Goronzy2011-07-151-0/+5
| | | | | | | | | | 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.
* Separate event parsing and layoutGrigori Goronzy2011-07-041-6/+7
| | | | | | Split up the combined event parsing and layout loop into two passes. State information needed for layout are duplicated in GlyphInfo structures.
* Introduce bitmap runsGrigori Goronzy2011-07-041-0/+13
| | | | | | | | 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.
* Use bare outlines for drawingsGrigori Goronzy2011-06-201-6/+2
| | | | | | | 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.
* refactor: move karaoke effect parsing into event parserGrigori Goronzy2011-06-061-0/+71
|
* Match first occurence of \fade, \fad, \an and \a tagsGrigori Goronzy2011-05-301-9/+18
| | | | | Track if we already parsed a fade or a alignment tag and ignore all further tags.
* Add support for \fs+ and \fs- syntaxGrigori Goronzy2010-08-121-0/+16
| | | | | | | 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.
* Get rid of NULL checks for freeGrigori Goronzy2010-08-091-2/+1
| | | | | The useless "if (foo) free(foo)" idiom is all over the place, just get rid of it finally...
* Fix drawing leakage: delay glyph allocationGrigori Goronzy2010-08-091-3/+4
| | | | | | Delay allocation of the "faux" glyph until a drawing is parsed. This helps with fixing a (pretty bad) memory leak and also reduces frame