Lazarus
Programming => Packages and Libraries => LazUtils => Topic started 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.

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.

>>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?

I suppose it is the Split_Bezier method in TTProfile unit, but I'm not sure how it works.

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

Ok, so how is computed for example a point with 3 control points using 2controlpoint bezier curves ?
Let's say these are (p1,p2,p3,p4,p5), what do you do with them?

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

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
?

>>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 midpoints on the curve. And because of the fact that the circuit is closed again be quadratic curves

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
function Catmull(const p0,p1,p2,p3,t: single): single;
begin
result:=0.5*( 2*p1+(p2p0)*t +
(2*p05*p1+4*p2p3)*t*t +
(3*p1p03*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.

>>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 midpoints 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.

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
function Catmull(const p0,p1,p2,p3,t: single): single;
begin
result:=0.5*( 2*p1+(p2p0)*t +
(2*p05*p1+4*p2p3)*t*t +
(3*p1p03*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.

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

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?

You need to deactivate font hinting (Hinted property).

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:
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
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
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?

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.

Ascent and Descend present in LazFreeType. What is bottom margin?

It is LineSpacing.

No. it not work((

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.

However in other applications these fonts are displayed correctly

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.

Ok. I try to understand.
I made a small example (http://download.shamangrad.net/zcad/ttf2vector.7z). Need to get the character height SymbolH
const
SymbolH=300;
In the example of an incorrect calculation of the coefficient for the map coordinates in TTF to range 0SymbolH
k:=(FTTFFont.Ascent+FTTFFont.Descent+FTTFFont.LineSpacing)/FTTFFont.SizeInPixels;
k:=SymbolH*k/FTTFFont.SizeInPixels;
Archive contains the font arial.ttf

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.

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
'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 96127 ): 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((

faced with a strange moment. I look at the contents of the arial.ttf:
'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
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?

Maybe it includes rounded letters. See for example the letter C.

At last everything worked as it should! Require minor changes to EasyLazFreeType for CapHeight property. Please review the attached patch.

Congratulations, that's perfect.
Patch seems good to me.