DGL
https://delphigl.com/forum/

Vector Font (Freetype for pascal?)
https://delphigl.com/forum/viewtopic.php?f=19&t=7761
Seite 1 von 3

Autor:  noeska [ Di Aug 19, 2008 18:13 ]
Betreff des Beitrags:  Vector Font (Freetype for pascal?)

Is it possible to use vector fonts with opengl? I know of wgl, but that is windows only.
Now there is also freetype2. It is supposed to be able to give access to the vector data of the glyph. That give me 3 questions:
1. Is there a delphi/pascal unit for freetype2?
2. How does rendering a glyph work? Bezier->Polygon->Triangulate?
3. Has someone else already done the hard work?

With knowing how point 2 works. The font can also be save in like a milkshape ascii format. So the original font is not needed.

Autor:  Traude [ Di Aug 19, 2008 19:34 ]
Betreff des Beitrags: 

Hallo Noeska,
Yes, there is already some code:

A project named "TextSuite" by Lossy eX: http://www.delphigl.com/forum/viewtopic.php?t=4859 and I think that he uses also Freetype, but I'm not quite sure

A font object named "TStdFont" that I have written myself, to be found here: http://glpasgui.bplaced.net/

And last not least SDL_TTF uses Freetype, as far as I know
Traude

Autor:  Lossy eX [ Di Aug 19, 2008 21:49 ]
Betreff des Beitrags: 

But in the TextSuite Library i only use Bitmap Chars. And at this moment the library dosn't support FreeType2. I startet to translate an header for it but the librarys header are around 1MB only interface definition (with much comments but it's still 1MB).

I mean FreeType supports reading of raw data. So you can use it with some splines and you will get an "simple" polygon. This you must tesslate into triangles and add an height and the char is done. The difficult part is got the polygon data. In the Windows API there is an function which returns the data. But in FreeType im not 100 percently sure. But it should possible. If i dont forget it i can take an look in the header. May i can find some usefull functions.

Anyway i dont know any other polygon fonts for multiple platforms. Only the WGL functions.

Autor:  Lossy eX [ Mi Aug 20, 2008 13:27 ]
Betreff des Beitrags: 

I have taken an short look in the header and if you load an glyph you normally get an FT_OutlineGlyph. And this allready contains the coordinates from the Outlines (it's possible to get more than one contour in one glyph). To get an Bitmap these outline must be rendered. But this isn't necessary for you.

Autor:  noeska [ Mi Aug 20, 2008 19:03 ]
Betreff des Beitrags: 

As always torry is verry helpful as it provides a ttf2vector component. Now this solutions is also windows only. But gives access to the font coords. And allowed me to render with GL_LINES.
http://www.torry.net/quicksearchd.php?S ... &Title=Yes
so with this i should also be able to extrude etc. I have yet to test it with my experimental 2dpolygon render to see if it can render it solid also, but i expect no problems there. It just needs a good cleanup.
And more importantly it is possible to save the font coords. So it is possible to render a font that is not available on the end user system. The ony thing to worry about is precission.

Only the font generator application would only run on windows only.

But for linux support freetype(2) is really needed.
@Lossy eX: where can i get the unit? And can you explain FT_OutlineGlyph a bit more?

Example:

Init
Code:
  1.  
  2.   TTF2Vector := TTTFToVectorConverter.Create(DGLForm);
  3.   TTF2Vector.Font := TFont.Create();
  4.   TTF2Vector.Font.Name := 'Arial';
  5.   // Setup spline precision (1 min, 100 max)
  6.   TTF2Vector.Precision := 1;
  7.  


Render
Code:
  1.  
  2.   // Get glyphs' strokes
  3.     glyphs := TTF2Vector.GetCharacterGlyphs( ord('m') );
  4.     if glyphs = nil then // May be a "empty" glyph !!!!
  5.       beep;
  6.     // Get character bounds
  7.     cbounds := glyphs.Bounds;
  8.     xm := (cbounds.Right-cbounds.Left+1) div 2;
  9.     ym := (cbounds.Bottom-cbounds.Top+1) div 2;
  10.     // Compute the scaling factors
  11.     sx := 0.5;//(PaintBox.Width-20)/(cbounds.Right-cbounds.Left+1);
  12.     sy := 0.5;//(PaintBox.Height-20)/(cbounds.Bottom-cbounds.Top+1);
  13.  
  14.     for i := 0 to glyphs.Count-1 do
  15.     begin
  16.       // Get a stroke
  17.       stroke := glyphs.Stroke[i];
  18.  
  19.         x1 := 10 + round( (stroke.Pt1.X-cbounds.Left) * sx );
  20.         x2 := 10 + round( (stroke.Pt2.X-cbounds.Left) * sx );
  21.         y1 := 10 + round( (stroke.Pt1.Y-cbounds.Top) * sy );
  22.         y2 := 10 + round( (stroke.Pt2.Y-cbounds.Top) * sy );
  23.  
  24.       // Draw the stroke
  25.       glBegin(GL_LINES);
  26.         glVertex3f(x1/1000, (y1-1)/1000, 0);
  27.         glVertex3f(x2/1000, (y2-1)/1000,0);
  28.       glEnd();
  29.  
  30.     end;
  31.     // Free the glyphs
  32.     glyphs.Free;
  33.  

Autor:  Traude [ Do Aug 21, 2008 00:03 ]
Betreff des Beitrags: 

Hallo Noeska,
But this would mean to implement it two times.

Do you know OGLFT: http://oglft.sourceforge.net/ ? On this site you can see what freetype can do for you (b.t.w. OGLFT is built in Blender, too).

You can find FT_OutlineGlyph etc. in the FreeType API reference:
FT_OutlineGlyph: http://www.freetype.org/freetype2/docs/reference/ft2-glyph_management.html
FT_Outline(included in FT_OutlineGlyph): http://www.freetype.org/freetype2/docs/reference/ft2-outline_processing.html#FT_Outline
FT_Vector(included in FT_Outline): http://www.freetype.org/freetype2/docs/reference/ft2-basic_types.html#FT_Vector
etc.

I did not use FT_OutlineGlyph in my Freetype font object because I wrote a texture font and therefore did not need it. But if you take a look at it you can see a lot of how to handle the freetype library inside this object (it is also a pascal header for Freetype2.DLL but does not provide all Freetype functionality).

Autor:  Lossy eX [ Do Aug 21, 2008 08:39 ]
Betreff des Beitrags: 

Zitat:
@Lossy eX: where can i get the unit?

At this moment? Nowhere. ;) But from saturday im in vacation for 2 weeks so i decide to upload it yet. But it is an really really developer snapshot! Im still converting functions like hell. So i don't have tested it under linux etc. But for an single person it's impossible to test all the functions of freetype.
http://files.opengl24.de/header/FreeType2_DEV.zip (55kb)

In the package there is an simple sample. This works under windows. I think you will understand it if you see it. After FT_Get_Glyph the glyph was copied into the variable glyph. And this mostly should be an outline glyph. For me i need to convert it to an bitmap. Same as Traude. But i actually dosn't use it.

Zitat:
And can you explain FT_OutlineGlyph a bit more?

I dont know much about the outlines. I have seen it during the header conversion. But the outlines only containing contours. But if you have holes inside an char they have an extra contour. But this contours must be subtracted from the main contour (this will controlled by the outline flag). For example in the Arial font. The char '1' dont have any holes so contours normally = 1. 'a' habe one hole so contours = 2. And 'B' have 2 holes so contours = 3. But if you have funny fonts this values can be different.

PS: Don't wonder about the crazy sizes in FreeType. They work with an 26dot6 integer values. The last 6 bits are decimal places. And the bit 7 means the value 1 in normal integer values.

Autor:  noeska [ Do Aug 21, 2008 20:14 ]
Betreff des Beitrags: 

I am using glu tesselation now. And with good results. Only how do i implement it as part of an class?

gluTessCallback(tess, GLU_TESS_BEGIN, @tessBeginCB);

@tessBeginCB cannot be part of the class and has to be an real procedure with stdcall.
But i need to access variable used it the class with these.

Autor:  Lossy eX [ Fr Aug 22, 2008 09:00 ]
Betreff des Beitrags: 

The glu callback always has to be single functions. For windows with stdcall as calling convetion and under linux with cdecl. Thats important.

So you can't use classmethods. But if i saw it right (im not sure) it's possible to pass an custom data pointer to the function gluTessBeginPolygon. This data will be sent via the callback GLU_TESS_BEGIN_DATA. But the parameter won't be sent to every call. So you have to cache these value. But in this fact you also can cache this before you tesslate. The result is the same. For an example of the strange description.

Code:
  1. var
  2.   gTessClass: TMyTessClass;
  3.  
  4.  
  5. procedure tessVertex3dv(const v: PGLdouble); {$IFDEF Win32}stdcall; {$ELSE}cdecl; {$ENDIF}
  6. begin
  7.   gTessClass.PutVertex3dv(v);
  8. end;
  9.  
  10.  
  11. procedure TMyTessClass.TesslateAnyFunnyStuff;
  12. begin
  13.   gTessClass := Self;
  14.  
  15.   gluTessCallback(tessobj, GLU_VERTEX, tessVertex3dv);
  16.   gluBeginPolygon(tessobj);
  17.     gluTessVertex(tessobj, ...);
  18.     ...
  19.   gluEndPolygon(tessobj);
  20.  
  21.   gTessClass := nil;
  22. end;
  23.  
  24. procedure TMyTessClass.PutVertex3dv(const v: PGLdouble);
  25. begin
  26.   // do any stuff with v
  27. end;

I think there is no other way to handle it.

BUT. This Method is 100% not threadsafe! If it should possible to use it from different threads you can use threadvars instead of var. So every thread has it's own variable. Or and you can (must) use some technics to make sure that 2 threads dont use it at the same time. I mean TCriticalSection. If your using var you need 1 CriticalSection. If you are using threadvar the critical section also should be an threadvar. But in this fact the initialization of the CriticalSection may be some difficulty. Because linux dosn't support the initialization part of Pascal.

Autor:  noeska [ Fr Aug 22, 2008 11:56 ]
Betreff des Beitrags: 

You classvar method is cleaner then my solution where i made a procedurevar for each command. Both are not threadsave.

Autor:  noeska [ Fr Aug 22, 2008 16:33 ]
Betreff des Beitrags: 

My TPolygon Class: (MPL license)

Code:
  1.  
  2. unit Polygon;
  3.  
  4. interface
  5.  
  6. uses DGLOpenGL;
  7.  
  8. type
  9. TPoint = packed record
  10.   x: single;
  11.   y: single;
  12.   z: single;
  13.   r: single;
  14.   g: single;
  15.   b: single;
  16.   a: single;
  17. end;
  18.  
  19. TPolygon = class
  20. private
  21.   FPoints: array of TPoint; //polygon point
  22.   FVertex: array of TPoint; //triangulated data
  23.   FColor: TPoint;
  24.   FCount: integer;
  25.   FVertexCount: integer;
  26.   FTesselated: boolean;
  27.   procedure SetPoint(I: integer; Value: TPoint);
  28.   procedure AddVertex(x: single; y: single; z: single; r: single; g: single; b: single; a:single);
  29.   function GetPoint(I: integer): TPoint;
  30.   function GetCount(): integer;
  31.   procedure tessBegin(which: GLenum);
  32.   procedure tessEnd();
  33.   procedure tessVertex(x: single; y: single; z: single; r: single; g: single; b: single; a:single);
  34. public
  35.   constructor Create();
  36.   destructor Destroy();
  37.   procedure SetColor(R: single; G: single; B: single;A: single);
  38.   procedure Add(X: single; Y: single); overload;
  39.   procedure Add(X: single; Y: single; Z: single); overload;
  40.   procedure Add(X: single; Y: single; Z: single; R: single; G: single; B: single; A: single); overload;
  41.   procedure Render();
  42.   procedure Tesselate();
  43.   property Points[I: integer]: TPoint read GetPoint write SetPoint;
  44.   property Count: integer read GetCount;
  45. end;
  46.  
  47. implementation
  48.  
  49. type
  50.      TGLArrayd6 = array[0..5] of GLDouble;
  51.      PGLArrayd6 = ^TGLArrayd6;
  52.      TGLArrayvertex4 = array[0..3] of PGLArrayd6;
  53.      PGLArrayvertex4 = ^TGLArrayvertex4;
  54.      PGLArrayf4 = ^TGLArrayf4;
  55.  
  56. threadvar
  57.   PolygonClass: TPolygon;
  58.  
  59. procedure TPolygon.SetColor(R: single; G: single; B: single;A: single);
  60. begin
  61.   FColor.r := R;
  62.   FColor.g := G;
  63.   FColor.b := B;
  64.   FColor.a := A;
  65. end;
  66.  
  67. procedure TPolygon.tessBegin(which: GLenum);
  68. begin
  69.     glBegin(which);
  70. end;
  71.  
  72. procedure TPolygon.tessEnd();
  73. begin
  74.     glEnd();
  75. end;
  76.  
  77. procedure TPolygon.tessVertex(x: single; y: single; z: single; r: single; g: single; b: single; a:single);
  78. begin
  79.     glcolor3f(r,g,b);
  80.     glVertex3f(x,y,z);
  81. end;
  82.  
  83. procedure TPolygon.AddVertex(x: single; y: single; z: single; r: single; g: single; b: single; a:single);
  84. begin
  85.     FVertexCount := FVertexCount + 1;
  86.     SetLength(FVertex, FVertexCount);
  87.  
  88.     FVertex[FVertexCount-1].R := R;
  89.     FVertex[FVertexCount-1].G := G;
  90.     FVertex[FVertexCount-1].B := B;
  91.  
  92.     FVertex[FVertexCount-1].X := X;
  93.     FVertex[FVertexCount-1].Y := Y;
  94.     FVertex[FVertexCount-1].Z := Z;
  95. end;
  96.  
  97. constructor TPolygon.Create();
  98. begin
  99.   inherited Create();
  100.   FCount := 0;
  101.   FVertexCount := 0;
  102.   FTesselated := false;
  103.   FColor.R := 0.0;
  104.   FColor.G := 0.0;
  105.   FColor.B := 0.0;
  106.   FColor.A := 0.0;
  107. end;
  108.  
  109. destructor TPolygon.Destroy();
  110. begin
  111.   FTesselated := false;
  112.   FCount := 0;
  113.   FVertexCount := 0;
  114.   SetLength(FPoints, FCount);
  115.   SetLength(FVertex, FVertexCount);
  116.   inherited Destroy;
  117. end;
  118.  
  119. procedure TPolygon.SetPoint(I: integer; Value: TPoint);
  120. begin
  121.   FTesselated := false; //check first on changed values
  122.   FPoints[I] := Value;
  123. end;
  124.  
  125. function TPolygon.GetPoint(I: integer): TPoint;
  126. begin
  127.   result := FPoints[I];
  128. end;
  129.  
  130. function TPolygon.GetCount(): integer;
  131. begin
  132.   result := FCount;
  133. end;
  134.  
  135. procedure TPolygon.Add(X: single; Y: single);
  136. begin
  137.   FTesselated := false;
  138.   FCount := FCount + 1;
  139.   SetLength(FPoints, FCount);
  140.   FPoints[FCount-1].X := X;
  141.   FPoints[FCount-1].Y := Y;
  142.   FPoints[FCount-1].Z := 0.0;
  143.   FPoints[FCount-1].R := FColor.R;
  144.   FPoints[FCount-1].G := FColor.G;
  145.   FPoints[FCount-1].B := FColor.B;
  146.   FPoints[FCount-1].A := FColor.A;
  147. end;
  148.  
  149. procedure TPolygon.Add(X: single; Y: single; Z: single);
  150. begin
  151.   FTesselated := false;
  152.   FCount := FCount + 1;
  153.   SetLength(FPoints, FCount);
  154.   FPoints[FCount-1].X := X;
  155.   FPoints[FCount-1].Y := Y;
  156.   FPoints[FCount-1].Z := Z;
  157.   FPoints[FCount-1].R := FColor.R;
  158.   FPoints[FCount-1].G := FColor.G;
  159.   FPoints[FCount-1].B := FColor.B;
  160.   FPoints[FCount-1].A := FColor.A;
  161. end;
  162.  
  163. procedure TPolygon.Add(X: single; Y: single; Z: single; R: single; G: single; B: single; A: single);
  164. begin
  165.   FTesselated := false;
  166.   FCount := FCount + 1;
  167.   SetLength(FPoints, FCount);
  168.   FPoints[FCount-1].X := X;
  169.   FPoints[FCount-1].Y := Y;
  170.   FPoints[FCount-1].Z := Z;
  171.   FPoints[FCount-1].R := R;
  172.   FPoints[FCount-1].G := G;
  173.   FPoints[FCount-1].B := B;
  174.   FPoints[FCount-1].A := A;
  175. end;
  176.  
  177. Procedure TPolygon.Render();
  178. var
  179.   loop: integer;
  180. begin
  181.   if FTesselated = false then Tesselate;
  182.  
  183.   glbegin(GL_TRIANGLES);
  184.   for loop:=0 to FVertexCount-1 do
  185.   begin
  186.     glcolor3f(FVertex[loop].R,FVertex[loop].G,FVertex[loop].B);
  187.     glvertex3f(FVertex[loop].X,FVertex[loop].Y,FVertex[loop].Z);
  188.   end;
  189.   glend;
  190. end;
  191.  
  192. procedure TPolygon.Tesselate();
  193. var
  194.   loop: integer;
  195.   tess: pointer;
  196.   test: TGLArrayd3;
  197.   pol: PGLArrayd6;
  198.  
  199.   MyTest: string;
  200.  
  201. procedure iTessBeginCB(which: GLenum); {$IFDEF Win32}stdcall; {$ELSE}cdecl; {$ENDIF}
  202. begin
  203.   //PolygonClass.tessBegin(which);
  204. end;
  205.  
  206. procedure iTessEndCB(); {$IFDEF Win32}stdcall; {$ELSE}cdecl; {$ENDIF}
  207. begin
  208.   //PolygonClass.tessEnd();
  209. end;
  210.  
  211. procedure iTessEdgeCB(flag: GLboolean; lpContext: pointer); {$IFDEF Win32}stdcall; {$ELSE}cdecl; {$ENDIF}
  212. begin
  213.       //just do nothing to force GL_TRIANGLES !!!
  214. end;
  215.  
  216. procedure iTessVertexCB(data: PGLArrayd6); {$IFDEF Win32}stdcall; {$ELSE}cdecl; {$ENDIF}
  217. begin
  218.   //PolygonClass.tessVertex(data[0], data[1], data[2], data[3], data[4], data[5],0);
  219.   PolygonClass.AddVertex(data[0], data[1], data[2], data[3], data[4], data[5],0);
  220. end;
  221.  
  222.  
  223. procedure iTessCombineCB(newVertex : PGLArrayd6; neighborVertex : Pointer;
  224.                       neighborWeight : Pointer; var outData : Pointer); {$IFDEF Win32}stdcall; {$ELSE}cdecl; {$ENDIF}
  225. var
  226.   vertex: PGLArrayd6;
  227.   loop: integer;
  228.   colorloop: integer;
  229.   color: double;
  230. begin
  231.   new(vertex);
  232.  
  233.   vertex[0] := newVertex^[0];
  234.   vertex[1] := newVertex^[1];
  235.   vertex[2] := newVertex^[2];
  236.  
  237.   for colorloop := 3 to 5 do
  238.   begin
  239.     vertex[colorloop] := 0.0;
  240.     for loop:=0 to 3 do
  241.     begin
  242.       if PGLArrayf4(neighborWeight)^[loop] <> 0 then
  243.       begin
  244.         vertex[colorloop] := vertex[colorloop] +
  245.              PGLArrayf4(neighborWeight)^[loop] *
  246.              PGLArrayvertex4(neighborVertex)^[loop][colorloop]
  247.       end;
  248.     end;
  249.   end;
  250.  
  251.   // return output data (vertex coords and others)
  252.   outData:= vertex;
  253. end;
  254.  
  255. begin
  256.   PolygonClass := Self;
  257.  
  258.   tess := gluNewTess();
  259.  
  260.   gluTessCallback(tess, GLU_TESS_BEGIN, @iTessBeginCB );
  261.   gluTessCallback(tess, GLU_TESS_END, @iTessEndCB);
  262.   gluTessCallback(tess, GLU_TESS_VERTEX, @iTessVertexCB);
  263.   gluTessCallback(tess, GLU_TESS_COMBINE, @iTessCombineCB);  //does not work for font?
  264.   gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, @iTessEdgeCB); //force triangles
  265.  
  266.   gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO );
  267.  
  268.   gluTessBeginPolygon(tess, nil);                   // with NULL data
  269.   gluTessBeginContour(tess);
  270.  
  271.   for loop := 0 to FCount-1 do
  272.   begin
  273.       new(pol);
  274.       pol[3]:=FPoints[loop].R; //color
  275.       pol[4]:=FPoints[loop].G;
  276.       pol[5]:=FPoints[loop].B;
  277.  
  278.       pol[0]:=FPoints[loop].X;
  279.       pol[1]:=FPoints[loop].Y;
  280.       pol[2]:=0;
  281.  
  282.       test[0] := pol[0];
  283.       test[1] := pol[1];
  284.       test[2] := pol[2];
  285.       gluTessVertex(tess, test, pol);
  286.   end;
  287.  
  288.   gluTessEndContour(tess);
  289.   gluTessEndPolygon(tess);
  290.   gluDeleteTess(tess);        // delete after tessellation
  291.  
  292.   PolygonClass := nil;
  293.   FTesselated := true;
  294. end;
  295.  
  296. end.
  297.  

Autor:  noeska [ Fr Aug 22, 2008 18:29 ]
Betreff des Beitrags: 

My PolygonFont class: (MPL license)

Needs to be improved. Also only does a..z lowercase only.
And needs freetype integration.

Code:
  1.  
  2. unit PolygonFont;
  3.  
  4. interface
  5.  
  6. uses Polygon;
  7.  
  8. type
  9. TPolygonFont = class
  10.      private
  11.         FCharGlyph: array[0..255] of TPolygon;
  12.         FCharWidth: array[0..255] of integer;
  13.         FName: string;
  14.         FPrecision: integer;
  15.         FScale: single;
  16.      public
  17.         procedure Generate();
  18.         procedure RenderChar(value: char);
  19.         procedure RenderString(value: string);
  20.         property Name: string read FName write FName;
  21.         property Precision: integer read FPrecision write FPrecision;
  22.         property Scale: single read FScale write FScale;
  23.      end;
  24.  
  25. implementation
  26.  
  27. uses DGLOpenGL, VectorFont, Windows, Graphics;
  28.  
  29. procedure TPolygonFont.Generate();
  30. var
  31.   loop: integer;
  32.   glyphs: TStrokeCollection;
  33.   cbounds: TRect;
  34.   x1, y1, x2, y2, xm, ym: integer;
  35.   sx, sy: double; // Scaling factors
  36.   i, j, k, sog: integer;
  37.   stroke: TFontStroke;
  38.   //scale: integer;
  39.  
  40.     TTF2Vector: TTTFToVectorConverter;
  41.  
  42. begin
  43.  
  44.  //vectorfont test
  45.   TTF2Vector := TTTFToVectorConverter.Create(nil);
  46.   TTF2Vector.Font := TFont.Create();
  47.   TTF2Vector.Font.Name := FName;
  48.   // Setup spline precision (1 min, 100 max)
  49.   TTF2Vector.Precision := FPrecision;
  50.  
  51.   for loop := 0 to 255 do
  52.   begin
  53.     FCharGlyph[loop] := TPolygon.Create();
  54.     //FCharGlyph[loop].Outline := true;
  55.     FCharGlyph[loop].SetColor(0.0,1.0,0.0,0.0);
  56.  
  57.     // Get glyphs' strokes
  58.     if (loop >= ord('a')) and (loop <= ord('z')) then
  59.     begin
  60.     glyphs := TTF2Vector.GetCharacterGlyphs( loop );
  61.  
  62.     // Get character bounds
  63.     cbounds := glyphs.Bounds;
  64.     xm := (cbounds.Right-cbounds.Left+1) div 2;
  65.     ym := (cbounds.Bottom-cbounds.Top+1) div 2;
  66.  
  67.     // Compute the scaling factors
  68.     sx := fscale;
  69.     sy := fscale;
  70.  
  71.     for i := 0 to glyphs.Count-1 do
  72.     begin
  73.       // Get a stroke
  74.       stroke := glyphs.Stroke[i];
  75.  
  76.       x1 := 10 + round( (stroke.Pt1.X-cbounds.Left) * sx );
  77.       x2 := 10 + round( (stroke.Pt2.X-cbounds.Left) * sx );
  78.       y1 := 10 + round( (stroke.Pt1.Y-cbounds.Top) * sy );
  79.       y2 := 10 + round( (stroke.Pt2.Y-cbounds.Top) * sy );
  80.  
  81.       FCharGlyph[loop].Add(x1/1000, (y1-1)/1000);
  82.       FCharGlyph[loop].Add(x2/1000, (y2-1)/1000);
  83.     end;
  84.  
  85.   // Free the glyphs
  86.   glyphs.Free;
  87.  
  88.   FCharWidth[loop] := cbounds.Right;
  89.   FCharGlyph[loop].Tesselate();
  90.   end;
  91.  
  92.   end;
  93.  
  94.   TTF2Vector.Free;
  95. end;
  96.  
  97. procedure TPolygonFont.RenderChar(value: char);
  98. begin
  99.   FCharGlyph[ord(value)].Render();
  100.   glTranslatef((FCharWidth[ord(value)]*fscale)/1000, 0, 0);
  101. end;
  102.  
  103. procedure TPolygonFont.RenderString(value: string);
  104. var
  105.   i: integer;
  106. begin
  107.   for i :=1 to length(value) do
  108.   begin
  109.     RenderChar(value[i]);
  110.   end;
  111. end;
  112.  
  113. end.
  114.  

Autor:  bero [ Fr Aug 22, 2008 22:14 ]
Betreff des Beitrags: 

Here http://bero.freqvibez.net/BeRoVectorFont.zip (or at post attachment) is my native own typetype font loader with pas src, but please give credits! I'm using it in my own complete-SVG-compliant rendering engine and vector artist software.

Dateianhänge:
BeRoVectorFont.zip [22.03 KiB]
625-mal heruntergeladen

Autor:  noeska [ Sa Aug 23, 2008 10:54 ]
Betreff des Beitrags: 

You have a native pascal ttf reader. No need for freetype2 or even windows? Nice work.

So with GetCommand i can set a char or even a text and i get back an array of fontcommands. So that still has to be converted to strokes to get a flat font outline.

My goal is to get a opengl accelerated vector gui. svg/xaml is not a goal for me.

Autor:  noeska [ Mo Aug 25, 2008 13:20 ]
Betreff des Beitrags: 

I am getting a bug when rendering outlines (see attached image).
It only happens with characters that consist of multiple parts like the i .

As i use the outlines also for extruding that also fails.

So how do i detect the beginning of a new part?
Does the font-data give info on this?

Dateianhänge:
vectorfontbug.jpg
vectorfontbug.jpg [ 13.28 KiB | 22793-mal betrachtet ]

Seite 1 von 3 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/