Lazarus

Programming => Packages and Libraries => LazUtils => Topic started by: zamtmn on February 19, 2013, 09:20:14 am

Title: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 19, 2013, 09:20:14 am
As I understand it in the TTF fonts order Bezier curve is not limited. There may be three or more points not on the curve. Built in LazFreeType tools for interpolating Bezier curves I have found. Interpolation to be done by himself or have a ready method in LazUtils?

In the screenshot "x" marked point on the curve, "o" - not on the curve.
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 19, 2013, 09:44:42 am
You mean you need a function do compute those ?

Yes, there are built in functions in LazFreeType, but not easy to use. To my knowledge, there are no independant function, and Bezier functions generally have 1 or 2 control points.
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 19, 2013, 10:04:39 am
>>Built in LazFreeType tools for interpolating Bezier curves I have found
Sorry for my english (google.translate). I not found.

>>You mean you need a function do compute those ?
Yes
>>Yes, there are built in functions in LazFreeType, but not easy to use
Where are they?
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 19, 2013, 10:20:45 am
I suppose it is the Split_Bezier method in TTProfile unit, but I'm not sure how it works.
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 21, 2013, 06:13:27 am
Thanks. Мethods from the TTProfile unit too complicated for me. I did my implementation Bezier
>> and Bezier functions generally have one or two control points.
In cases when there is 2 or more points "not on curve", between them need generate a point "on curve." It turned out that the Bezier curves in TTF always quadratic
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 21, 2013, 08:14:50 am
Ok, so how is computed for example a point with 3 control points using 2-control-point bezier curves ?

Let's say these are (p1,p2,p3,p4,p5), what do you do with them?
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 21, 2013, 09:27:46 am
First I made the interpolation points as Bezier curves of higher order. This is not correct, see wrong.png. Then added via points - all became good, see good.png. If there is a sequence P0, P1, P2, P3, and P0,P3 - on curve, P1,P2 not on curve, It splits into two quadratic Bezier curve.
P0, P1, (P1+P2)/2
and
(P1+P2)/2, P2, P3
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 21, 2013, 10:29:59 pm
Oh ok, so no cubic Bezier at all. And if there are 3 control points ?

P0, P1, P2, P3, P4 with P0,P4 on curve ?

Does it gives :
P0, P1, (P1+P2)/2
(P1+P2)/2, P2,(P2+P3)/2
(P2+P3)/2, P3, P4
?
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 21, 2013, 10:55:22 pm
>>P0, P1, (P1+P2)/2
>>(P1+P2)/2, P2,(P2+P3)/2
>>(P2+P3)/2, P3, P4
Yes, it is.
But it also may be the case that there is no point on the curve, look at the circle of the percent. In this case between the points are added to the mid-points on the curve. And because of the fact that the circuit is closed again be quadratic curves
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: User137 on February 22, 2013, 12:30:13 am
I don't know if this is what you are looking for, but catmull curve goes through the points. Helper points are simply next polygon points in the curve.
http://code.google.com/p/nxpascal/source/browse/trunk/src/nxMath.pas#75
Code: [Select]
function Catmull(const p0,p1,p2,p3,t: single): single;
begin
  result:=0.5*( 2*p1+(p2-p0)*t +
    (2*p0-5*p1+4*p2-p3)*t*t +
    (3*p1-p0-3*p2+p3)*t*t*t );
end;

I mean it could look like that in the middle of long point sequence:
http://www.mvps.org/directx/articles/shadeland.old/images/spline2a.gif
Red circles are p0..p3 from left to right.
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 22, 2013, 01:00:07 am
>>P0, P1, (P1+P2)/2
>>(P1+P2)/2, P2,(P2+P3)/2
>>(P2+P3)/2, P3, P4
Yes, it is.
But it also may be the case that there is no point on the curve, look at the circle of the percent. In this case between the points are added to the mid-points on the curve. And because of the fact that the circuit is closed again be quadratic curves
Alright, thank you very much for the explanations.
Title: Re: [LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 22, 2013, 01:01:36 am
I don't know if this is what you are looking for, but catmull curve goes through the points. Helper points are simply next polygon points in the curve.
http://code.google.com/p/nxpascal/source/browse/trunk/src/nxMath.pas#75
Code: [Select]
function Catmull(const p0,p1,p2,p3,t: single): single;
begin
  result:=0.5*( 2*p1+(p2-p0)*t +
    (2*p0-5*p1+4*p2-p3)*t*t +
    (3*p1-p0-3*p2+p3)*t*t*t );
end;

I mean it could look like that in the middle of long point sequence:
http://www.mvps.org/directx/articles/shadeland.old/images/spline2a.gif
Red circles are p0..p3 from left to right.
It seems like a cubic spline.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 22, 2013, 07:13:23 am
User137
Thanks, but in this case it does not fit. As it turned out, in TTF fonts used only quadratic Bezier curves http://en.wikipedia.org/wiki/File:Bezier_2_big.gif
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 23, 2013, 09:52:15 am
Previous screenshots I gave the value ftFont.SizeInPoints: = 100; If SizeInPoints reduce glyphs detail decreases and artefacts appear. I've attached a screenshot of the font times.ttf and ftFont.SizeInPoints: = 10. And the values ​​that appear after distortion for all the fonts are different. What values ​​to use to always get the maximum detail glyphs?
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 23, 2013, 01:32:06 pm
You need to deactivate font hinting (Hinted property).
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 24, 2013, 09:16:41 pm
circular
>>You need to deactivate font hinting (Hinted property).
Thank you. it works.
There was one more question.
I need the ttf fonts in vector editor, so DPI for me does not matter. When loading fonts I divide the coordinates of glyphs on the font size, and expect to receive a letter of unit height:
Code: [Select]
k:=1/ftFont.SizeInPoints;
...
CoordInMyEditor.x:=k*_glyph^.outline.points^[j].x/64;
CoordInMyEditor.y:=k*_glyph^.outline.points^[j].y/64;
...
In fact, I get a little smaller, and for each font, it's different.
By experimenting, I found to get the font аrial.ttf unit height I have to do
Code: [Select]
k:=1.074/ftFont.SizeInPoints;
...
CoordInMyEditor.x:=k*_glyph^.outline.points^[j].x/64;
CoordInMyEditor.y:=k*_glyph^.outline.points^[j].y/64;
...
To get the times.ttf unit height I have to do
Code: [Select]
k:=1.162/ftFont.SizeInPoints;
...
CoordInMyEditor.x:=k*_glyph^.outline.points^[j].x/64;
CoordInMyEditor.y:=k*_glyph^.outline.points^[j].y/64;
...
Where did these factors and how to get them from TFreeTypeFont?
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 25, 2013, 12:45:44 am
I'm not sure.

There are ascent and descent values, full height or not full height, etc.

full height = ascent + descent + bottom margin

Also values found in the font file may not be accurate.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 25, 2013, 08:59:06 am
Ascent and Descend present in LazFreeType. What is bottom margin?
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 25, 2013, 11:56:22 am
It is LineSpacing.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 25, 2013, 12:14:45 pm
No. it not work((
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 25, 2013, 05:10:41 pm
It's possible that the font "size in pixels" is not exactly the same as the size of the glyphs. This depends on how the font file was made.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 26, 2013, 06:14:41 am
However in other applications these fonts are displayed correctly
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 26, 2013, 11:38:30 am
Maybe there are some tricks. I don't know.

Obviously, it is not possible to determine the size by computing the bounding rectangle of the glyphs, because some fonts have vertical overhang (like 'script' fonts).

Note that there are different values inside a font file that can be used, they might be contradictory or wrong. Maybe you can compare with FreeType dll rendering, and see if it is different. In this case, you can look at the code to see if there are some special tests added.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 26, 2013, 12:18:21 pm
Ok. I try to understand.
I made a small example (http://download.shamangrad.net/zcad/ttf2vector.7z). Need to get the character height SymbolH
Code: [Select]
const
     SymbolH=300;
In the example of an incorrect calculation of the coefficient for the map coordinates in TTF to range 0-SymbolH
Code: [Select]
     k:=(FTTFFont.Ascent+FTTFFont.Descent+FTTFFont.LineSpacing)/FTTFFont.SizeInPixels;
     k:=SymbolH*k/FTTFFont.SizeInPixels;

Archive contains the font arial.ttf
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 26, 2013, 11:32:22 pm
Font ascent includes :
- small top margin
- space for accents
- letters up to baseline

So I suppose it's normal that you get some space above it.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 26, 2013, 11:47:10 pm
I need the value CapHeight of your pictures. It is described in the "'OS/2' Table - OS/2 and Windows Metrics" http://www.microsoft.com/typography/otspec/os2.htm
OS/2 Table from arial.ttf
Quote
'OS/2' Table - OS/2 and Windows Metrics
---------------------------------------
Size = 96 bytes (expecting 96 bytes)
  'OS/2' version:           3
  xAvgCharWidth:            904
  usWeightClass:            400
  usWidthClass:             5
  fsType:                   0x0008
  ySubscriptXSize:          1434
  ySubscriptYSize:          1331
  ySubscriptXOffset:        0
  ySubscriptYOffset:        283
  ySuperscriptXSize:        1434
  ySuperscriptYSize:        1331
  ySuperscriptXOffset:      0
  ySuperscriptYOffset:      977
  yStrikeoutSize:           102
  yStrikeoutPosition:       530
  sFamilyClass:             8    subclass = 5
  PANOSE:                   2 11  6  4  2  2  2  2  2  4
  Unicode Range 1( Bits 0 - 31 ): E0002AFF
  Unicode Range 2( Bits 32- 63 ): C0007843
  Unicode Range 3( Bits 64- 95 ): 00000009
  Unicode Range 4( Bits 96-127 ): 00000000
  achVendID:                'TMC '
  fsSelection:              0x0040
  usFirstCharIndex:         0x0020
  usLastCharIndex:          0xFFFC
  sTypoAscender:            1491
  sTypoDescender:           -431
  sTypoLineGap:             307
  usWinAscent:              1854
  usWinDescent:             434
  CodePage Range 1( Bits 0 - 31 ): 400001FF
  CodePage Range 2( Bits 32- 63 ): FFFF0000
  sxHeight:                 1062
  sCapHeight:               1467 <-----------------------------------------------------------------------------------
  usDefaultChar:            0x0000
  usBreakChar:              0x0020
  usMaxLookups:             4
But in type TT_OS2 it not present((
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 27, 2013, 09:50:25 am
faced with a strange moment. I look at the contents of the arial.ttf:
Code: [Select]
'hhea' Table - Horizontal Header
--------------------------------
Size = 36 bytes (expecting 36 bytes)
'hhea' version:         1.0
yAscender:            1854<--------------------------------Ascend;
yDescender:           -434
yLineGap:             67
advanceWidthMax:      4096
minLeftSideBearing:   -1361
........................................
........................................
Symbol "T"
Glyph  55: off = 0x00004B08, len = 258
  numberOfContours: 1
  xMin: 48
  yMin: 0
  xMax: 1210
  yMax: 1466
.............
Coordinates
-----------
  0: Rel (   531,     0)  ->  Abs (   531,     0)
  1: Rel (     0,  1293)  ->  Abs (   531,  1293)
  2: Rel (  -483,     0)  ->  Abs (    48,  1293)
  3: Rel (     0,   173)  ->  Abs (    48,  1466)
  4: Rel (  1162,     0)  ->  Abs (  1210,  1466)
  5: Rel (     0,  -173)  ->  Abs (  1210,  1293)
  6: Rel (  -485,     0)  ->  Abs (   725,  1293)
  7: Rel (     0, -1293)  ->  Abs (   725,     0)
........................................
If I set the font size in the test program to 1854/64, I have to see the array coordinates such as a ttf. But it is not so
Code: [Select]
FTTFFont.SizeInPoints:=1854/64;
............................
_glyph^.outline.points^=
{
  {
    X = 514, Y = 0},
  {
    X = 514, Y = 1253},
  {
    X = 47, Y = 1253},
  {
    X = 47, Y = 1420},
  {
    X = 1172, Y = 1420},
  {
    X = 1172, Y = 1253},
  {
    X = 702, Y = 1253},
  {
    X = 702, Y = 0},
.........
}
Why they are a little less?
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 27, 2013, 10:36:22 am
Maybe it includes rounded letters. See for example the letter C.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: zamtmn on February 27, 2013, 05:06:32 pm
At last everything worked as it should! Require minor changes to EasyLazFreeType for CapHeight property. Please review the attached patch.
Title: Re: [Solved][LazFreeType]How to interpolate a point not on the curve?
Post by: circular on February 27, 2013, 05:26:11 pm
Congratulations, that's perfect.

Patch seems good to me.