summaryrefslogtreecommitdiffstats
path: root/libass/ass_render.h
Commit message (Collapse)AuthorAgeFilesLines
* ass_render: move TextInfo into RenderContextrcombs8 days1-2/+1
|
* bitmap_engine: switch to dynamic vtableDr.Smile2022-12-041-1/+1
| | | | This should help with potential combinatorial explosion.
* Use compatible blur parameters on anamorphic videoOleg Oshmyan2022-11-161-1/+2
| | | | Fixes https://github.com/libass/libass/issues/410.
* ass_render: mover rasterizer into RenderContextrcombs2022-11-151-3/+5
|
* ass_render: move shaper member to RenderContextrcombs2022-11-151-3/+3
|
* ass_shaper: move cache ownership to the rendererrcombs2022-11-151-0/+1
|
* ass_render: take RenderContext* in reset_render_context()rcombs2022-11-151-1/+1
|
* ass_render: move (font|border|blur)_scale to RenderContextrcombs2022-11-151-6/+7
|
* ass_render: add text_info member to RenderContextrcombs2022-11-151-0/+1
|
* ass_render: add renderer pointer to RenderContextrcombs2022-11-151-0/+2
|
* refactor: prefix all internal API with ass_Oneric2022-10-221-2/+2
| | | | | | | | | | | | | | | 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
* Implement v4++'s \kt tagOneric2022-10-141-0/+2
| | | | | | | | | | | | | | \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.
* parse: avoid signed overflow for effect_skip_timingOneric2022-09-291-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Rename orig_{width,height} and font_scale_xOneric2022-09-241-6/+6
| | | | | | | | | | | 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_*.
* Fix scaling in x directionOleg Oshmyan2022-09-241-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Allow subpixel movement for legacy effectsOneric2022-09-151-1/+1
| | | | | | | | 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.
* render: simplify storage resolution checksOneric2022-09-091-0/+1
| | | | | | | | | 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.
* Add WRAP_UNICODE featureOneric2022-08-191-0/+1
| | | | | | | | | | | | | 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.
* Move event_text to text_infoOneric2022-08-191-0/+2
| | | | | | | | | 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.
* Fix embedded and memory fontsOneric2021-04-221-0/+1
| | | | | | | | | | | 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
* parsing: use string references for font family and drawing textDr.Smile2021-02-221-3/+3
| | | | That eliminates most uses of strdup() in the rendering process.
* ass_render: fix aliasing when 1a=0 but 3a>0rcombs2021-02-131-0/+1
|
* Improve \kf position roundingOleg Oshmyan2020-10-271-2/+2
|
* Fix \kf fill positioningOleg Oshmyan2020-10-271-3/+8
| | | | | | | | | | | | | | | | | | 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.
* Drop the now-useless, previously-broken first_pos_xOleg Oshmyan2020-10-271-2/+0
|
* ass_render: Replace Segment with RectOneric2020-10-221-5/+0
| | | | | | | | | 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.
* Make harfbuzz a hard dependency; closes #199rcombs2020-10-221-6/+0
|
* Split glyph runs earlyOleg Oshmyan2020-10-191-1/+1
| | | | | | | | | | | | | | | | | | 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.
* Fix Scroll effects with rectangle \clip/\iclipOleg Oshmyan2020-10-181-0/+1
|
* Support Banner/Scroll effects with \pos/\moveOleg Oshmyan2020-10-181-4/+4
|
* Ignore metrics of trimmable whitespace on nonblank linesOleg Oshmyan2020-09-191-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-191-1/+2
|
* render: match VSFilter's behavior when painting fill in shadow/borderrcombs2020-08-301-0/+1
| | | | | | | 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
* Take border into account during collision detectionOneric2020-07-051-0/+3
| | | | | | | | 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)
* renderer: fix subtitles to full screen frame iff use_marginsOleg Oshmyan2020-07-051-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* render: reorder context fields to eliminate paddingrcombs2020-05-261-13/+14
|
* renderer: fix incorrect deallocationDr.Smile2019-09-261-0/+1
| | | | | | | | | 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.
* bitmap: remove level of indirection in bitmap functionsDr.Smile2019-05-201-1/+1
| | | | | This allows to use Bitmap struct directly as cache value and to remove bunch of unnecessary allocations.
* renderer: improve handling of subpixel shiftDr.Smile2019-05-201-1/+0
| | | | | | | 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.
* renderer: move outline stroking immediately before rasterizationDr.Smile2019-05-201-3/+2
|
* Consolidate and quantize all transformationsDr.Smile2019-05-201-4/+10
| | | | | | | | | | | | | | 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.
* cache: construct cache values only from corresponding keysDr.Smile2019-05-191-4/+4
| | | | | | | | | | | | | | | | | | | | 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-2/+5
| | | | Purpose of this commit is to simplify logic behind drawing handling.
* Rename DBBox to ASS_DRect for uniformityDr.Smile2017-09-171-7/+0
|
* Replace FreeType types with libass native typesDr.Smile2017-09-171-16/+6
| | | | | | 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.
* renderer: switch to using two border outlines instead of oneDr.Smile2017-07-311-1/+1
|
* renderer: remove legacy FreeType rasterizerDr.Smile2017-07-311-2/+0
|
* stroker: implement fast two-outline strokerDr.Smile2017-07-311-3/+0
|
* render: remove redundant has_clipsDr.Smile2017-01-311-1/+0
| | | | | | | | | | | | | 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.
* api: make ass_set_cache_limits() work on total bitmap cache sizesDr.Smile2016-12-291-2/+4
| | | | | | Previously was possible to set only bitmap_max_size, now requested memory amount is divided between bitmap_max_size and composite_max_size.
* Add text justificationDan Oscarsson2016-11-121-0/+1
| | | | | | | | | | | | | | | | | | | | | | | 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.
* render: add refcounting functionality to image listsDr.Smile2016-06-301-1/+3
|
* render: keep track of any associated resources within ASS_ImageDr.Smile2016-06-301-8/+4
| | | | | That resources can be cached composite bitmap or raw bitmap buffer. Consequently, free lists are no longer needed.
* cache: keep ref_count of all active objects nonzeroDr.Smile2016-06-301-1/+3
|
* cache: switch to gradual cache clearingDr.Smile2016-06-301-2/+2
| | | | | | | | | | | 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.
* Use proper include statement for HarfBuzzwm42015-10-071-1/+1
|
* Move ASS_Shaper declaration to ass_shaper.hOleg Oshmyan2015-09-171-3/+2
|
* Custom font matching and font sourcesGrigori Goronzy2015-07-101-2/+2
| | | | | | | 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.
*