From 70a287773fc7001b810b9f91daf6d6e941e662f3 Mon Sep 17 00:00:00 2001 From: tobigun Date: Sat, 1 Nov 2008 11:04:27 +0000 Subject: - freetype enabled by default - Result[DstPos] := WideChar(Src[SrcPos]) must be Result[DstPos] := WideChar(Ord(Src[SrcPos])) otherwise FPC (but not Delphi) will convert the character according to current locale. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@1495 b956fd51-792f-4845-bead-9b4dfca2ff2c --- unicode/src/base/TextGL.pas | 320 +++++++++--------------------------- unicode/src/base/TextGLFreetype.pas | 222 ------------------------- unicode/src/base/UTextEncoding.pas | 5 +- unicode/src/switches.inc | 2 - unicode/src/ultrastardx.dpr | 12 +- 5 files changed, 87 insertions(+), 474 deletions(-) delete mode 100644 unicode/src/base/TextGLFreetype.pas diff --git a/unicode/src/base/TextGL.pas b/unicode/src/base/TextGL.pas index 11bbd52b..e3724e9c 100644 --- a/unicode/src/base/TextGL.pas +++ b/unicode/src/base/TextGL.pas @@ -33,17 +33,26 @@ interface {$I switches.inc} -// as long as the transition to freetype is not finished -// use the old implementation -{$IFDEF UseFreetype} - {$INCLUDE TextGLFreetype.pas} -{$ELSE} uses gl, + glext, SDL, UTexture, + UFont, + Classes, ULog; +type + PGLFont = ^TGLFont; + TGLFont = record + Font: TScalableFont; + X, Y, Z: real; + end; + +var + Fonts: array of TGLFont; + ActFont: integer; + procedure BuildFont; // build our bitmap font procedure KillFont; // delete the font function glTextWidth(const text: string): real; // returns text width @@ -54,148 +63,78 @@ procedure SetFontZ(Z: real); // sets Z procedure SetFontSize(Size: real); procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc) procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts) -procedure SetFontAspectW(Aspect: real); procedure SetFontReflection(Enable:boolean;Spacing: real); // enables/disables text reflection -//function NextPowerOfTwo(Value: integer): integer; -// Checks if the ttf exists, if yes then a SDL_ttf is returned -//function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font; -// Does the renderstuff, color is in $ffeecc style -//function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal):PSDL_Surface; - -type - TTextGL = record - X: real; - Y: real; - Z: real; - Text: string; - Size: real; - ColR: real; - ColG: real; - ColB: real; - end; - - PFont = ^TFont; - TFont = record - Tex: TTexture; - Width: array[0..255] of byte; - AspectW: real; - Centered: boolean; - Outline: real; - Italic: boolean; - Reflection: boolean; - ReflectionSpacing: real; - end; - - -var - Fonts: array of TFont; - ActFont: integer; - - implementation uses UMain, UCommon, + UTextEncoding, SysUtils, - IniFiles, - Classes, - UGraphic; + IniFiles; +function FindFontFile(FontIni: TCustomIniFile; Font: string): string; var - // Colours for the reflection - TempColor: array[0..3] of GLfloat; - -{** - * Load font info. - * FontFile is the name of the image (.png) not the data (.dat) file - *} -procedure LoadFontInfo(FontID: integer; const FontFile: string); -var - Stream: TFileStream; - DatFile: string; + Filename: string; begin - DatFile := ChangeFileExt(FontFile, '.dat'); - FillChar(Fonts[FontID].Width[0], Length(Fonts[FontID].Width), 0); - - Stream := nil; - try - Stream := TFileStream.Create(DatFile, fmOpenRead); - Stream.Read(Fonts[FontID].Width, 256); - except - Log.LogError('Error while reading font['+ inttostr(FontID) +']', 'LoadFontInfo'); - end; - Stream.Free; + Filename := FontIni.ReadString(Font, 'File', ''); + Result := FontPath + Filename; + // if path does not exist, try as an absolute path + if (not FileExists(Result)) then + Result := Filename; end; -// Builds bitmap fonts procedure BuildFont; var - Count: integer; FontIni: TMemIniFile; - FontFile: string; // filename of the image (with .png/... ending) + //BitmapFont: TBitmapFont; + FontFile: string; begin ActFont := 0; SetLength(Fonts, 4); - FontIni := TMemIniFile.Create(FontPath + 'fonts.ini'); - - // Normal - - FontFile := FontPath + FontIni.ReadString('Normal', 'File', ''); - - Fonts[0].Tex := Texture.LoadTexture(true, FontFile, TEXTURE_TYPE_TRANSPARENT, 0); - Fonts[0].Tex.H := 30; - Fonts[0].AspectW := 0.9; - Fonts[0].Outline := 0; - - LoadFontInfo(0, FontFile); - - // Bold - - FontFile := FontPath + FontIni.ReadString('Bold', 'File', ''); + FontIni := TMemIniFile.Create(FontPath + 'fontsTTF.ini'); + //FontIni := TMemIniFile.Create(FontPath + 'fonts.ini'); - Fonts[1].Tex := Texture.LoadTexture(true, FontFile, TEXTURE_TYPE_TRANSPARENT, 0); - Fonts[1].Tex.H := 30; - Fonts[1].AspectW := 1; - Fonts[1].Outline := 0; - - LoadFontInfo(1, FontFile); - for Count := 0 to 255 do - Fonts[1].Width[Count] := Fonts[1].Width[Count] div 2; - - // Outline1 - - FontFile := FontPath + FontIni.ReadString('Outline1', 'File', ''); + try - Fonts[2].Tex := Texture.LoadTexture(true, FontFile, TEXTURE_TYPE_TRANSPARENT, 0); - Fonts[2].Tex.H := 30; - Fonts[2].AspectW := 0.95; - Fonts[2].Outline := 5; + // Normal + FontFile := FindFontFile(FontIni, 'Normal'); + Fonts[0].Font := TFTScalableFont.Create(FontFile, 64); + //Fonts[0].Font.GlyphSpacing := 1.4; + //Fonts[0].Font.Aspect := 1.2; - LoadFontInfo(2, FontFile); - for Count := 0 to 255 do - Fonts[2].Width[Count] := Fonts[2].Width[Count] div 2 + 2; + { + BitmapFont := TBitmapFont.Create(FontFile, 0, 19, 35, -10); + BitmapFont.CorrectWidths(2, 0); + Fonts[0].Font := TScalableFont.Create(BitmapFont, false); + } - // Outline2 + //Fonts[0].Font.Aspect := 0.9; - FontFile := FontPath + FontIni.ReadString('Outline2', 'File', ''); + // Bold + FontFile := FindFontFile(FontIni, 'Bold'); + Fonts[1].Font := TFTScalableFont.Create(FontFile, 64); - Fonts[3].Tex := Texture.LoadTexture(true, FontFile, TEXTURE_TYPE_TRANSPARENT, 0); - Fonts[3].Tex.H := 30; - Fonts[3].AspectW := 0.95; - Fonts[3].Outline := 4; + // Outline1 + FontFile := FindFontFile(FontIni, 'Outline1'); + Fonts[2].Font := TFTScalableOutlineFont.Create(FontFile, 64, 0.06); + //TFTScalableOutlineFont(Fonts[2].Font).SetOutlineColor(0.3, 0.3, 0.3); - LoadFontInfo(3, FontFile); - for Count := 0 to 255 do - Fonts[3].Width[Count] := Fonts[3].Width[Count] + 1; + // Outline2 + FontFile := FindFontFile(FontIni, 'Outline2'); + Fonts[3].Font := TFTScalableOutlineFont.Create(FontFile, 64, 0.08); + except on E: Exception do + Log.LogCritical(E.Message, 'BuildFont'); + end; // close ini-file FontIni.Free; end; + // Deletes the font procedure KillFont; begin @@ -205,131 +144,30 @@ end; function glTextWidth(const text: string): real; var - Letter: char; - i: integer; - Font: PFont; + Bounds: TBoundsDbl; begin - Result := 0; - Font := @Fonts[ActFont]; - - for i := 0 to Length(text) -1 do - begin - Letter := Text[i]; - Result := Result + Font.Width[Ord(Letter)] * Font.Tex.H / 30 * Font.AspectW; - end; - - if ((Result > 0) and Font.Italic) then - Result := Result + 12 * Font.Tex.H / 60 * Font.AspectW; -end; - -procedure glPrintLetter(Letter: char); -var - TexX, TexY: real; - TexR, TexB: real; - TexHeight: real; - FWidth: real; - PL, PT: real; - PR, PB: real; - XItal: real; // X shift for italic type letter - ReflectionSpacing: real; // Distance of the reflection - Font: PFont; - Tex: PTexture; -begin - Font := @Fonts[ActFont]; - Tex := @Font.Tex; - - FWidth := Font.Width[Ord(Letter)]; - - Tex.W := FWidth * (Tex.H/30) * Font.AspectW; - - // set texture positions - TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Font.Outline/1024; - TexY := (ord(Letter) div 16) * 1/16 + 2/1024; - TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Font.Outline/1024; - TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024; - - TexHeight := TexB - TexY; - - // set vector positions - PL := Tex.X - Font.Outline * (Tex.H/30) * Font.AspectW /2; - PT := Tex.Y; - PR := PL + Tex.W + Font.Outline * (Tex.H/30) * Font.AspectW; - PB := PT + Tex.H; - - if (not Font.Italic) then - XItal := 0 - else - XItal := 12; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, Tex.TexNum); - - glBegin(GL_QUADS); - glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT); - glTexCoord2f(TexX, TexB); glVertex2f(PL, PB); - glTexCoord2f(TexR, TexB); glVertex2f(PR, PB); - glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT); - glEnd; - - // Reflection - // Yes it would make sense to put this in an extra procedure, - // but this works, doesn't take much lines, and is almost lightweight - if Font.Reflection then - begin - ReflectionSpacing := Font.ReflectionSpacing + Tex.H/2; - - glDepthRange(0, 10); - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - - glBegin(GL_QUADS); - glColor4f(TempColor[0], TempColor[1], TempColor[2], 0); - glTexCoord2f(TexX, TexY + TexHeight/2); - glVertex3f(PL, PB + ReflectionSpacing - Tex.H/2, Tex.z); - - glColor4f(TempColor[0], TempColor[1], TempColor[2], Tex.Alpha-0.3); - glTexCoord2f(TexX, TexB ); - glVertex3f(PL + XItal, PT + ReflectionSpacing, Tex.z); - - glTexCoord2f(TexR, TexB ); - glVertex3f(PR + XItal, PT + ReflectionSpacing, Tex.z); - - glColor4f(TempColor[0], TempColor[1], TempColor[2], 0); - glTexCoord2f(TexR, TexY + TexHeight/2); - glVertex3f(PR, PB + ReflectionSpacing - Tex.H/2, Tex.z); - glEnd; - - glDisable(GL_DEPTH_TEST); - end; // reflection - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - Tex.X := Tex.X + Tex.W; - - //write the colour back - glColor4fv(@TempColor); + Bounds := Fonts[ActFont].Font.BBox(Text, true); + Result := Bounds.Right - Bounds.Left; end; // Custom GL "Print" Routine procedure glPrint(const Text: string); var - Pos: integer; + GLFont: PGLFont; begin // if there is no text do nothing if (Text = '') then Exit; - //Save the actual color and alpha (for reflection) - glGetFloatv(GL_CURRENT_COLOR, @TempColor); + GLFont := @Fonts[ActFont]; - for Pos := 1 to Length(Text) do - begin - glPrintLetter(Text[Pos]); - end; + glPushMatrix(); + // set font position + glTranslatef(GLFont.X, GLFont.Y + GLFont.Font.Ascender, GLFont.Z); + // draw string + //GLFont.Font.Print(RecodeString(Text, encCP1252)); + GLFont.Font.Print(Text); + glPopMatrix(); end; procedure ResetFont(); @@ -342,18 +180,18 @@ end; procedure SetFontPos(X, Y: real); begin - Fonts[ActFont].Tex.X := X; - Fonts[ActFont].Tex.Y := Y; + Fonts[ActFont].X := X; + Fonts[ActFont].Y := Y; end; procedure SetFontZ(Z: real); begin - Fonts[ActFont].Tex.Z := Z; + Fonts[ActFont].Z := Z; end; procedure SetFontSize(Size: real); begin - Fonts[ActFont].Tex.H := Size; + Fonts[ActFont].Font.Height := Size; end; procedure SetFontStyle(Style: integer); @@ -363,21 +201,19 @@ end; procedure SetFontItalic(Enable: boolean); begin - Fonts[ActFont].Italic := Enable; -end; - -procedure SetFontAspectW(Aspect: real); -begin - Fonts[ActFont].AspectW := Aspect; + if (Enable) then + Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style + [Italic] + else + Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style - [Italic] end; procedure SetFontReflection(Enable: boolean; Spacing: real); begin - Fonts[ActFont].Reflection := Enable; - Fonts[ActFont].ReflectionSpacing := Spacing; + if (Enable) then + Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style + [Reflect] + else + Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style - [Reflect]; + Fonts[ActFont].Font.ReflectionSpacing := Spacing - Fonts[ActFont].Font.Descender; end; end. - -{$ENDIF} - diff --git a/unicode/src/base/TextGLFreetype.pas b/unicode/src/base/TextGLFreetype.pas deleted file mode 100644 index 61b26693..00000000 --- a/unicode/src/base/TextGLFreetype.pas +++ /dev/null @@ -1,222 +0,0 @@ -{* UltraStar Deluxe - Karaoke Game - * - * UltraStar Deluxe is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * $URL: https://ultrastardx.svn.sourceforge.net/svnroot/ultrastardx/trunk/src/base/TextGL.pas $ - * $Id: TextGL.pas 1483 2008-10-28 19:01:20Z tobigun $ - *} - -(* -unit TextGL; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} -*) - -uses - gl, - glext, - SDL, - UTexture, - UFont, - Classes, - ULog; - -type - PGLFont = ^TGLFont; - TGLFont = record - Font: TScalableFont; - X, Y, Z: real; - end; - -var - Fonts: array of TGLFont; - ActFont: integer; - -procedure BuildFont; // build our bitmap font -procedure KillFont; // delete the font -function glTextWidth(const text: string): real; // returns text width -procedure glPrint(const text: string); // custom GL "Print" routine -procedure ResetFont(); // reset font settings of active font -procedure SetFontPos(X, Y: real); // sets X and Y -procedure SetFontZ(Z: real); // sets Z -procedure SetFontSize(Size: real); -procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc) -procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts) -procedure SetFontReflection(Enable:boolean;Spacing: real); // enables/disables text reflection - -implementation - -uses - UMain, - UCommon, - UTextEncoding, - SysUtils, - IniFiles; - -function FindFontFile(FontIni: TCustomIniFile; Font: string): string; -var - Filename: string; -begin - Filename := FontIni.ReadString(Font, 'File', ''); - Result := FontPath + Filename; - // if path does not exist, try as an absolute path - if (not FileExists(Result)) then - Result := Filename; -end; - -procedure BuildFont; -var - FontIni: TMemIniFile; - //BitmapFont: TBitmapFont; - FontFile: string; -begin - ActFont := 0; - - SetLength(Fonts, 4); - FontIni := TMemIniFile.Create(FontPath + 'fontsTTF.ini'); - //FontIni := TMemIniFile.Create(FontPath + 'fonts.ini'); - - try - - // Normal - FontFile := FindFontFile(FontIni, 'Normal'); - Fonts[0].Font := TFTScalableFont.Create(FontFile, 64); - //Fonts[0].Font.GlyphSpacing := 1.4; - //Fonts[0].Font.Aspect := 1.2; - - { - BitmapFont := TBitmapFont.Create(FontFile, 0, 19, 35, -10); - BitmapFont.CorrectWidths(2, 0); - Fonts[0].Font := TScalableFont.Create(BitmapFont, false); - } - - //Fonts[0].Font.Aspect := 0.9; - - // Bold - FontFile := FindFontFile(FontIni, 'Bold'); - Fonts[1].Font := TFTScalableFont.Create(FontFile, 64); - - // Outline1 - FontFile := FindFontFile(FontIni, 'Outline1'); - Fonts[2].Font := TFTScalableOutlineFont.Create(FontFile, 64, 0.06); - //TFTScalableOutlineFont(Fonts[2].Font).SetOutlineColor(0.3, 0.3, 0.3); - - // Outline2 - FontFile := FindFontFile(FontIni, 'Outline2'); - Fonts[3].Font := TFTScalableOutlineFont.Create(FontFile, 64, 0.08); - - except on E: Exception do - Log.LogCritical(E.Message, 'BuildFont'); - end; - - // close ini-file - FontIni.Free; -end; - - -// Deletes the font -procedure KillFont; -begin - // delete all characters - //glDeleteLists(..., 256); -end; - -function glTextWidth(const text: string): real; -var - Bounds: TBoundsDbl; -begin - // FIXME: remove conversion - Bounds := Fonts[ActFont].Font.BBox(RecodeString(Text, encCP1252), true); - Result := Bounds.Right - Bounds.Left; -end; - -// Custom GL "Print" Routine -procedure glPrint(const Text: string); -var - GLFont: PGLFont; -begin - // if there is no text do nothing - if (Text = '') then - Exit; - - GLFont := @Fonts[ActFont]; - - glPushMatrix(); - // set font position - glTranslatef(GLFont.X, GLFont.Y + GLFont.Font.Ascender, GLFont.Z); - // draw string - // FIXME: remove conversion - GLFont.Font.Print(RecodeString(Text, encCP1252)); - glPopMatrix(); -end; - -procedure ResetFont(); -begin - SetFontPos(0, 0); - SetFontZ(0); - SetFontItalic(False); - SetFontReflection(False, 0); -end; - -procedure SetFontPos(X, Y: real); -begin - Fonts[ActFont].X := X; - Fonts[ActFont].Y := Y; -end; - -procedure SetFontZ(Z: real); -begin - Fonts[ActFont].Z := Z; -end; - -procedure SetFontSize(Size: real); -begin - Fonts[ActFont].Font.Height := Size; -end; - -procedure SetFontStyle(Style: integer); -begin - ActFont := Style; -end; - -procedure SetFontItalic(Enable: boolean); -begin - if (Enable) then - Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style + [Italic] - else - Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style - [Italic] -end; - -procedure SetFontReflection(Enable: boolean; Spacing: real); -begin - if (Enable) then - Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style + [Reflect] - else - Fonts[ActFont].Font.Style := Fonts[ActFont].Font.Style - [Reflect]; - Fonts[ActFont].Font.ReflectionSpacing := Spacing - Fonts[ActFont].Font.Descender; -end; - -end. diff --git a/unicode/src/base/UTextEncoding.pas b/unicode/src/base/UTextEncoding.pas index 6eec8eec..ae36a270 100644 --- a/unicode/src/base/UTextEncoding.pas +++ b/unicode/src/base/UTextEncoding.pas @@ -115,7 +115,10 @@ begin if (Src[SrcPos] < #128) then begin // copy ASCII char - Result[DstPos] := Src[SrcPos]; + // Important: the Ord() is necessary to prevent FPC from an automatic + // encoding conversion (using the local codepage). Delphi does not perform + // such a conversion. + Result[DstPos] := WideChar(Ord(Src[SrcPos])); Inc(DstPos); end else diff --git a/unicode/src/switches.inc b/unicode/src/switches.inc index 215fe239..cfd57fd4 100644 --- a/unicode/src/switches.inc +++ b/unicode/src/switches.inc @@ -65,8 +65,6 @@ {$DEFINE CONSOLE} {$IFEND} -{.$DEFINE UseFreetype} - // audio config {$IF Defined(HaveBASS)} {$DEFINE UseBASSPlayback} diff --git a/unicode/src/ultrastardx.dpr b/unicode/src/ultrastardx.dpr index e83a7569..c7e330e0 100644 --- a/unicode/src/ultrastardx.dpr +++ b/unicode/src/ultrastardx.dpr @@ -76,12 +76,7 @@ uses zlib in 'lib\zlib\zlib.pas', png in 'lib\libpng\png.pas', - - {$IFDEF UseFreetype} freetype in 'lib\freetype\freetype.pas', - UFont in 'base\UFont.pas', - UTextEncoding in 'base\UTextEncoding.pas', - {$ENDIF} {$IFDEF UseBass} bass in 'lib\bass\delphi\bass.pas', @@ -137,7 +132,7 @@ uses {$IFDEF DARWIN} PseudoThread in 'macosx\PseudoThread.pas', {$ENDIF} - + SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas', SQLite3 in 'lib\SQLite\SQLite3.pas', @@ -176,7 +171,6 @@ uses UDraw in 'base\UDraw.pas', URecord in 'base\URecord.pas', UTime in 'base\UTime.pas', - TextGL in 'base\TextGL.pas', USong in 'base\USong.pas', UXMLSong in 'base\UXMLSong.pas', USongs in 'base\USongs.pas', @@ -200,6 +194,10 @@ uses USingScores in 'base\USingScores.pas', USingNotes in 'base\USingNotes.pas', + TextGL in 'base\TextGL.pas', + UFont in 'base\UFont.pas', + UTextEncoding in 'base\UTextEncoding.pas', + //------------------------------ //Includes - Plugin Support //------------------------------ -- cgit v1.2.3