Montag, 30. Mai 2011

libass 0.9.12 released

I released libass 0.9.12 just now. There are no surprises, this is just a bugfix release that further improves compatibility with VSFilter. Tarballs are available from the project page.

Donnerstag, 26. Mai 2011

Vertical shaper in Harfbuzz

Looks like support for vertical layouts and the vert and vrt2 tables became usable in Harfbuzz now, just in time! This will definitely make proper vertical CJK layout easier in libass. I still need to test it, though...

After a little bit of trouble, this worked just fine.

Dienstag, 24. Mai 2011

Getting complex text layout into libass

Unfortunately, libass's rendering model doesn't make it easy to plug-in contextual transforms that are needed for complex text layout. Currently, for every subtitle event, a lot of  processing is done per-glyph before line breaking, positioning, etc. take place. However, the complex text layout engine needs runs of text. Let's look again at the text layout pipeline:

  1. Split up text into runs according to style (font, size, decoration).
  2. Split up runs further according to text direction (depending on script and language).
  3. Shape runs that need it.
  4. Break lines.
  5. Reorder lines into visual order
Step 1 is currently not done with runs, style is strictly applied per glyph. This is not without problems, for example it makes text decorations (underline, strike-through) hard to implement correctly and positioning after certain style changes is hard to get right (from italic to non-italic style). Moreover, this requires inter-glyph blending later on in the rendering pipeline.

My plan is to completely refactor the main rendering loop from individual glyphs to runs to get rid of these problems. Obviously, the other advantage of it is that it makes plugging complex text layout into rendering much easier.

What about the next steps? Steps 2 and 5, BiDi transformation, will be handled by fribidi. Step 3, text shaping, will be handled by the new harfbuzz-ng library. Step 4 is going to be handled by liblinebreak plus support code in libass.

As a first step, I will implement a simple standalone renderer for steps 2-5. I'm using the hb-view program from harfbuzz-ng as the base.

Update: added step 5, reordering.

GSoC welcome package

It just arrived. I like the glowing sticker!

Montag, 23. Mai 2011

Introduction to complex text layout

Complex text layout is, as the name says, a pretty complicated process. The term stands for various text transformations that need to be done to render scripts that require more than trivial codepoint-to-glyph mapping.

Generally, the following transformations are complex text layout:

  • BiDi. Many languages do not write from left to right, but from right to left (e.g. Hebrew). Usually, numbers are still written from left to right, though. Sometimes you need to mix right to left text into left to right text. When there's any mix between directions, and that can happen quite quickly, the text needs to be split up into so-called runs with the same direction, and rendered accordingly. Unicode specifies such an algorithm, the Unicode Bidirectional Algorithm.
  • Text shaping. Many scripts, especially cursive scripts (most importantly Arabic and derivatives) require contextual glyph substitutions. Depending on the position of a glyph inside a word, a certain variant needs to be used. Moreover, as it is a cursive script, the letters need to be repositioned so that they connect cleanly to each other. There are a lot more features referred to as shaping. Shaping requires runs of text with the same direction and script.
  • Line breaking. Mixing text direction, language and script complicates line breaking. Unicode specifies the Unicode Line Breaking Algorithm to deal with that.
According to that, a full complex text layout engine needs to do a lot of work.
  1. Split up text into runs according to style (font, size, decoration).
  2. Split up runs further according to text direction (depending on script and language).
  3. Shape runs that need it.
  4. Break lines.
Complete and easy to use cross-platform engines already exist and work well. One example is the popular Pango library. However, Pango only offers a very high-level API for the complete engine. It's not flexible enough for libass, which does a lot of rather low-level font manipulations, and it's said to be slow, while performance is critical for libass.

So there's no way around doing all steps yourself. Fortunately, stable libraries for all of the critical steps are available. I'm going to describe the plans for the libass implementation in the next posts.

Freitag, 20. Mai 2011

Let's get this started

This blog is mostly dedicated for Google Summer of Code 2011, where I am going to implement complex text layout support for the libass subtitle rendering library, under mentorship of the VideoLAN project.

I'll probably also blog about some topics only mildly related to GSOC. Anyway, let's get this started!