GLText.pas

Top  Previous  Next

 

// Bitmap Fonts in OpenGL

unit GL_Text;

 

interface

 

uses

Windows, Messages, SysUtils, Graphics, OpenGL;

 

Type

PGLFont = ^TGLFont;

 

TGLFont = record

   b3D : Boolean;

   Angle : integer;

   bBold : Boolean;

   bItalic : Boolean;

   Height : Integer;

   Weight : Integer;

   CharSet : Cardinal;

   Typeface: PChar;

end;

 

TGLText = class

private

GLStrEng : PChar;

GLStrChn : PChar;

public

constructor Create(srcDC : HDC; EngStr, ChnStr : PChar;

                               EngFont, ChnFont : PGLFont);

destructor Destroy; override;

procedure Build(srcDC: HDC; glStr: PChar; glFont: PGLFont);

procedure wglUseFontBitmapsExt(srcDC : HDC; First, Count, ListBase: DWORD);

procedure glShowStr(glStr : PChar);

end;

 

 

implementation

 

{ TGLText }

procedure TGLText.Build(srcDC: HDC; glStr: PChar; glFont: PGLFont);

var

i,

Chartmp : Byte;

Font, oFont : HFONT;

glBold : Integer;

glItalic : Cardinal;

dwChar : DWORD;

gmf : GLYPHMETRICSFLOAT;

begin

 

if glFont.bBold then

  glBold := FW_BOLD

else

  glBold := FW_NORMAL;

 

if glFont.bItalic then

  glItalic := 1

else

  glItalic := 0;

 

Font := CreateFont(glFont.Height, glFont.Weight, glFont.Angle, 0, glBold,

    glItalic,

    0, 0, glFont.CharSet, OUT_TT_PRECIS,

    CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,

    FF_DONTCARE or DEFAULT_PITCH,

    glFont.Typeface);

 

oFont := SelectObject(srcDC, Font);

 

if glStr = 'All English' then

begin

for i := 32 to 255 do

if glFont.b3D then

wglUseFontOutLines(srcDC, i, 1, i, 0, 0, WGL_FONT_POLYGONS,

@gmf)

else

wglUseFontBitMaps(srcDC, i, 1, i);

end

else

begin

i := 0;

While i < StrLen(glStr) do

begin

Chartmp := Byte(glStr[i]);

if IsDBCSLeadByte(Chartmp) then

begin

dwChar := ((Chartmp shl 8) or Byte(glStr[i+1]));

i := i + 2;

end

else

begin

dwChar := Chartmp;

i := i + 1;

end;

if glFont.b3D then

wglUseFontOutLines(srcDC, dwChar, 1, dwChar, 0, 0,

WGL_FONT_POLYGONS, @gmf)

else

wglUseFontBitMapsExt(srcDC, dwChar, 1, dwChar);

end;

end;

 

SelectObject(srcDC, oFont);

DeleteObject(Font);

 

end;

 

constructor TGLText.Create(srcDC : HDC; EngStr, ChnStr: PChar;

                                EngFont, ChnFont: PGLFont);

begin

    GLStrEng := EngStr;

    GLStrChn := ChnStr;

 

    if EngStr <> nil then

       Build(srcDC, EngStr, EngFont);

 

    if ChnStr <> nil then

       Build(srcDC, ChnStr, ChnFont);

end;

 

destructor TGLText.Destroy;

var

i,

Chartmp : Byte;

dwChar : DWORD;

begin

 

if GLStrEng <> nil then

if GLStrEng = 'All English' then

begin

glDeleteLists(32, 93);

end

else

begin

i := 0;

While i < StrLen(GLStrEng) do

begin

dwChar := Byte(GLStrEng[i]);

glDeleteLists(dwChar, 1);

i := i + 1;

end;

end;

 

if GLStrChn <> nil then

begin

i := 0;

While i < StrLen(GLStrChn) do

begin

Chartmp := Byte(GLStrChn[i]);

if IsDBCSLeadByte(Chartmp) then

begin

dwChar := ((Chartmp shl 8) or Byte(GLStrChn[i+1]));

i := i + 2;

end

else

begin

dwChar := Chartmp;

i := i + 1;

end;

glDeleteLists(dwChar, 1);

end;

end;

 

inherited Destroy;

 

end;

 

procedure TGLText.glShowStr(glStr : PChar);

var

i,

Chartmp : Byte;

dwChar : DWORD;

begin

 

i := 0;

While i < StrLen(glStr) do

begin

Chartmp := Byte(glStr[i]);

if IsDBCSLeadByte(Chartmp) then

begin

dwChar := ((Chartmp shl 8) or Byte(glStr[i+1]));

i := i + 2;

end

else

begin

dwChar := Chartmp;

i := i + 1;

end;

glCallList(dwChar);

end;

 

end;

 

procedure TGLText.wglUseFontBitmapsExt(srcDC: HDC; First, Count,

ListBase: DWORD);

var

i : DWORD;

size : DWORD;

gm : GLYPHMETRICS;

hBits : THANDLE;

lpBits : PGLubyte;

mat : MAT2;

begin

 

mat.eM11.fract := 0;

mat.eM11.value := 1;

mat.eM12.fract := 0;

mat.eM12.value := 0;

mat.eM21.fract := 0;

mat.eM21.value := 0;

mat.eM22.fract := 0;

mat.eM22.value := -1;

 

for i := 0 to Count - 1 do

begin

glNewList(ListBase+i, GL_COMPILE);

 

size := GetGlyphOutline(srcDC, First+i, GGO_BITMAP, gm, 0, nil, mat);

 

hBits := GlobalAlloc(GHND, size);

lpBits := GlobalLock(hBits);

 

GetGlyphOutline(srcDC, //* handle to device context */

First+i, //* character to query */

GGO_BITMAP, //* format of data to return */

gm, //* pointer to structure for metrics */

size, //* size of buffer for data */

lpBits, //* pointer to buffer for data */

mat //* pointer to transformation */

//* matrix structure */

);

 

glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,

gm.gmptGlyphOrigin.x,

gm.gmptGlyphOrigin.y,

gm.gmCellIncX,gm.gmCellIncY,

lpBits);

 

 

GlobalUnlock(hBits);

GlobalFree(hBits);

 

glEndList;

end;

 

end;

 

end.