Lazarus

Programming => Packages and Libraries => LazUtils => Topic started by: zamtmn on June 16, 2016, 10:22:54 am

Title: [Solved]LazFreeType parasitic contours
Post by: zamtmn on June 16, 2016, 10:22:54 am
I noticed that for some fonts LazFreeType produces spurious contours.
For example calibri.ttf from windows\fonts - see attached screenshot.
This prevents to obtain a correctly char image in my application. I attached a small test application to see this bug
Title: Re: LazFreeType parasitic contours
Post by: marcov on June 16, 2016, 12:59:59 pm

One of the for loops is wrong:

Code: Pascal  [Select]
  1. for j:=0 to _glyph^.outline.n_points do

iterates over outline.n_points+1 points.
Title: Re: LazFreeType parasitic contours
Post by: zamtmn on June 16, 2016, 01:49:34 pm
Thank you. but it is not everything. I fix it and athach new bugscreen.

As I understand the problem lies somewhere near this place
components\lazutils\ttgload.pas line 1220
Code: Pascal  [Select]
  1.    (* copy also the phantom points, the debugger needs them *)
  2.    inc( num_points, 2 );
and shows if in symbols inscription uses "subglyph`s"
Title: Re: LazFreeType parasitic contours
Post by: marcov on June 16, 2016, 02:03:20 pm
Seems ttf has two extra phantom points to pass values:

(from a MS document found via google:)
Quote
The font scaler will always add two “phantom points” to the end of every outline. If the entire set of contours for a glyph requires “n” points (i.e., contour points numbered from 0 to n-1), then the scaler will add points n and n+1. These points will be placed on the character baseline. Point “n” will appear at the character origin, while “n+1” will be placed at the advance width point.
Both points (n and n+1) may be controlled by TrueType instructions, with corresponding effects on the sidebearings and advance width of the instructed glyph. The side bearings and advance width that are computed using these phantom points are called the device-specific widths (since they reflect the results of grid fitting the width along with the glyph to the characteristics of the device). The device-specific widths can be different from or identical to the linearly scaled widths (obtained by simple scaling operations), depending on the instructions applied to the phantom points.

Or: you shouldn't draw them.
Title: Re: LazFreeType parasitic contours
Post by: zamtmn on June 16, 2016, 04:47:23 pm
But how do I distinguish between such points. and why in other fonts they do not exist?
Title: Re: LazFreeType parasitic contours
Post by: Windsurfer on June 17, 2016, 09:39:57 am
This is just a guess. It looks as though the last two points are provided as a quick look up to work out the width of each character. My guess is that the x, y values are reversed for the advance width point.
Title: Re: LazFreeType parasitic contours
Post by: zamtmn on June 17, 2016, 12:29:27 pm
Thanks all! Issue was resolved.
1. Need to handle outline.n_points-3 points. Last 2 points always "phantom"
2. Need to be prepared to meet the contour consisting of only one point. And drop this contour
Title: Re: LazFreeType parasitic contours
Post by: Graeme on June 17, 2016, 01:35:57 pm
This is just a guess. It looks as though the last two points are provided as a quick look up to work out the width of each character. My guess is that the x, y values are reversed for the advance width point.

Yeah, and that sounds like a perfect Microsoft hack. And probably explains why most or all non-Microsoft supplied fonts don't have that. The TTF file has perfectly well defined fields supplying that information - there is no need for such a hacks.

I guess now font rendering libraries like FreeType etc needs to do:

Code: Pascal  [Select]
  1.    if Font.Manufacturer = 'Microsoft Corporation' then
  2.      result := xyz  // do shitty hack
  3.    else
  4.      result := outline.n_points;
  5.