Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 16:33

Foren-Übersicht » English » English Programming Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 35 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: Vector Font (Freetype for pascal?)
BeitragVerfasst: Di Aug 19, 2008 18:13 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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.

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Aug 19, 2008 19:34 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Aug 19, 2008 21:49 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 20, 2008 13:27 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 20, 2008 19:03 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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.  

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 21, 2008 00:03 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
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).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 21, 2008 08:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 21, 2008 20:14 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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.

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 09:00 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 11:56 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
You classvar method is cleaner then my solution where i made a procedurevar for each command. Both are not threadsave.

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 16:33 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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.  

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 18:29 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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.  

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 22, 2008 22:14 
Offline
DGL Member

Registriert: Di Aug 26, 2003 20:08
Beiträge: 81
Wohnort: Mönchengladbach
Programmiersprache: ObjPas ASM C C++ etc
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]
620-mal heruntergeladen

_________________
Behindert ist man nicht, behindert wird man.
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 10:54 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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.

_________________
http://3das.noeska.com - create adventure games without programming


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 25, 2008 13:20 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 01, 2003 18:59
Beiträge: 887
Wohnort: (The Netherlands)
Programmiersprache: fpc/delphi/java/c#
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 | 22654-mal betrachtet ]

_________________
http://3das.noeska.com - create adventure games without programming
Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 35 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Foren-Übersicht » English » English Programming Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.013s | 17 Queries | GZIP : On ]