waddou / libass

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

Make empty newline handling consistent #112

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Consider these three cases:
1. {\an5}foobar\N\N\N
2. {\an5}foo\N\N\Nbar
3. {\an5}\N\N\Nfoobar

The first two cases render the same in both VSFilter and libass, but in the 
third case the newlines are ignored. Now, I know this is listed as a "known 
difference", but considering that the first case works the same I'd say it 
would make sense for the last case to work the same too. Currently this 
difference also means that you can for example "bump up" subtitles with 
{\an2}foobar\N\N\N but you can't similarly "bump down" supertitles with 
{\an8}\N\N\Nfoobar. The current libass behavior just isn't consistent, and 
since VSFilter consistently considers the newlines in all places, it would make 
sense for libass to do the same.

Original issue reported on code.google.com by taneli.v...@gmail.com on 4 Nov 2013 at 5:04

GoogleCodeExporter commented 8 years ago
Apparently the problem is that libass can't get a height from empty lines 
(because there are no characters in a line), so empty lines just amount to 
nothing. Apparently it's not obvious what height exactly should be used.

We don't really know what exactly vsfilter does either. Excerpt from IRC:

<zgreg> it's again a case where vsfilter does something really strange
<zgreg> see how the line height is divided by two? :p
<zgreg> I wonder what vsfilter bases the line height on for leading newlines

Can you provide information about this?

Original comment by nfxjfg@googlemail.com on 9 Nov 2013 at 4:25

GoogleCodeExporter commented 8 years ago
>Can you provide information about this?

Sure. After a bit of testing, I find that VSFilter simply treats an empty line 
as being half the height of a normal line. Since line height does not vary for 
a particular font in a particular style (and can't be changed with any tags 
either, much to my dismay), calculating the height for an empty line should be 
as simple as taking the line height from anything else in that style, and 
dividing it by two. Ultimately VSFilter's behavior seems to be pretty 
consistent with this.

I have attached some pictures and the .ass file used to produce them (with 
1280x720 dummy video in Aegisub). I also noticed the the case of following 
empty lines isn't handled exactly the same either, so that should probably also 
be fixed while you're at it.

Original comment by taneli.v...@gmail.com on 9 Nov 2013 at 5:07

Attachments:

GoogleCodeExporter commented 8 years ago
> Sure. After a bit of testing, I find that VSFilter simply treats an empty 
line as being half the height of a normal line.

Yep, libass already handles it that way, too.

> Since line height does not vary for a particular font in a particular style

No, it does and will vary. Font name and style are abstract until they're 
actually being used for rendering a particular run. Glyph substitutions are 
they keyword here. Obviously VSFilter seems to chose a particular font face to 
determine line height even for empty lines, and it would be interesting to know 
how it does that.

Original comment by g...@chown.ath.cx on 9 Nov 2013 at 5:13

GoogleCodeExporter commented 8 years ago
>No, it does and will vary.

I was the under the impression that the font size for a style with ASS 
determines the line height - so if you have font size 48, the line height will 
be 48px (assuming script resolution and video resolution match) and the font is 
fitted in that space. Does it not actually work like that? Because it sure 
seems like it does, and with that determining the line height for an empty line 
should be theoretically as simple as looking at the current font size when 
hitting empty lines and dividing it by two. I don't know the details, though, 
so I guess it's more complicated than that...

Anyway, I made another little test file to look at the half-lines. It that 
seems that with the following empty lines scenario libass is simply "one \N 
behind" VSFilter, so to say.

Original comment by taneli.v...@gmail.com on 9 Nov 2013 at 5:45

Attachments:

GoogleCodeExporter commented 8 years ago
>I was the under the impression that the font size for a style with ASS 
determines the line height - so if you have font size 48, the line height will 
be 48px (assuming script resolution and video resolution match) and the font is 
fitted in that space.

This sounds a bit unlikely... is there proof for this? Does vsfilter handle 
empty lines explicitly specially and uses the font size value as pixel size 
(which doesn't make much sense)?

>Anyway, I made another little test file to look at the half-lines.

What's with the {} in there?

Original comment by nfxjfg@googlemail.com on 9 Nov 2013 at 7:25

GoogleCodeExporter commented 8 years ago
>This sounds a bit unlikely... is there proof for this?

That's what Aegisub devs told me on IRC a while back. We can also see this by 
looking at the previous example I posted. The font size is set to 48 with \fs48 
on that. If we overlay a some rulers on the image, we can see that each line is 
48 pixels tall, and an empty line bumps things by 24 pixels (though since this 
example uses \an5, we basically get a "quarter-line" step too).

>What's with the {} in there?

I just added some separators to show "full line" points.

Original comment by taneli.v...@gmail.com on 9 Nov 2013 at 7:34

Attachments:

GoogleCodeExporter commented 8 years ago
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037%28v=vs.85%29.as
px covers how it works - if you pass a positive size it's the line height, and 
the font size is calculated to fit that, and if you pass a negative size it's 
the actual font size. Naturally, VSFilter does both. It first sets lfHeight 
using the formula on that page to make the font size actually be the font 
size... and then it promptly overwrites it with lf.lfHeight = 
(LONG)(style.fontSize+0.5), resulting in the "font size" actually being the 
line height.

Original comment by tgoyne on 10 Nov 2013 at 12:44

GoogleCodeExporter commented 8 years ago
Alright, it was a few years ago when I initially looked at these things, and 
now it's coming back slowly. :)

The most important fact here is that in SSA/ASS, what can be specified as font 
size in styles or overrides is not actually a font size in the traditional 
meaning, but line height. The renderer internally adjusts the font size so that 
(ascender + descender) == requested_size. This means we *can* count on line 
height being constant, irrespective of the actual font being it used (however 
it also means relative size might scale strangely if multiple fonts are used in 
the same line).

Original comment by g...@chown.ath.cx on 10 Nov 2013 at 1:50

GoogleCodeExporter commented 8 years ago
With VSFilter it's also noteworthy that 'line height' essentially becomes 
'opaque box height', when avoiding collisions between multiple lines without 
explicit positioning in a script.

Libass doesn't really do this currently, which can cause multiple lines to 
overlap, especially with large border sizes. If the current Libass behavior is 
by design, it's probably something which should be added to the 'Known issues 
and differences to VSFilter' wiki.

The bumpy edge on the opaque box with subpixel border is a separate issue.

Original comment by cyber.sp...@gmail.com on 19 Jan 2014 at 7:22

Attachments: