rougier / freetype-gl

OpenGL text using one vertex buffer, one texture and FreeType
Other
1.65k stars 266 forks source link

Glyphs in descending portion of glyph getting cut off. #158

Open silverness2 opened 7 years ago

silverness2 commented 7 years ago

Hi, I have edited the markup demo program to display one line of text whose characters are: "FREE-ypjg". Similar to issue #152, in order to get the correct OpenGL window width and height to properly contain and display this text, I do a two pass run:

(Pass 1) - Run the program once with a pen offset of (0, 0) to get the text bounds (textwidth, textheight). (Pass 2) - Run the program again with the OpenGL window (width, height) set to the text bounds from Pass 1 and the pen offset set to (0, textheight).

This is the result of the image from Pass 2 whose window size is set to (3079, 715) and whose pen offset is set to (0, 715): free-ypjg

These are the metrics:

for font size: 650.000000
bounds width is: 3079.046875
bounds height is: 715.000000
pen x is: 3079.046875
pen y is: 130.000000
markup.font.ascender is: 585.000000
markup.font.descender is: -130.000000

You'll notice that the lower-case characters are getting cut off at the bottom. I'm surprised by this as I thought the bounding height would accommodate for the lowest character in the set of font glyphs via the descender metrics. But perhaps I'm mis-understanding how this works.

How should I ensure that the text does not get cut of at the bottom (besides arbitrarily moving the text up by increasing the pen offset height)?

The font I'm using is FreeSans.

rougier commented 7 years ago

Could you try displaying only the y (or maybe Fy) so we can narrow down the problem?

silverness2 commented 7 years ago

After setting the pen offset in the second pass to (0, 715) before rendering:

Here is the image for "y". y

And here are the metrics for "y":

for font size: 650.000000
bounds width is: 310.703125
bounds height is: 715.000000
pen x is: 310.703125
pen y is: 130.000000
markup.font.ascender is: 585.000000
markup.font.descender is: -130.000000

Here is the image for "Fy": fy

And here are the metrics for "Fy":

for font size: 650.000000
bounds width is: 700.046875
bounds height is: 715.000000
pen x is: 700.046875
pen y is: 130.000000
markup.font.ascender is: 585.000000
markup.font.descender is: -130.000000
rougier commented 7 years ago

Could you try without the 100.f scaling factor to check if ti changes things or not ?(https://github.com/rougier/freetype-gl/blob/master/texture-font.c)

silverness2 commented 7 years ago

In the texture_font_init() function, I removed the 100.0 scaling factor from the following line only (assuming this is what you meant):

if (!texture_font_load_face(self, self->size * 100.f, &library, &face))

Here is the image after Pass 1: fywithout100scale

Here are the metrics after Pass 1. I believe the bounding box is incorrect so I didn't proceed further to Pass 2.

for font size: 650.000000
bounds width is: 700.046875
bounds height is: 7.150024
pen x is: 700.046875
pen y is: 709.150024
markup.font.ascender is: 5.850000
markup.font.descender is: -1.300000
rougier commented 7 years ago

Oh, you have also to remove /100.f when computing metrics.

silverness2 commented 7 years ago

Oh right. So the code that I removed the scaling factor from are the following lines:

if (!texture_font_load_face(self, self->size, &library, &face))
self->ascender = (metrics.ascender >> 6);
self->descender = (metrics.descender >> 6);
self->height = (metrics.height >> 6);

The image after Pass 1 is: fy-removedscale

The metrics after Pass 1 is:

for font size: 650.000000
bounds width is: 700.046875
bounds height is: 715.000000
pen x is: 700.046875
pen y is: 130.000000
markup.font.ascender is: 585.000000
markup.font.descender is: -130.000000
rougier commented 7 years ago

Not good... the descender is read directly from the font information and I cannot see what is wrong at this stage. Do you know if the problem is proportional to the font size ? Maybe I forgot some adjustement and using big size makes it more obvious.

silverness2 commented 7 years ago

Hi,

I did the two pass test with the text "Fy" for font size 32, with Pass 2 using a window size of (34, 35). It's a little hard to tell, but if you zoom in, I think the text is still getting cut off at the bottom. This test was run with no scaling factor (i.e. with all the 100.f's removed).

Here is the image: fy-font32-noscale

Here are the metrics after Pass 2:

for font size: 32.000000
bounds width is: 34.468750
bounds height is: 35.000000
pen x is: 34.468750
pen y is: 6.000000
markup.font.ascender is: 29.000000
markup.font.descender is: -6.000000
rougier commented 7 years ago

From section 3 on https://www.freetype.org/freetype2/docs/tutorial/step2.html, maybe the descender is not the right way to compute it.

silverness2 commented 7 years ago

Following is output for a test where an extra character in a different font (Courier 10 Pitch) is pre-pended to the "Fy" characters (in FreeSans font) to see how that affects the descending character that is getting cut off.

Output for "Fy" (all in FreeSans) with window set to (107, 110): fy

for font size: 100.000000
bounds width is: 107.703125
bounds height is: 110.000000
pen x is: 107.703125
pen y is: 20.000000
markup.font.ascender is: 90.000000
markup.font.descender is: -20.000000

Output for "AFy" ("A" in Courier 10 Pitch, "Fy" in FreeSans) with window set to (167, 119): afy

for font size: 100.000000
bounds width is: 167.906250
bounds height is: 119.900002
pen x is: 167.906250
pen y is: 29.000000
markup.font.ascender is: 90.000000
markup.font.descender is: -20.000000

Output for "yFy" ("y" in Courier 10 Pitch, "Fy" in FreeSans) with window set to (167, 119): yfy

for font size: 100.000000
bounds width is: 167.906250
bounds height is: 119.900002
pen x is: 167.906250
pen y is: 29.000000
markup.font.ascender is: 90.000000
markup.font.descender is: -20.000000
rougier commented 7 years ago

Does that mean the descender is wrong in FreeSans ? I imagine this is unlikely but from your test it seems to be the case. I expect a "Fy" in Courier 10 Pitch to be ok from your test.

I think freetype comes with a font tool that allows to get a lot of information from the font. I'll look at the FreeSans.

silverness2 commented 7 years ago

"Fy" in Courier 10 Pitch is indeed ok.

Output for "Fy" with window size (120, 115) all-courier

for font size: 100.000000
bounds width is: 120.406250
bounds height is: 115.700005
pen x is: 120.406250
pen y is: 29.199997
markup.font.ascender is: 90.000000
markup.font.descender is: -20.000000
silverness2 commented 7 years ago

"Fy" in DejaVu Sans. The "y" is not getting cut off, but I think I would have expected more space underneath the "y", similar to the Courier 10 Pitch test above.

Output with window size (107, 116): all-dejavusans

for font size: 100.000000
bounds width is: 107.523438
bounds height is: 116.400002
pen x is: 107.523438
pen y is: 23.180000
markup.font.ascender is: 90.000000
markup.font.descender is: -20.000000

Output for "Fgjpqy" in DejaVu Sans: falllower

silverness2 commented 7 years ago

And just another test with Free Sans with window size = (298, 110):

falllower-freesans

for font size: 100.000000
bounds width is: 298.812500
bounds height is: 110.000000
pen x is: 298.812500
pen y is: 20.000000
markup.font.ascender is: 90.000000
markup.font.descender is: -20.000000