program showfont; { showfont: An example of using the SDL_ttf library with 2D graphics. Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@libsdl.org } { $Id: showfont.dpr,v 1.3 2007/06/01 08:39:06 savage Exp $ } { A simple program to test the text rendering feature of the TTF library } uses SysUtils, sdl, sdl_ttf; const DEFAULT_PTSIZE = 18; DEFAULT_TEXT = 'The quick Pascal compiler jumped over the lazy C compiler'; NUM_COLORS = 256; Usage = 'Usage: %s .ttf [-solid] [-utf8 or -unicode] [-b] [-i] [-u] [-fgcol r g b] [-bgcol r g b] [-ptsize nn] [-text "message"]'; SCREEN_WIDTH = 640; SCREEN_HEIGHT = 480; SCREEN_BPP = 8; type TRenderType = ( rtLatin1, rtUTF8, rtUnicode ); procedure ShutDownApplication( HaltStatus : integer ); begin TTF_Quit; SDL_Quit; Halt( HaltStatus ); end; var screen : PSDL_Surface = nil; font : PTTF_Font; text : PSDL_Surface = nil; temp : PSDL_Surface = nil; ptsize : integer = 0; i : integer; done : Boolean = false; rdiff, gdiff, bdiff : integer; colors : array[ 0..NUM_COLORS - 1 ] of TSDL_Color; white : TSDL_Color = ( r : $FF; g : $FF; b : $FF; unused : 0 ); black : TSDL_Color = ( r : $00; g : $00; b : $00; unused : 0 ); forecol : TSDL_Color; backcol : TSDL_Color; dstrect : TSDL_Rect; event : TSDL_Event; rendersolid : Boolean = false; renderstyle : integer = TTF_STYLE_NORMAL; rendertype : TRenderType = rtLatin1; dump : Boolean; message : WideString; glyph : PSDL_Surface = nil; r, g, b : integer; outname : string; begin { Look for special execution mode } {dump := false; { Look for special rendering types } {rendersolid := false; renderstyle := TTF_STYLE_NORMAL; rendertype := rtLatin1;} { Default is black and white } forecol := black; backcol := white; for i := 1 to ParamCount do begin if ( ParamStr( i ) = '-solid' ) then begin rendersolid := true; end else if ( ParamStr( i ) = '-utf8' ) then begin rendertype := rtUTF8; end else if ( ParamStr( i ) = '-unicode' ) then begin rendertype := rtUnicode; end else if ( ParamStr( i ) = '-b' ) then begin renderstyle := renderstyle or TTF_STYLE_BOLD; end else if ( ParamStr( i ) = '-i' ) then begin renderstyle := renderstyle or TTF_STYLE_ITALIC; end else if ( ParamStr( i ) = '-u' ) then begin renderstyle := renderstyle or TTF_STYLE_UNDERLINE; end else if ( ParamStr( i ) = '-dump' ) then begin dump := true; end else if ( ParamStr( i ) = '-fgcol' ) then begin try r := StrToInt( ParamStr( i + 1 ) ); g := StrToInt( ParamStr( i + 2 ) ); b := StrToInt( ParamStr( i + 3 ) ); except ShutDownApplication( 1 ) end; forecol.r := r; forecol.g := g; forecol.b := b; end else if ( ParamStr( i ) = '-bgcol' ) then begin try r := StrToInt( ParamStr( i + 1 ) ); g := StrToInt( ParamStr( i + 2 ) ); b := StrToInt( ParamStr( i + 3 ) ); except ShutDownApplication( 1 ) end; forecol.r := r; forecol.g := g; forecol.b := b; end else if ( ParamStr( i ) = '-ptsize' ) then begin ptsize := StrToInt( ParamStr( i + 1 ) ); end else if ( ParamStr( i ) = '-text' ) then begin message := WideString( ParamStr( i + 1 ) ); end else begin //fprintf(stderr, Usage, argv0); end; end; { Check usage } { if ( ! argv[0] ) then begin fprintf(stderr, Usage, argv0); return(1); end; } { Initialize SDL } if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) then begin //fprintf(stderr, 'Couldn''t initialize SDL: %s',SDL_GetError); ShutDownApplication( 2 ) end; //atexit(SDL_Quit); { Initialize the TTF library } if ( TTF_Init( ) < 0 ) then begin //fprintf(stderr, 'Couldn''t initialize TTF: %s',SDL_GetError); ShutDownApplication( 2 ) end; //atexit(TTF_Quit); { Open the font file with the requested point size } if ( ptsize = 0 ) then begin i := 2; ptsize := DEFAULT_PTSIZE; end else begin i := 3; end; font := TTF_OpenFont( PChar( ParamStr( 1 ) ), ptsize ); if ( font = nil ) then begin //fprintf(stderr, 'Couldn''t load %d pt font from %s: %s',[ptsize, ParamStr(0), SDL_GetError]); ShutDownApplication( 2 ) end; TTF_SetFontStyle( font, renderstyle ); if ( dump ) then begin for i := 48 to 123 do begin glyph := TTF_RenderGlyph_Shaded( font, i, forecol, backcol ); if ( glyph <> nil ) then begin //sprintf( outname, 'glyph-%d.bmp', i ); outname := 'glyph-' + IntToStr( i ) + '.bmp'; SDL_SaveBMP( glyph, PChar( outname ) ); end; end; ShutDownApplication( 0 ); exit; end; { Set a 640x480x8 video mode } screen := SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE ); if ( screen = nil ) then begin //fprintf(stderr, 'Couldn't set 640x480x8 video mode: %s',[SDL_GetError]); ShutDownApplication( 2 ); end; // Set the window manager title bar SDL_WM_SetCaption( 'JEDI-SDL 2D TTF Demo', 'showfont' ); { Set a palette that is good for the foreground colored text } rdiff := backcol.r - forecol.r; gdiff := backcol.g - forecol.g; bdiff := backcol.b - forecol.b; for i := 0 to NUM_COLORS - 1 do begin colors[ i ].r := forecol.r + ( i * rdiff ) div 4; colors[ i ].g := forecol.g + ( i * gdiff ) div 4; colors[ i ].b := forecol.b + ( i * bdiff ) div 4; end; SDL_SetColors( screen, @colors, 0, NUM_COLORS ); { Clear the background to background color } SDL_FillRect( screen, nil, SDL_MapRGB( screen.format, backcol.r, backcol.g, backcol.b ) ); SDL_UpdateRect( screen, 0, 0, 0, 0 ); { Show which font file we're looking at } //sprintf(string, 'Font file: %s', argv[0]); { Render and center the message } if message = '' then begin message := DEFAULT_TEXT; end; case rendertype of rtLatin1 : begin if ( rendersolid ) then begin text := TTF_RenderText_Solid( font, PChar( string(message) ), forecol ); end else begin text := TTF_RenderText_Shaded( font, PChar( string( message ) ), forecol, backcol ); end; end; rtUTF8 : begin if ( rendersolid ) then begin text := TTF_RenderUTF8_Solid( font, PChar( string( message ) ), forecol ); end else begin text := TTF_RenderUTF8_Shaded( font, PChar( string( message ) ), forecol, backcol ); end; end; rtUnicode : begin { This doesn't actually work because you can't pass UNICODE text in via command line, AFAIK, but...} {Uint16 unicode_text[BUFSIZ]; int index;} {for index := 0 to Length(message) - 1 do begin unicode_text[index] := ((Uint8 *)message)[0]; unicode_text[index] := unicode_text[index] shl 8; unicode_text[index] := unicode_text[index] or ((Uint8 *)message)[1]; message := message + 2; end; } if ( rendersolid ) then begin text := TTF_RenderUNICODE_Solid(font, PUInt16( message ), forecol); end else begin text := TTF_RenderUNICODE_Shaded( font, PUInt16( message ), forecol, backcol); end; end; else begin text := nil; { This shouldn't happen } end; end; if ( text = nil ) then begin //fprintf(stderr, 'Couldn''t render text: %s', [SDL_GetError]); TTF_CloseFont( font ); ShutDownApplication( 2 ); end; dstrect.x := ( screen.w - text.w ) div 2; dstrect.y := ( screen.h - text.h ) div 2; dstrect.w := text.w; dstrect.h := text.h; //printf('Font is generally %d big, and string is %hd big', TTF_FontHeight(font), text.h); { Blit the text surface } if ( SDL_BlitSurface( text, nil, screen, @dstrect ) < 0 ) then begin //fprintf(stderr, 'Couldn't blit text to display: %s', [SDL_GetError]); TTF_CloseFont( font ); ShutDownApplication( 2 ); end; SDL_UpdateRect( screen, 0, 0, 0, 0 ); { Set the text colorkey and convert to display format } if ( SDL_SetColorKey( text, SDL_SRCCOLORKEY or SDL_RLEACCEL, 0 ) < 0 ) then begin //fprintf(stderr, 'Warning: Couldn't set text colorkey: %s', [SDL_GetError]); end; temp := SDL_DisplayFormat( text ); if ( temp <> nil ) then begin SDL_FreeSurface( text ); text := temp; { Wait for a keystroke, and blit text on mouse press } done := false; while ( not done ) do begin while ( SDL_PollEvent( @event ) <> 0 ) do begin case ( event.type_ ) of SDL_MOUSEBUTTONDOWN : begin dstrect.x := event.button.x - text.w div 2; dstrect.y := event.button.y - text.h div 2; dstrect.w := text.w; dstrect.h := text.h; if ( SDL_BlitSurface( text, nil, screen, @dstrect ) = 0 ) then begin SDL_UpdateRects( screen, 1, @dstrect ); end else begin //fprintf(stderr, 'Couldn''t blit text to display: %s', [SDL_GetError]); end; end; SDL_KEYDOWN, SDL_QUITEV : begin done := true; end; end; end; end; end; SDL_FreeSurface( text ); TTF_CloseFont( font ); ShutDownApplication( 0 ); end.