ganzhijie / libass

Automatically exported from code.google.com/p/libass
0 stars 0 forks source link

Improving @-font rotatable character choice #95

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
@-fonts are used for vertical writing and work by rotating characters that 
should
always stay upright by ninety degrees in preparation for the entire line being
rotated by ninety degrees in the opposite direction.

Currently libass decides which characters to rotate by simply thresholding
their Unicode codepoints. Anything below U+02F1 (#define VERTICAL_LOWER_BOUND
in ass_font.h) is left alone, while everything else is rotated.

Of course, what libass is trying to do is emulate the behaviour of VSFilter.
But VSFilter doesn't simply rotate all codepoints above a threshold!
I tried the following in xy-VSFilter on Windows 7:

    {\fn@MS Mincho\frz-90}よ‼ņfi«‹вα←⒜—ー

(note: א is rendered in a different font)
and got the following results:

    Original | Substituted | Rotated? | Codepoint | Category | Width
           よ |             |      yes |    U+3088 |       Lo |     W
           ‼ |             |      yes |    U+203C |       Po |     N
           ņ |             |       no |    U+0146 |       Ll |     N
           fi |             |       no |    U+FB01 |       Ll |     N
           « |             |       no |    U+00AB |       Pi |     N
           ‹ |             |      yes |    U+2039 |       Pi |     N
           в |             |       no |    U+0432 |       Ll |     A
           α |             |       no |    U+03B1 |       Ll |     A
           ← |     upward* |       no |    U+2190 |       Sm |     A
           ⒜ |             |      yes |    U+249C |       So |     A
           — |             |      yes |    U+2014 |       Pd |     A
           ー |    vertical |      yes |    U+30FC |       Lm |     W
    * and since it's then rotated by -90 degrees along with the baseline,
      ultimately it appears to point to the right

As I understand it, responsibility for VSFilter's behaviour here lies with GDI.
So I tried to search for a description of how GDI does this, and I failed to 
find
one. Then I tried to disassemble a GDI function that supposedly decides whether
to rotate glyphs based on an input parameter, but I couldn't find anything
relevant in the code I got (which is long and seemingly complicated). Thanks
to Google, I even looked at the implementation of the same function in 
ReactOS...
but it didn't seem to take @-fonts into account, and I suspect their font system
may not implement them at all.

It seems further investigation is needed. I think it may be useful to test many
codepoints one by one in Windows and try to extract rules from the gathered
statistics. For example, in the above (admittedly very small) sample,
all wide characters and none of the Ll characters were rotated.

Original issue reported on code.google.com by chortos@inbox.lv on 25 Feb 2013 at 2:02

GoogleCodeExporter commented 9 years ago
Whoops, forgot to remove the note about aleph after removing aleph itself.

Original comment by chortos@inbox.lv on 25 Feb 2013 at 2:03

GoogleCodeExporter commented 9 years ago
While researching how the @font feature of GDI works, I noticed that Wine 
rotates all characters over a certain codepoint, so that's what I implemented 
as well.

What GDI probably does (I havent't tested) is checking the Unicode script 
property. It should be easy to query HarfBuzz's character database (which is 
likely UCDN anyway :)) and only rotate CJK characters.

Original comment by g...@chown.ath.cx on 3 Mar 2013 at 10:08