123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- unit sdltruetypefont;
- {
- $Id: sdltruetypefont.pas,v 1.1 2004/09/30 22:39:50 savage Exp $
- }
- {******************************************************************************}
- { }
- { JEDI-SDL : Pascal units for SDL - Simple DirectMedia Layer }
- { Wrapper class for SDL_ttf }
- { }
- { The initial developer of this Pascal code was : }
- { Dominqiue Louis <[email protected]> }
- { }
- { Portions created by Dominqiue Louis are }
- { Copyright (C) 2000 - 2001 Dominqiue Louis. }
- { }
- { }
- { Contributor(s) }
- { -------------- }
- { }
- { }
- { 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/MPL/MPL-1.1.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 }
- { ----------- }
- { }
- { }
- { }
- { }
- { }
- { }
- { }
- { Requires }
- { -------- }
- { The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL.so }
- { They are available from... }
- { http://www.libsdl.org . }
- { }
- { Programming Notes }
- { ----------------- }
- { }
- { }
- { }
- { }
- { Revision History }
- { ---------------- }
- { September 23 2004 - DL : Initial Creation }
- {
- $Log: sdltruetypefont.pas,v $
- Revision 1.1 2004/09/30 22:39:50 savage
- Added a true type font class which contains a wrap text function.
- Changed the sdl_ttf.pas header to reflect the future of jedi-sdl.
- }
- {******************************************************************************}
- interface
- uses
- sdl,
- sdl_ttf;
- type
- TRenderType = ( rtLatin1, rtUTF8, rtUnicode );
- TSDLFontStyle = ( fsBold, fsItalic, fsUnderline, fsStrikeOut );
- TSDLFontStyles = set of TSDLFontStyle;
- TTrueTypeFont = class( TObject )
- private
- FFont : PTTF_Font;
- FSolid : Boolean;
- FBackGroundColour : TSDL_Color;
- FForeGroundColour : TSDL_Color;
- FRenderType : TRenderType;
- FStyle : TSDLFontStyles;
- FFontFile : string;
- FFontSize : integer;
- procedure PrepareFont;
- protected
- public
- constructor Create( aFontFile : string; aRenderStyle : TSDLFontStyles = [ ]; aFontSize : integer = 14 );
- destructor Destroy; override;
- function DrawText( aText : WideString ) : PSDL_Surface; overload;
- function DrawText( aText : WideString; aWidth, aHeight : Integer ) : PSDL_Surface; overload;
- property BackGroundColour : TSDL_Color read FBackGroundColour write FBackGroundColour;
- property ForeGroundColour : TSDL_Color read FForeGroundColour write FForeGroundColour;
- property FontFile : string read FFontFile write FFontFile;
- property RenderType : TRenderType read FRenderType write FRenderType;
- property Solid : Boolean read FSolid write FSolid;
- property Style : TSDLFontStyles read FStyle write FStyle;
- property FontSize : integer read FFontSize write FFontSize;
- end;
- implementation
- uses
- SysUtils;
- { TTrueTypeFont }
- constructor TTrueTypeFont.Create( aFontFile : string; aRenderStyle : TSDLFontStyles; aFontSize : integer );
- begin
- inherited Create;
- if FileExists( aFontFile ) then
- begin
- FStyle := aRenderStyle;
- FFontSize := aFontSize;
- FSolid := false;
- FBackGroundColour.r := 255;
- FBackGroundColour.g := 255;
- FBackGroundColour.b := 255;
- FForeGroundColour.r := 0;
- FForeGroundColour.g := 0;
- FForeGroundColour.b := 0;
- FRenderType := rtUTF8;
- if ( TTF_Init >= 0 ) then
- begin
- FFontFile := aFontFile;
- end
- else
- raise Exception.Create( 'Failed to Initialiase SDL_TTF' );
- end
- else
- raise Exception.Create( 'Font File does not exist' );
- end;
- destructor TTrueTypeFont.Destroy;
- begin
- if FFont <> nil then
- TTF_CloseFont( FFont );
- TTF_Quit;
- inherited;
- end;
- function TTrueTypeFont.DrawText( aText : WideString ) : PSDL_Surface;
- begin
- PrepareFont;
- result := nil;
- case FRenderType of
- rtLatin1 :
- begin
- if ( FSolid ) then
- begin
- result := TTF_RenderText_Solid( FFont, PChar( string( aText ) ), FForeGroundColour );
- end
- else
- begin
- result := TTF_RenderText_Shaded( FFont, PChar( string( aText ) ), FForeGroundColour, FBackGroundColour );
- end;
- end;
- rtUTF8 :
- begin
- if ( FSolid ) then
- begin
- result := TTF_RenderUTF8_Solid( FFont, PChar( string( aText ) ), FForeGroundColour );
- end
- else
- begin
- result := TTF_RenderUTF8_Shaded( FFont, PChar( string( aText ) ), FForeGroundColour, FBackGroundColour );
- end;
- end;
- rtUnicode :
- begin
- if ( FSolid ) then
- begin
- result := TTF_RenderUNICODE_Solid( FFont, PUInt16( aText ), FForeGroundColour );
- end
- else
- begin
- result := TTF_RenderUNICODE_Shaded( FFont, PUInt16( aText ), FForeGroundColour, FBackGroundColour );
- end;
- end;
- end;
- end;
- function TTrueTypeFont.DrawText( aText : WideString; aWidth, aHeight : Integer ) : PSDL_Surface;
- var
- textw, texth, i, yPos : integer;
- strChopped : WideString;
- SurfaceList : array of PSDL_Surface;
- strlist : array of WideString;
- ReturnedSurface : PSDL_Surface;
- BltRect : TSDL_Rect;
- begin
- PrepareFont;
- // Do an initial check to see if it already fits
- case FRenderType of
- rtLatin1 :
- begin
- if TTF_SizeText( FFont, PChar( string( aText ) ), textw, texth ) = 0 then
- begin
- if ( textw < aWidth )
- and ( texth < aHeight ) then
- begin
- result := DrawText( aText );
- exit;
- end
- end;
- end;
- rtUTF8 :
- begin
- if TTF_SizeUTF8( FFont, PChar( string( aText ) ), textw, texth ) = 0 then
- begin
- if ( textw < aWidth )
- and ( texth < aHeight ) then
- begin
- result := DrawText( aText );
- exit;
- end
- end;
- end;
- rtUnicode :
- begin
- if TTF_SizeUNICODE( FFont, PUInt16( aText ), textw, texth ) = 0 then
- begin
- if ( textw < aWidth )
- and ( texth < aHeight ) then
- begin
- result := DrawText( aText );
- exit;
- end
- end;
- end;
- end;
- // Create the Surface we will be returning
- ReturnedSurface := SDL_DisplayFormat( SDL_CreateRGBSurface( SDL_SRCCOLORKEY or SDL_RLEACCEL or SDL_HWACCEL, aWidth, aHeight, 16, 0, 0, 0, 0 ) );
- // If we are still here there is some serious parsing to do
- case FRenderType of
- rtLatin1 :
- begin
- strChopped := aText;
- i := Length( strChopped );
- while ( i <> 0 ) do
- begin
- if ( string( strChopped[ i ] ) <> ' ' ) and ( Integer( string( strChopped[ i ] ) ) <> 13 ) then
- dec( i )
- else
- begin
- dec( i );
- strChopped := Copy( strChopped, 0, i );
- if TTF_SizeText( FFont, PChar( string( strChopped ) ), textw, texth ) = 0 then
- begin
- if ( textw < aWidth )
- and ( texth < aHeight ) then
- begin
- SetLength( strlist, Length( strlist ) + 1 );
- strlist[ Length( strlist ) - 1 ] := strChopped;
- strChopped := Copy( aText, i + 2, Length( aText ) - ( i - 1 ) );
- i := Length( strChopped );
- if TTF_SizeText( FFont, PChar( string( strChopped ) ), textw, texth ) = 0 then
- begin
- SetLength( strlist, Length( strlist ) + 1 );
- strlist[ Length( strlist ) - 1 ] := strChopped;
- break;
- end;
- end;
- end;
- end;
- end;
- SetLength( SurfaceList, Length( strlist ) );
- for i := Low( strlist ) to High( strlist ) do
- begin
- if ( FSolid ) then
- begin
- SurfaceList[ i ] := TTF_RenderText_Solid( FFont, PChar( string( strlist[ i ] ) ), FForeGroundColour );
- end
- else
- begin
- SurfaceList[ i ] := TTF_RenderText_Shaded( FFont, PChar( string( strlist[ i ] ) ), FForeGroundColour, FBackGroundColour );
- end;
- end;
- end;
- rtUTF8 :
- begin
- strChopped := aText;
- i := Length( strChopped );
- while ( i <> 0 ) do
- begin
- if ( string( strChopped[ i ] ) <> ' ' ) and ( Integer( string( strChopped[ i ] ) ) <> 13 ) then
- dec( i )
- else
- begin
- dec( i );
- strChopped := Copy( strChopped, 0, i );
- if TTF_SizeUTF8( FFont, PChar( string( strChopped ) ), textw, texth ) = 0 then
- begin
- if ( textw < aWidth )
- and ( texth < aHeight ) then
- begin
- SetLength( strlist, Length( strlist ) + 1 );
- strlist[ Length( strlist ) - 1 ] := strChopped;
- strChopped := Copy( aText, i + 2, Length( aText ) - ( i - 1 ) );
- i := Length( strChopped );
- if TTF_SizeUTF8( FFont, PChar( string( strChopped ) ), textw, texth ) = 0 then
- begin
- SetLength( strlist, Length( strlist ) + 1 );
- strlist[ Length( strlist ) - 1 ] := strChopped;
- break;
- end;
- end;
- end;
- end;
- end;
- SetLength( SurfaceList, Length( strlist ) );
- for i := Low( strlist ) to High( strlist ) do
- begin
- if ( FSolid ) then
- begin
- SurfaceList[ i ] := TTF_RenderUTF8_Solid( FFont, PChar( string( strlist[ i ] ) ), FForeGroundColour );
- end
- else
- begin
- SurfaceList[ i ] := TTF_RenderUTF8_Shaded( FFont, PChar( string( strlist[ i ] ) ), FForeGroundColour, FBackGroundColour );
- end;
- end;
- end;
- rtUnicode :
- begin
- strChopped := aText;
- i := Length( strChopped );
- while ( i <> 0 ) do
- begin
- if ( string( strChopped[ i ] ) <> ' ' ) and ( Integer( string( strChopped[ i ] ) ) <> 13 ) then
- dec( i )
- else
- begin
- dec( i );
- strChopped := Copy( strChopped, 0, i );
- if TTF_SizeUNICODE( FFont, PUInt16( strChopped ), textw, texth ) = 0 then
- begin
- if ( textw < aWidth )
- and ( texth < aHeight ) then
- begin
- SetLength( strlist, Length( strlist ) + 1 );
- strlist[ Length( strlist ) - 1 ] := strChopped;
- strChopped := Copy( aText, i + 2, Length( aText ) - ( i - 1 ) );
- i := Length( strChopped );
- if TTF_SizeUNICODE( FFont, PUInt16( strChopped ), textw, texth ) = 0 then
- begin
- SetLength( strlist, Length( strlist ) + 1 );
- strlist[ Length( strlist ) - 1 ] := strChopped;
- break;
- end;
- end;
- end;
- end;
- end;
- SetLength( SurfaceList, Length( strlist ) );
- for i := Low( strlist ) to High( strlist ) do
- begin
- if ( FSolid ) then
- begin
- SurfaceList[ i ] := TTF_RenderUNICODE_Solid( FFont, PUInt16( strlist[ i ] ), FForeGroundColour );
- end
- else
- begin
- SurfaceList[ i ] := TTF_RenderUNICODE_Shaded( FFont, PUInt16( strlist[ i ] ), FForeGroundColour, FBackGroundColour );
- end;
- end;
- end;
- end;
- // Now Draw the SurfaceList onto the resulting Surface
- yPos := 6;
- for i := Low( SurfaceList ) to High( SurfaceList ) do
- begin
- BltRect.x := 6;
- BltRect.y := yPos;
- BltRect.w := SurfaceList[ i ].w;
- BltRect.h := SurfaceList[ i ].h;
- SDL_BlitSurface( SurfaceList[ i ], nil, ReturnedSurface, @BltRect );
- yPos := yPos + TTF_FontHeight( FFont );
- end;
- result := ReturnedSurface;
- for i := Low( SurfaceList ) to High( SurfaceList ) do
- begin
- SDL_FreeSurface( SurfaceList[ i ] );
- end;
- SetLength( SurfaceList, 0 );
- SetLength( strlist, 0 );
- end;
- procedure TTrueTypeFont.PrepareFont;
- var
- renderstyle : integer;
- begin
- if FFont <> nil then
- TTF_CloseFont( FFont );
- FFont := TTF_OpenFont( PChar( FFontFile ), FFontSize );
- renderstyle := TTF_STYLE_NORMAL;
- if ( fsBold in FStyle ) then
- renderstyle := renderstyle or TTF_STYLE_BOLD;
- if ( fsItalic in FStyle ) then
- renderstyle := renderstyle or TTF_STYLE_ITALIC;
- if ( fsUnderline in FStyle ) then
- renderstyle := renderstyle or TTF_STYLE_UNDERLINE;
- TTF_SetFontStyle( FFont, renderstyle );
- end;
- end.
|