unit Helios_Font;
{$I Global_Conditionals.INC}
interface
// font support
Const
GLYPH_START = 0;
GLYPH_END = 255;
GLYPH_CHARSTART = 32;
GLYPH_CHAREND = 127;
GLYPHS_PER_FONT = GLYPH_END - GLYPH_START;
Type
TGlyphInfo = Packed Record
height, // number of scan lines
top, // top of glyph in buffer
bottom, // bottom of glyph in buffer
pitch, // width for copying
xSkip, // x adjustment
imageWidth, // width of actual image
imageHeight : integer; // height of actual image
s, // x offset in image where glyph starts
t, // y offset in image where glyph starts
s2,
t2 : single;
glyph : integer; // handle to the shader with the glyph
ShaderName : Array [1..32] of Char;
end;
THelios_Font = record
Size : Integer;
Glyphs : array [0..255] of TGlyphInfo;
DisplayList : Integer;
Height : Integer;
end;
THelios_Fonts = record
Font : array of THelios_Font;
Font_No : Integer;
end;
Var
Fonts : THelios_Fonts;
//Function LoadAFont(Filename : String; Size : Integer) : Boolean;
//Procedure BuildFont(Var Font : THelios_Font);
Procedure BuildFonts;
Procedure LoadFonts;
Procedure WriteTextHN(X,Y : Single; S : Pchar; Font : THelios_Font);
implementation
Uses SysUtils,Helios_Filesystem, OpenGL15, Textures;
Function LoadFont(Filename : String; Size : Integer; Var Font : THelios_Font) : Boolean;
var
F : file;
X : Integer;
begin
Result := False;
If not Fileexists(Filename) then exit;
AssignFile(f, filename);
Reset(f,1);
Font.Size := Size;
Font.DisplayList := -1;
Font.Height := -1;
For x := 0 to 255 do
begin
BlockRead(F,Font.Glyphs[x],SizeOf(TGlyphInfo));
If Font.Glyphs[x].imageHeight > Font.Height then
Font.Height := Font.Glyphs[x].imageHeight;
end;
CloseFile(f);
Result := True;
end;
Function LoadAFont(Filename : String; Size : Integer) : Boolean;
var
X : integer;
begin
Result := False;
For x := 0 to Fonts.Font_No-1 do
if Fonts.Font[x].Size = Size then
begin
Result := True;
exit;
end;
Inc(Fonts.Font_No);
SetLength(Fonts.Font,Fonts.Font_No);
Result := LoadFont(Filename,Size,Fonts.Font[Fonts.Font_No-1]);
If Not Result then
begin
Dec(Fonts.Font_No);
SetLength(Fonts.Font,Fonts.Font_No);
end;
end;
Procedure LoadFonts;
begin
Fonts.Font_No := 0;
SetLength(Fonts.Font,Fonts.Font_No);
LoadAFont(DoesFileExist('fonts\fontimage_12.dat'),12);
LoadAFont(DoesFileExist('fonts\fontimage_16.dat'),16);
LoadAFont(DoesFileExist('fonts\fontimage_17.dat'),17);
LoadAFont(DoesFileExist('fonts\fontimage_24.dat'),24);
BuildFonts;
end;
Function CharArrayToStr(Chars : Array of Char; Ammount : Integer) : String;
var
x : integer;
begin
Result := '';
For x := 0 to Ammount-1 do
If Chars[x] <> #0 then
Result := Result + Chars[x]
else
Exit;
end;
Procedure BuildFont(Var Font : THelios_Font);
Var
I : Integer;
S : Cardinal;
CurTex,CurTex2 : String;
begin
glLoadIdentity;
CurTex := '';
CurTex2 := '';
s := 0;
Font.DisplayList := glGenLists(256);
for I := 0 to 255 do
begin
If (String(Font.Glyphs[I].ShaderName) <> CurTex2) then
begin
CurTex2 := String(Font.Glyphs[I].ShaderName);
CurTex := DoesFileExist(StringReplace(CharArrayToStr(Font.Glyphs[I].ShaderName,32), '/', '', [rfReplaceAll]));
If CurTex <> '' then
LoadTexture(CurTex,S,False,False,False);
end;
glNewList(Font.DisplayList+I, GL_COMPILE); // Start Building A List
glBegin(GL_QUADS);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, S);
glTexCoord2f(Font.Glyphs[i].s,1-Font.Glyphs[i].t2);
glVertex2i(0, Font.Glyphs[i].top - Font.Glyphs[i].height);
glTexCoord2f(Font.Glyphs[i].s2, 1-Font.Glyphs[i].t2);
glVertex2i( Font.Glyphs[i].imageWidth, Font.Glyphs[i].top - Font.Glyphs[i].height);
glTexCoord2f(Font.Glyphs[i].s2, 1-Font.Glyphs[i].t);
glVertex2i( Font.Glyphs[i].imageWidth, Font.Glyphs[i].top - Font.Glyphs[i].height + Font.Glyphs[i].imageHeight);
glTexCoord2f(Font.Glyphs[i].s,1-Font.Glyphs[i].t);
glVertex2i(0, Font.Glyphs[i].top - Font.Glyphs[i].height + Font.Glyphs[i].imageHeight);
glEnd();
If i = 32 then
glTranslatef(6, 0, 0)
else
glTranslatef(Font.Glyphs[I].imageWidth, 0, 0);
glEndList();
end;
glDisable(GL_BLEND);
end;
Procedure BuildFonts;
var
x : Integer;
begin
if Fonts.Font_No > 0 then
for x := 0 to Fonts.Font_No-1 do
BuildFont(Fonts.Font[x]);
end;
Procedure WriteTextHN(X,Y : Single; S : Pchar; Font : THelios_Font);
begin
glLoadIdentity;
glTranslatef(x,y,0);
{ glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
glColor4f(1,1,1,1);//Colour.X,Colour.Y,Colour.Z,Alpha);
// glRasterPos2f(X, SCREEN_HEIGHT-Y); // Set the position for the text to be rendered
glPushAttrib (GL_LIST_BIT);
glListBase(Font.DisplayList);
glCallLists(length(S),GL_UNSIGNED_BYTE,S); // Write The Text To The Screen
glPopAttrib();
glDisable(GL_BLEND);
end;
end.