summaryrefslogtreecommitdiffstats
path: root/libass/ass_render.h
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* Implement cascade gaussian blurDr.Smile2015-07-041-1/+0
| | | | | | | | | | That's complete version with SSE2/AVX2 assembly. Should be much faster than old algorithm even in pure C. Algorithm description can be found in this article (PDF): https://github.com/MrSmile/CascadeBlur/releases Close #9
* Switch to virtual function tableDr.Smile2015-06-261-15/+2
| | | | | | | | | | Use one pointer to table of functions instead of scattered bunch of function pointers. Different versions of these tables can be constructed in compile time. Also, bitmap memory alignment now depends only on SSE2/AVX2 support and is constant for every width. That simplifies code without noticeable performance penalty.
* Apply fade only when the fade alpha is positive (like VSFilter)Oleg Oshmyan2015-05-251-1/+1
|
* Remove RenderContext.drawingwm42015-05-101-1/+0
| | | | | This really didn't make a lot of sense. This is a simplification, and should not affect actual program behavior.
* Don't use margins for events that should not be overriddenwm42015-03-161-0/+2
| | | | | | | libass already does not use the margins for events using \pos. This is not quite complete: there are other tags that we consider as "not dialogue", and which should not be overridden. These tags do not use EVENT_POSITIONED, and thus use the margins, which can mess up rendering.
* Allow more fine grained control over style overrideswm42015-02-261-1/+3
| | | | | | | | Add tons of ASS_OVERRIDE_ flags, which control whether certain ASS_Style fields are copied when doing selective style overrides with ass_set_selective_style_override_enabled(). This comes with some cleanup. It should be fully backwards-compatible.
* Clean up bitmap combiningDr.Smile2015-01-281-40/+15
| | | | | | | | | | Now pre- and post-combining operations are clearly separated, many parameters in cache keys are no longer necessary due to that. Also an ambiguous (in case of multiple fonts) text string is replaced with a list of direct bitmap references in composite cache key. Fixes #153. Fixes #82.
* Replace FT_Outline with ASS_OutlineDr.Smile2014-11-231-2/+2
|
* Move apply_blur() to ass_bitmap.cwm42014-11-131-1/+0
| | | | Put all code into one place, which makes it easier to follow.
* Provide slightly more fine-grained control over style overrideswm42014-10-171-0/+3
|
* Add a mechanism for selective style overrideswm42014-06-051-0/+6
| | | | | | | | | | | | | | | 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 change detection when text is clipped to screenwm42014-06-011-1/+1
| | | | | | The glyphs are clipped before combining, so the combined bitmap can always have the same position, size, and address. This breaks the change detection. Or at least I think that's what happens.
* Remove bitmap restridingwm42014-06-011-4/+0
| | | | It turns out we don't need this.
* Implement fast quad-tree rasterizer in C and x86/SSE2/AVX2Dr.Smile2014-04-291-0/+4
| | | | Signed-off-by: Rodger Combs <rodger.combs@gmail.com>
* Fix change detection in presence of vector clipswm42014-03-061-0/+1
| | | | | | | | | | | | | | | | | Fixes this test case: Dialogue: 0,0:00:00.00,0:00:02.00,,,0,0,0,,{\fs50\pos(250,250)\iclip(m 0 0 l 400 0 l 400 220 l0 220)}Hello Dialogue: 0,0:00:02.00,0:10:00.00,,,0,0,0,,{\fs50\pos(250,250)\iclip(m 0 0 l 400 0 l 400 230 l0 230)}Hello The problem here is that the rendered output bitmap list itself does not change, only its contents (due to the different vector clip). ass_render_frame() will not set *detect_change correctly, and an application using this flag (like mplayer or mpv) will not update the screen as needed. Fix this with a very cheap hack: always report a full change if there's a vector clip. This is basically an emergency fix until we have a proper way to detect the change.
* Fix subpixel jumping of rotated glyph runsOleg Oshmyan2014-01-291-0/+1
| | | | | Rotation origin was not taken into account when caching glyph run bitmaps.
* Make apply_blur and make_shadow_bitmap static; remove an unneeded local variable11rcombs2014-01-251-2/+0
|
* Simplify storage size handlingOleg Oshmyan2014-01-261-4/+2
| | | | No functional changes.
* Combine bitmaps before applying blur and shadow11rcombs2014-01-251-2/+74
|
* Do not reset \pbo and \p values after each drawingOleg Oshmyan2014-01-081-1/+2
| | | | Confirmed with VSFilter. This complements the previous commit.
* Fix Hinting againwm42013-09-261-0/+1
| | | | | | | | | | | | Commit 05eb520 missed some duplicated bits in ass_shaper.c. <wm4> oh crap <zgreg> oh crap indeed Instead of duplicating the logic in ass_shaper.c, just change the glyphs before they even get into processing. This way, all code reading the font size etc. is affected. This essentially reverts commit c207000c, because it's not needed anymore.
* Don't overwrite user-defined aspect ratio settingswm42013-03-291-2/+1
| | | | | | | | | | | | | | | | | | | | | ass_set_storage_size() overwrote the user-defined aspect ratio set with ass_set_aspect_ratio(). Change it so that if ass_set_aspect_ratio() is used, the ass_set_storage_size() parameters are not used for any aspect ratio calculations. (The storage size is still used for calculating the blur scale.) This simplifies the code as well, because the aspect ratio is now centrally calculated in ass_start_frame(). Update the doxygen. Make it clear that ass_set_storage_size() will be used for aspect ratio calculation, unless ass_set_aspect_ratio() is used. Also mention what libass actually does with the dar and sar parameters: it uses them to calculate a pixel aspect ratio, nothing else. Explicitly allow resetting the storage size with w=h=0. Document that it's allowed to remove the user defined aspect ratio by setting a pixel aspedct ratio of 0. See issue 6.
* shaper: proper script/language handlingGrigori Goronzy2013-03-041-0/+8
| | | | | | | | | | | | | | | | | | | | | Determine script for each character and use this as an additional property for splitting up the text into runs. Characters of Common or Inherited script assume the script of the preceding character. If that is not possible (First character(s) in a run are Common/Inherited, for instance), a backwards scan is done so they can assume the script of the following character. Additionally, determine default language in case no override is set. This simply maps a language to a script, if a language exists that is mostly representative for a given script. Pango's mapping has been adapted. This helps with fonts that don't have OpenType features set up for default script/language pairs. It's also considered to be right approach by most people, and might help with correct OpenType rendering in some other cases. Fixes issue 85.
* Add ass_set_storage_size and fix related scaling issuesOleg Oshmyan2013-03-031-0/+5
| | | | | | | | \blur radius is not scaled from script to storage resolution but is scaled from storage to display resolution. The same applies to borders and shadows if ScaledBorderAndShadow is "no". (If it is "yes", borders and shadows are scaled from script to display resolution just like before.)
* Fix change detection when cache is clearedwm42012-10-011-0/+1
| | | | | | | | | | | check_cache_limits() clears the image list. If all subtitles disappear right in the frame the cache has been cleared, ass_detect_change() will see two empty image lists (old - not empty, but cleared, new - empty), and signal to the application that there was no change. As result, media players which rely on the change detection will keep displaying the last subtitle until the next subtitle event. This bug was found by uau and has been reported on IRC in February.
* Add ass_set_line_position() API function for subtitle positionwm42012-10-011-0/+1
| | | | | | | | This allows users to change the vertical position of normal subtitles. MPlayer has such a feature as -sub-pos option using its internal subtitle renderer. Bump LIBASS_VERSION to indicate the API addition.
* Fix resetting border style with \rSTYLEwm42012-09-291-0/+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-0/+1
| | | | | Make sure to update the border appropriately in the second pass, after parsing.
* Support \rSTYLENAME syntaxGrigori Goronzy2012-03-111-1/+1
| | | | | This al