123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- unit sfont;
- {******************************************************************}
- {
- $Id: sfont.pas,v 1.2 2004/03/31 09:04:31 savage Exp $
- }
- { }
- { Borland Delphi SFont }
- { Conversion of the Linux Games- SFont Library for SDL }
- { }
- { Original work created by Karl Bartel <[email protected]> }
- { Copyright (C) 2003 Karl Bartel. }
- { All Rights Reserved. }
- { }
- { The original files are : sfont.c }
- { }
- { The original Pascal code is : SFont.pas }
- { The initial developer of the Pascal code is : }
- { Jason Farmer <[email protected]> }
- { }
- { }
- { Contributor(s) }
- { -------------- }
- { Dominique Louis <[email protected]> }
- { }
- { Obtained through: }
- { Joint Endeavour of Delphi Innovators ( Project JEDI ) }
- { }
- { You may retrieve the latest version of this file at the Project }
- { JEDI home page, located at http://delphi-jedi.org }
- { }
- { The contents of this file are used with permission, subject to }
- { the Mozilla Public License Version 1.1 (the "License"); you may }
- { not use this file except in compliance with the License. You may }
- { obtain a copy of the License at }
- { http://www.mozilla.org/NPL/NPL-1_1Final.html }
- { }
- { Software distributed under the License is distributed on an }
- { "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
- { implied. See the License for the specific language governing }
- { rights and limitations under the License. }
- { }
- { Description }
- { ----------- }
- { }
- { SFONT - SDL Font Library by Karl Bartel <[email protected]> }
- { }
- { All functions are explained below. }
- { There are two versions of each }
- { funtction. The first is the normal one, }
- { the function with the 2 at the end can be used when you }
- { want to handle more than one font }
- { in your program. }
- { }
- { }
- { }
- { }
- { Requires }
- { -------- }
- { SDL runtime libary somewhere in your path }
- { The Latest SDL runtime can be found on http://www.libsdl.org }
- { }
- { Programming Notes }
- { ----------------- }
- { }
- { }
- { }
- { }
- { }
- { Revision History }
- { ---------------- }
- { July 04 2001 - JF : Initial translation. }
- { Sept 29 2001 - JF : Added Róbert Surface Adding and }
- { Subtraction functions }
- { }
- {
- $Log: sfont.pas,v $
- Revision 1.2 2004/03/31 09:04:31 savage
- Added jedi-sdl.inc files for better FreePascal/multi compiler support.
- Revision 1.1 2004/03/28 10:45:16 savage
- Standardised SFont Functions so that they are prefixed with SFont_ and more in line with Karl's v2.02 release. Demos have been updated appropriately.
- }
- {******************************************************************}
- {$I jedi-sdl.inc}
- interface
- uses
- SysUtils,
- sdl,
- sdlutils;
- // Delcare one variable of this type for each font you are using.
- // To load the fonts, load the font image into YourFont->Surface
- // and call InitFont( YourFont );
- type
- TSfont_FontInfo = record
- Surface : PSDL_Surface; //SDL_Surface *Surface;
- CharPos : array[ 0..511 ] of integer; //int CharPos[512];
- MaxPos : integer; //int h;
- end;
- PSFont_FontInfo = ^TSfont_FontInfo;
- // Initializes the font
- // Font: this contains the suface with the font.
- // The font must be loaded before using this function.
- procedure SFont_InitFont( Font : PSDL_Surface );
- procedure SFont_InitFont2( Font : PSFont_FontInfo );
- // Blits a string to a surface
- // Destination: the suface you want to blit to
- // text: a string containing the text you want to blit.
- procedure SFont_Write( Surface_ : PSDL_Surface; x : Integer; y : Integer; text :
- pchar );
- procedure SFont_WriteAdd( Surface_ : PSDL_Surface; x : Integer; y : Integer; text :
- pchar );
- procedure SFont_WriteSub( Surface_ : PSDL_Surface; x : Integer; y : Integer; text :
- pchar );
- procedure SFont_Write2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; x : integer;
- y : integer; text : pchar );
- procedure SFont_WriteAdd2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; x : integer;
- y : integer; text : pchar );
- procedure SFont_WriteSub2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; x : integer;
- y : integer; text : pchar );
- // Returns the width of "text" in pixels
- function SFont_TextWidth( Text : pchar ) : integer;
- function SFont_TextWidth2( Font : PSFont_FontInfo; Text : pchar ) : integer;
- // Blits a string to with centered x position
- procedure SFont_WriteCentered( Surface_ : PSDL_Surface; y : Integer; text : pchar );
- procedure SFont_WriteCentered2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; y :
- integer; text : pchar );
- // Allows the user to enter text
- // Width: What is the maximum width of the text (in pixels)
- // text: This string contains the text which was entered by the user
- procedure SFont_Input( Destination : PSDL_Surface; x : Integer; y : integer; Width :
- integer; text : pchar );
- procedure SFont_Input2( Destination : PSDL_Surface; Font : PSFont_FontInfo; x :
- integer; y : integer; Width : integer; text : pchar );
- // Not part of the original implementation, but We really shouldn't be falling for the C Scanf problem...
- // This version requires a maximum length for the amount of text to input.
- procedure SFont_Input3( Destination : PSDL_Surface; Font : PSFont_FontInfo; x :
- integer; y : integer; Width : integer; text : pchar; MaxChars : Cardinal );
- { We'll use SDL for reporting errors }
- procedure SFont_SetError( fmt : PChar );
- function SFont_GetError : PChar;
- var
- InternalFont : TSFont_FontInfo;
- implementation
- procedure SFont_SetError( fmt : PChar );
- begin
- SDL_SetError( fmt );
- end;
- function SFont_GetError : PChar;
- begin
- result := SDL_GetError;
- end;
- procedure SFont_InitFont2( Font : PSFont_FontInfo );
- var
- X : Integer;
- I : Integer;
- begin
- x := 0;
- i := 0;
- if Font.Surface = nil then
- begin
- //Font_SetError ("The font has not been loaded!");
- //printf("The font has not been loaded!\n");
- //exit(1);
- exit;
- end;
- while x < Font.Surface.w do
- begin
- if SDL_GetPixel( Font.Surface, x, 0 ) = SDL_MapRGB( Font.Surface.format, 255, 0,
- 255 ) then
- begin
- Font.CharPos[ i ] := x;
- inc( i );
- while ( ( x < Font.Surface.w - 1 ) and ( SDL_GetPixel( Font.Surface, x, 0 ) =
- SDL_MapRGB( Font.Surface.format, 255, 0, 255 ) ) ) do
- begin
- inc( x );
- end;
- Font.CharPos[ i ] := x;
- inc( i );
- end;
- inc( x );
- end;
- Font.MaxPos := Font.Surface.h;
- SDL_SetColorKey( Font.Surface, SDL_SRCCOLORKEY, SDL_GetPixel( Font.Surface, 0,
- Font.Surface.h - 1 ) );
- end;
- procedure SFont_InitFont( Font : PSDL_Surface );
- begin
- InternalFont.Surface := Font;
- SFont_InitFont2( @InternalFont );
- end;
- procedure SFont_WriteAdd2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; x : integer;
- y : integer; text : pchar );
- var
- ofs : Integer;
- i : Integer;
- srcrect, dstrect : SDL_Rect;
- begin
- i := 0;
- while text[ i ] <> chr( 0 ) do
- begin
- if text[ i ] = ' ' then
- begin
- x := x + Font.CharPos[ 2 ] - Font.CharPos[ 1 ];
- inc( i );
- end
- else
- begin
- ofs := ( ( integer( text[ i ] ) - 33 ) * 2 ) + 1;
- srcrect.w := ( Font.CharPos[ ofs + 2 ] + Font.CharPos[ ofs + 1 ] ) div 2 -
- ( Font.CharPos[ ofs ] + Font.CharPos[ ofs - 1 ] ) div 2;
- dstrect.w := srcrect.w;
- srcrect.h := Font.Surface.h - 1;
- dstrect.h := srcrect.h;
- srcrect.x := ( Font.CharPos[ ofs ] + Font.CharPos[ ofs - 1 ] ) div 2;
- srcrect.y := 1;
- dstrect.x := x - ( Font.CharPos[ ofs ] - Font.CharPos[ ofs - 1 ] ) div 2;
- dstrect.y := y;
- SDL_AddSurface( Font.Surface, @srcrect, Surface_, @dstrect );
- x := x + Font.CharPos[ ofs + 1 ] - Font.CharPos[ ofs ];
- inc( i );
- end;
- end;
- end;
- procedure SFont_WriteSub2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; x : integer;
- y : integer; text : pchar );
- var
- ofs : Integer;
- i : Integer;
- srcrect, dstrect : SDL_Rect;
- begin
- i := 0;
- while text[ i ] <> chr( 0 ) do
- begin
- if text[ i ] = ' ' then
- begin
- x := x + Font.CharPos[ 2 ] - Font.CharPos[ 1 ];
- inc( i );
- end
- else
- begin
- ofs := ( ( integer( text[ i ] ) - 33 ) * 2 ) + 1;
- srcrect.w := ( Font.CharPos[ ofs + 2 ] + Font.CharPos[ ofs + 1 ] ) div 2 -
- ( Font.CharPos[ ofs ] + Font.CharPos[ ofs - 1 ] ) div 2;
- dstrect.w := srcrect.w;
- srcrect.h := Font.Surface.h - 1;
- dstrect.h := srcrect.h;
- srcrect.x := ( Font.CharPos[ ofs ] + Font.CharPos[ ofs - 1 ] ) div 2;
- srcrect.y := 1;
- dstrect.x := x - ( Font.CharPos[ ofs ] - Font.CharPos[ ofs - 1 ] ) div 2;
- dstrect.y := y;
- SDL_SubSurface( Font.Surface, @srcrect, Surface_, @dstrect );
- x := x + Font.CharPos[ ofs + 1 ] - Font.CharPos[ ofs ];
- inc( i );
- end;
- end;
- end;
- procedure SFont_Write2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; x : integer;
- y : integer; text : pchar );
- var
- ofs : Integer;
- i : Integer;
- srcrect, dstrect : SDL_Rect;
- begin
- i := 0;
- while text[ i ] <> chr( 0 ) do
- begin
- if text[ i ] = ' ' then
- begin
- x := x + Font.CharPos[ 2 ] - Font.CharPos[ 1 ];
- inc( i );
- end
- else
- begin
- ofs := ( ( integer( text[ i ] ) - 33 ) * 2 ) + 1;
- srcrect.w := ( Font.CharPos[ ofs + 2 ] + Font.CharPos[ ofs + 1 ] ) div 2 -
- ( Font.CharPos[ ofs ] + Font.CharPos[ ofs - 1 ] ) div 2;
- dstrect.w := srcrect.w;
- srcrect.h := Font.Surface.h - 1;
- dstrect.h := srcrect.h;
- srcrect.x := ( Font.CharPos[ ofs ] + Font.CharPos[ ofs - 1 ] ) div 2;
- srcrect.y := 1;
- dstrect.x := x - ( Font.CharPos[ ofs ] - Font.CharPos[ ofs - 1 ] ) div 2;
- dstrect.y := y;
- SDL_BlitSurface( Font.Surface, @srcrect, Surface_, @dstrect );
- x := x + Font.CharPos[ ofs + 1 ] - Font.CharPos[ ofs ];
- inc( i );
- end;
- end;
- end;
- procedure SFont_Write( Surface_ : PSDL_Surface; x : Integer; y : Integer; text :
- pchar );
- begin
- SFont_Write2( Surface_, @InternalFont, x, y, text );
- end;
- procedure SFont_WriteAdd( Surface_ : PSDL_Surface; x : Integer; y : Integer; text :
- pchar );
- begin
- SFont_WriteAdd2( Surface_, @InternalFont, x, y, text );
- end;
- procedure SFont_WriteSub( Surface_ : PSDL_Surface; x : Integer; y : Integer; text :
- pchar );
- begin
- SFont_WriteSub2( Surface_, @InternalFont, x, y, text );
- end;
- function SFont_TextWidth2( Font : PSFont_FontInfo; Text : pchar ) : integer;
- var
- x, i, ofs : integer;
- begin
- x := 0;
- i := 0;
- ofs := 0;
- while text[ i ] <> chr( 0 ) do
- begin
- if text[ i ] = ' ' then
- begin
- x := x + Font.CharPos[ 2 ] - Font.CharPos[ 1 ];
- inc( i );
- end
- else
- begin
- ofs := ( integer( text[ i ] ) - 33 ) * 2 + 1;
- x := x + Font.CharPos[ ofs + 1 ] - Font.CharPos[ ofs ];
- inc( i );
- end;
- end;
- result := ( x + Font.CharPos[ ofs + 2 ] - Font.CharPos[ ofs + 1 ] );
- end;
- function SFont_TextWidth( Text : pchar ) : integer;
- begin
- result := SFont_TextWidth2( @InternalFont, Text );
- end;
- procedure SFont_WriteCentered2( Surface_ : PSDL_Surface; Font : PSFont_FontInfo; y :
- integer; text : pchar );
- begin
- SFont_Write2( Surface_, @InternalFont, Surface_.w div 2 - SFont_TextWidth( text ) div 2,
- y, text );
- end;
- procedure SFont_WriteCentered( Surface_ : PSDL_Surface; y : Integer; text : pchar );
- begin
- SFont_WriteCentered2( Surface_, @InternalFont, y, text );
- end;
- procedure SFont_Input3( Destination : PSDL_Surface; Font : PSFont_FontInfo; x :
- integer; y : integer; Width : integer; text : pchar; MaxChars : Cardinal );
- var
- event : TSDL_Event;
- ch, ofs, leftshift : integer;
- Back : PSDL_Surface;
- rect : SDL_Rect;
- begin
- ch := 0; //Just to shut the compiler up
- ofs := ( integer( text[ 0 ] ) - 33 ) * 2 + 1;
- leftshift := ( Font.CharPos[ ofs ] - Font.CharPos[ ofs - 1 ] ) div 2;
- Back := SDL_AllocSurface( Destination.flags,
- Width,
- Font.MaxPos,
- Destination.format.BitsPerPixel,
- Destination.format.Rmask,
- Destination.format.Gmask,
- Destination.format.Bmask, 0 );
- rect.x := x - leftshift;
- rect.y := y;
- rect.w := Width;
- rect.h := Font.Surface.h;
- SDL_BlitSurface( Destination, @rect, Back, nil );
- SFont_Write2( Destination, Font, x, y, text );
- SDL_UpdateRect( Destination, x - leftshift, y, Width, Font.MaxPos );
- // start input
- SDL_EnableUNICODE( 1 );
- while ( ( ch <> SDLK_RETURN ) and ( SDL_WaitEvent( @event ) > 0 ) ) do
- begin
- if event.type_ = SDL_KEYDOWN then
- begin
- ch := event.key.keysym.unicode;
- if ( ch = SDLK_BACKSPACE ) and ( strlen( text ) > 0 ) then
- begin
- text[ strlen( text ) - 1 ] := chr( 0 );
- end
- else
- begin
- if strlen( text ) < MaxChars then
- begin
- if ch <> SDLK_BACKSPACE then
- begin
- text[ strlen( text ) ] := chr( ch );
- text[ strlen( text ) ] := chr( 0 );
- end;
- if ( SFont_TextWidth2( Font, text ) > Width ) then
- text[ strlen( text ) ] := chr( 0 );
- end;
- end;
- SDL_BlitSurface( Back, nil, Destination, @rect );
- SFont_Write2( Destination, Font, x, y, text );
- SDL_UpdateRect( Destination, x - ( Font.CharPos[ ofs ] - Font.CharPos[ ofs - 1 ] )
- div 2, y, Width, Font.Surface.h );
- end;
- end;
- text[ strlen( text ) ] := chr( 0 );
- SDL_FreeSurface( Back );
- end;
- procedure SFont_Input2( Destination : PSDL_Surface; Font : PSFont_FontInfo; x :
- integer; y : integer; Width : integer; text : pchar );
- var
- MaxChars : Cardinal;
- begin
- MaxChars := length( text ); // Just to make sure that we don't spill into
- // memory that doesn't belong to us.
- // We can't test the array as we use it
- // Because we're putting the 0 at the current
- // position.
- SFont_Input3( Destination, Font, x, y, Width, Text, MaxChars );
- end;
- procedure SFont_Input( Destination : PSDL_Surface; x : Integer; y : integer; Width :
- integer; text : pchar );
- begin
- SFont_Input2( Destination, @InternalFont, x, y, Width, text );
- end;
- end.
|