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.
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.
Grigori Goronzy [Sun, 2 Oct 2011 22:41:53 +0000 (00:41 +0200)]
Letter spacing is a per-cluster property
Layout refactoring broke letter spacing and always used the last valid
spacing specified for the whole line, which is of course wrong.
Letter-spacing is an inline property and can be different for each glyph
cluster. Add that property to GlyphInfo and use it to fix this
regression.
Grigori Goronzy [Sun, 25 Sep 2011 00:18:20 +0000 (02:18 +0200)]
pkg-config: tailor libass.pc for static-only builds
Add library and package dependencies to the default (non-private)
pkg-config fields for static-only builds. This makes sure the packages
and libraries are always picked up and used, even if the --static option
is not supplied to the pkg-config commandline.
Grigori Goronzy [Mon, 29 Aug 2011 17:15:31 +0000 (19:15 +0200)]
Fix off-by-one error in \fad, \fade
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.
Grigori Goronzy [Thu, 25 Aug 2011 01:48:18 +0000 (03:48 +0200)]
vertical: improve glyph positioning
It is a bit crazy, but for vertical layout the sTypoAscender and
sTypoDescender fields of the OS/2 table are supposed to be used for
determining the size of the ideographic EM box [1], so that glyphs
can be centered on the baseline more neatly.
With this change, vertical layout should be completely equal to
VSFilter.
Grigori Goronzy [Sun, 21 Aug 2011 22:21:50 +0000 (00:21 +0200)]
opaque box: avoid unnecessary outline copy
It's faster and easier to just create a new outline, than to copy it,
free it, and create a new one. The old glyph-based code needed to do
this since it's not possible to create a glyph "from scratch".
Grigori Goronzy [Sun, 21 Aug 2011 22:17:45 +0000 (00:17 +0200)]
Fix and simplify opaque box border
Make sure to pass the correct advance and ascender/descender to the
opaque box creation function. We can also simplify this a bit as we
do not need to check if it's a glyph or drawing anymore.
Grigori Goronzy [Sun, 7 Aug 2011 23:09:24 +0000 (01:09 +0200)]
Add compile time switch for HarfBuzz support
Now that it's possible to switch shapers at runtime, it also becomes a
lot easier to disable them at compile time. Add ifdefs and build system
changes so that HarfBuzz can be safely disabled. It's autodetected now
and enabled if available.
This shuffles a bit of code around, but there are no functional changes.
Note that FriBidi remains mandatory for the time being, but this
shouldn't pose any problems, since it is a small and very portable
library without any special dependencies.
Grigori Goronzy [Sun, 7 Aug 2011 22:22:32 +0000 (00:22 +0200)]
Runtime shaper selection
Add an API call, ass_set_shaper, and infrastructure to make shapers
selectable at runtime. Currently, this allows to switch between two
shapers: a SIMPLE shaper that maps to FriBidi and a COMPLEX shaper that
maps to HarfBuzz.
Grigori Goronzy [Sat, 6 Aug 2011 18:06:54 +0000 (20:06 +0200)]
Adjust italic to non-italic style spacing
Previously, the space added was quite a lot, since it was calculated so
that it would be enough to accommodate a heavily FreeType-slanted glyph
in the worst case. In many cases this was too much spacing, especially
if the italic font was only slightly angled.
The new fix simply ensures that the glyph is inside the bounds of the
advance.
Grigori Goronzy [Mon, 1 Aug 2011 13:51:27 +0000 (15:51 +0200)]
Support language hint in the Script Info section
Parse a hint in the form "Language: xx" with xx being an ISO 639-1
language code, and pass it to HarfBuzz. This can be useful to render
scripts with language-specific character variants.
Grigori Goronzy [Fri, 29 Jul 2011 02:21:48 +0000 (04:21 +0200)]
harfbuzz: cache glyph metrics
HarfBuzz' FreeType font functions do not cache anything and call
FT_Load_Glyph all the time, which can be slow. Add a cache for metrics
and use it with custom font functions.
Grigori Goronzy [Sun, 24 Jul 2011 22:00:53 +0000 (00:00 +0200)]
Disable reordering of non-spacing marks
FriBidi's line reordering algorithm reorders non-spacing marks
(diacritics, etc.) to come after the base character by default. This
doesn't work particularly well with our layout model and leads to
wrongly positioned marks in some cases with HarfBuzz and all cases
with FriBidi shaping.
Grigori Goronzy [Sun, 17 Jul 2011 15:43:55 +0000 (17:43 +0200)]
Fix crash with FreeType's updated stroker
The new revision of the stroker in FreeType doesn't like the way
contours are zero-filled to disable them. It's not particularly clean
anyway, so rewrite the whole outline instead.
Grigori Goronzy [Sun, 17 Jul 2011 11:53:29 +0000 (13:53 +0200)]
Fix line counting and breaking
Make sure to increment the line counter only if the offset of the new
line is actually legal and inside the bounds of the text size. Fixes
random crashes in case the last symbol of the line is a break.
git-blame says it's Evgeniys fault, it wasn't caused by the recent
layout changes.
Grigori Goronzy [Thu, 14 Jul 2011 22:49:50 +0000 (00:49 +0200)]
Cache HarfBuzz fonts
Add a new opaque data structure to store shaper-specific font data in
an ASS_Font. At the moment, this is used for caching HarfBuzz fonts,
to reduce allocation and font initialization overhead.
Grigori Goronzy [Thu, 14 Jul 2011 18:49:44 +0000 (20:49 +0200)]
Revert @font ascender/descender hack
This was introduced with commit e051ab. After re-evaluation, it
seems to be rather wrong. Windows appears to use the same ascender
as horizontal rendering, except for the first line. We don't have this
special handling of the first line, but apart from that, everything is
similar to Windows now. Verified with a couple of popular CJK fonts,
such as MS Mincho, Meiryo, etc.
Grigori Goronzy [Wed, 13 Jul 2011 22:01:11 +0000 (00:01 +0200)]
Use the "font encoding" property as a base direction hint
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.
Grigori Goronzy [Wed, 13 Jul 2011 20:32:00 +0000 (22:32 +0200)]
Enable vert/vkna features for @font vertical text
Set up a feature list and toggles these features as needed. The "vert"
feature enables vertical glyph variants in general, while "vkna"
additionally enables vertical variants for Kana.
Grigori Goronzy [Wed, 13 Jul 2011 19:52:23 +0000 (21:52 +0200)]
Introduce ASS_Shaper object
Encapsulate all data related to shaping into this new object and migrate
all shaping-related code to it. The object is long-living; arrays are
allocated only once and then grown as needed.
Grigori Goronzy [Mon, 11 Jul 2011 18:35:16 +0000 (20:35 +0200)]
Support glyph clusters of multiple glyphs
Sometimes a glyph cluster resolves to multiple glyphs, for example when
diacritics are used with Arabic script. This doesn't map well to the
list of glyphs expected by libass.
Extend the glyph list to a list of singly-linked glyph clusters of
glyphs and adapt the renderer to support this.
Grigori Goronzy [Sun, 10 Jul 2011 02:08:55 +0000 (04:08 +0200)]
Separate glyph font face matching and glyph loading
Split up ass_font_get_glyph into two functions: one function matches
checks the fonts for support of the requested codepoint and returns
a face_index and glyph_index to later load the glyph, with a second
function.
This approach is very useful for shaping, which needs to be done
on runs with the same font face and font size and changes the
glyph_index.
Grigori Goronzy [Sat, 9 Jul 2011 23:53:09 +0000 (01:53 +0200)]
Fix bitmap cache
Pass the *complete* hash key to the cache handling functions, not
only the outline-specific subkey. This mistake completely stopped
the cache from actually working and resulted in great slowdown!
Grigori Goronzy [Sat, 9 Jul 2011 22:38:12 +0000 (00:38 +0200)]
Reorder positions for "Banner" effect text
Events that use the "Banner" effect have different wrapping/breaking
handling (none at all, to be exact) and need special treatment to
make reordering work.
Grigori Goronzy [Sat, 9 Jul 2011 20:04:01 +0000 (22:04 +0200)]
Redesign horizontal alignment calculations for bidi
The line alignment code determined the first and last glyph in a
line and calculated the distance from that. This is rather arcane
and doesn't easily work with bidi. Redesign the algorithm to simply
add together all individual character widths instead.
Grigori Goronzy [Wed, 6 Jul 2011 21:19:54 +0000 (23:19 +0200)]
Provisional bidi and shaping support
Adds fully working bidirectional text and simple shaping support.
The following works:
- bidirectional text according to the Unicode Bidirectional Algorithm
- simple shaper for mirrored forms (brackets, etc.) according to
rule L4 of the Unicode Bidirectional Algorithm
- reordering into visual order with correct line wrapping
However, the implementation certainly needs efficiency improvements
(caching, less malloc'ing), a proper shaper (HarfBuzz) needs to be
hooked up and various bugs with karaoke and positioning need to be
fixed.
Grigori Goronzy [Mon, 4 Jul 2011 10:59:11 +0000 (12:59 +0200)]
Introduce bitmap runs
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.
Grigori Goronzy [Fri, 1 Jul 2011 01:13:22 +0000 (03:13 +0200)]
Cache ascender/descender
Cache ascender/descender so they don't have to be queried every frame
for every glyph. This also makes it possible to more uniformly handle
drawings and glyphs.
Grigori Goronzy [Mon, 27 Jun 2011 19:04:12 +0000 (21:04 +0200)]
cache: unified bitmap cache
Similarly to the glyph cache, subclass the bitmap cache to allow both
outline bitmaps and clipping mask bitmaps to coexist in the same cache
in a much cleaner way.
Grigori Goronzy [Mon, 27 Jun 2011 18:10:45 +0000 (20:10 +0200)]
cache: use outline-bitmap hierarchy to slim down bitmap hash key
The bitmap hash key duplicated a lot of information the glyph hash
key already saves. The subclassing introduced recently complicates
this even more. Modify the hash key to utilize a pointer to the glyph
hash value instead, which is faster and more flexible. Make sure to
always empty the bitmap cache when the glyph cache is emptied.
Grigori Goronzy [Mon, 27 Jun 2011 00:17:10 +0000 (02:17 +0200)]
cache: unified outline cache for glyphs/drawings
Glyphs and drawings have wildly different hash keys. Subclass the hash
keys of glyphs and drawings in a new, unified outline cache. This also
fixes some issues with drawings in the glyph cache. Now, the textual
description of the drawing is included in the key (the hash value isn't
really good enough, especially not fnv32) and the baseline offset is
saved as well.
Grigori Goronzy [Mon, 20 Jun 2011 21:12:22 +0000 (23:12 +0200)]
Use bare outlines for drawings
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.
Grigori Goronzy [Mon, 20 Jun 2011 20:50:34 +0000 (22:50 +0200)]
Convert outline processing and caching from glyphs to bare outlines
This introduces functions to use and copy pointered outline objects
easily and uses these instead of glyphs everywhere.
Previously the glyph cache was abused for caching vector clipping masks,
but this isn't possible anymore (nor desirable), thus vector clipping
cache has been disabled for the moment.
Grigori Goronzy [Mon, 13 Jun 2011 20:39:26 +0000 (22:39 +0200)]
Render outlines, not glyphs
libass can render both regular glyphs (extracted from a font) and
drawings, which are inserted into an existing glyph so far. This is a
rather crude hack. However, it is necessary, as the renderer only works
with FT_Glyphs. The obvious solution is to work on the underlying
outlines directly instead.
This is the first step to make this possible: change the basic
rasterizer to use the outline-specific rasterization functions. There
are more advantages:
- It's more efficient. The bitmap can be directly rendered into the
bordered target bitmap.
- This should make it easier to adapt the renderer to run-based
rendering later on (the pixels are ORed into the target)
The higher-level rendering code still needs to be adjusted.
Grigori Goronzy [Sat, 9 Apr 2011 19:48:08 +0000 (21:48 +0200)]
Improved "last resort" charmap matching
After font reselection, loop through all charmaps if no glyph can't be
found until we hopefully find one that works. If we get here at all, the
font is seriously broken, so this is unlikely to harm anything.
This improves the last resort charmap fallback introduced in 96057d.