2018-01-21 10:31:38 +01:00
/*
2019-06-02 17:13:34 +02:00
Copyright ( C ) 2018 - 2019 Parallel Realities
2018-01-21 10:31:38 +01:00
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 ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# include "text.h"
2018-12-22 23:46:38 +01:00
static void initFont ( char * name , char * filename ) ;
static void drawWord ( char * word , int * x , int * y , int startX ) ;
2018-12-23 16:32:33 +01:00
static void drawTextLines ( int x , int y , int size , int align ) ;
static void drawTextLine ( int x , int y , int size , int align , const char * line ) ;
2018-12-22 23:46:38 +01:00
void calcTextDimensions ( const char * text , int size , int * w , int * h ) ;
void useFont ( char * name ) ;
static void initChars ( Font * f ) ;
static char * nextCharacter ( const char * str , int * i ) ;
static Glyph * findGlyph ( char * c ) ;
static char drawTextBuffer [ 1024 ] ;
static Font fontHead ;
static Font * fontTail ;
static Font * activeFont = NULL ;
static float scale ;
2018-01-21 10:31:38 +01:00
void initFonts ( void )
{
2018-12-22 23:46:38 +01:00
memset ( & fontHead , 0 , sizeof ( Font ) ) ;
fontTail = & fontHead ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
initFont ( " roboto " , getFileLocation ( " gfx/fonts/Roboto-Medium.ttf " ) ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
useFont ( " roboto " ) ;
2018-01-21 10:31:38 +01:00
}
2018-12-22 23:46:38 +01:00
static void initFont ( char * name , char * filename )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
SDL_Texture * texture ;
TTF_Font * font ;
Font * f ;
SDL_Surface * surface , * text ;
SDL_Rect dest ;
Glyph * g ;
int i ;
2018-12-23 16:32:33 +01:00
SDL_Color white = { 255 , 255 , 255 , 255 } ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
f = malloc ( sizeof ( Font ) ) ;
memset ( f , 0 , sizeof ( Font ) ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
font = TTF_OpenFont ( filename , FONT_SIZE ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
initChars ( f ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
surface = SDL_CreateRGBSurface ( 0 , FONT_TEXTURE_SIZE , FONT_TEXTURE_SIZE , 32 , 0 , 0 , 0 , 0xff ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
SDL_SetColorKey ( surface , SDL_TRUE , SDL_MapRGBA ( surface - > format , 0 , 0 , 0 , 0 ) ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
dest . x = dest . y = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
for ( i = 0 ; i < NUM_GLYPH_BUCKETS ; i + + )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
for ( g = f - > glyphHead [ i ] . next ; g ! = NULL ; g = g - > next )
{
text = TTF_RenderUTF8_Blended ( font , g - > character , white ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
TTF_SizeText ( font , g - > character , & dest . w , & dest . h ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( dest . x + dest . w > = FONT_TEXTURE_SIZE )
{
dest . x = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
dest . y + = dest . h + 1 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( dest . y + dest . h > = FONT_TEXTURE_SIZE )
{
SDL_LogMessage ( SDL_LOG_CATEGORY_APPLICATION , SDL_LOG_PRIORITY_CRITICAL , " Out of glyph space in %dx%d font atlas texture map. " , FONT_TEXTURE_SIZE , FONT_TEXTURE_SIZE ) ;
exit ( 1 ) ;
}
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
SDL_BlitSurface ( text , NULL , surface , & dest ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
g - > rect = dest ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
SDL_FreeSurface ( text ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
dest . x + = dest . w ;
}
2018-01-21 10:31:38 +01:00
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
TTF_CloseFont ( font ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
texture = toTexture ( surface , 1 ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
f - > texture = texture ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
strcpy ( f - > name , name ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
fontTail - > next = f ;
fontTail = f ;
2018-01-21 10:31:38 +01:00
}
2018-12-22 23:46:38 +01:00
static void initChars ( Font * f )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
char * characters , * character ;
Glyph * g , * glyphTail ;
int i , bucket ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
characters = readFile ( " data/locale/characters.dat " ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
i = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character = nextCharacter ( characters , & i ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
while ( character )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
bucket = hashcode ( character ) % NUM_GLYPH_BUCKETS ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
glyphTail = & f - > glyphHead [ bucket ] ;
2018-01-21 10:31:38 +01:00
2018-12-22 23:46:38 +01:00
/* horrible bit to look for the tail */
while ( glyphTail - > next )
{
glyphTail = glyphTail - > next ;
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
g = malloc ( sizeof ( Glyph ) ) ;
memset ( g , 0 , sizeof ( Glyph ) ) ;
glyphTail - > next = g ;
glyphTail = g ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
STRNCPY ( g - > character , character , MAX_NAME_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character = nextCharacter ( characters , & i ) ;
2018-01-21 10:31:38 +01:00
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
free ( characters ) ;
}
2018-01-21 10:31:38 +01:00
2018-12-22 23:46:38 +01:00
void drawText ( int x , int y , int size , int align , SDL_Color color , const char * format , . . . )
{
va_list args ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( activeFont )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
memset ( & drawTextBuffer , ' \0 ' , sizeof ( drawTextBuffer ) ) ;
2018-01-21 10:31:38 +01:00
2018-12-22 23:46:38 +01:00
va_start ( args , format ) ;
vsprintf ( drawTextBuffer , format , args ) ;
va_end ( args ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( app . textWidth = = 0 )
{
2022-09-19 20:29:41 +02:00
# if !defined(__amigaos4__) && !defined(__morphos__)
2018-12-23 16:32:33 +01:00
SDL_SetTextureColorMod ( activeFont - > texture , 0 , 0 , 0 ) ;
SDL_SetTextureAlphaMod ( activeFont - > texture , 255 ) ;
2019-06-02 17:13:34 +02:00
2018-12-23 16:32:33 +01:00
drawTextLine ( x + 2 , y + 2 , size , align , drawTextBuffer ) ;
drawTextLine ( x + 1 , y + 1 , size , align , drawTextBuffer ) ;
2019-06-02 17:13:34 +02:00
2018-12-23 16:32:33 +01:00
SDL_SetTextureColorMod ( activeFont - > texture , color . r , color . g , color . b ) ;
SDL_SetTextureAlphaMod ( activeFont - > texture , color . a ) ;
2022-09-19 20:29:41 +02:00
# endif
2019-06-02 17:13:34 +02:00
2018-12-23 16:32:33 +01:00
drawTextLine ( x , y , size , align , drawTextBuffer ) ;
2018-12-22 23:46:38 +01:00
}
else
{
2022-09-19 20:29:41 +02:00
# if !defined(__amigaos4__) && !defined(__morphos__)
2018-12-23 16:32:33 +01:00
SDL_SetTextureColorMod ( activeFont - > texture , 0 , 0 , 0 ) ;
SDL_SetTextureAlphaMod ( activeFont - > texture , 255 ) ;
2019-06-02 17:13:34 +02:00
2018-12-23 16:32:33 +01:00
drawTextLines ( x + 2 , y + 2 , size , align ) ;
drawTextLines ( x + 1 , y + 1 , size , align ) ;
2019-06-02 17:13:34 +02:00
2018-12-23 16:32:33 +01:00
SDL_SetTextureColorMod ( activeFont - > texture , color . r , color . g , color . b ) ;
SDL_SetTextureAlphaMod ( activeFont - > texture , color . a ) ;
2022-09-19 20:29:41 +02:00
# endif
2018-12-23 16:32:33 +01:00
drawTextLines ( x , y , size , align ) ;
2018-12-22 23:46:38 +01:00
}
}
2018-01-21 10:31:38 +01:00
}
2018-12-23 16:32:33 +01:00
static void drawTextLines ( int x , int y , int size , int align )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
char line [ MAX_LINE_LENGTH ] , token [ MAX_WORD_LENGTH ] ;
int i , n , w , h , currentWidth , len ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( & line , ' \0 ' , sizeof ( line ) ) ;
memset ( & token , ' \0 ' , sizeof ( token ) ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
len = strlen ( drawTextBuffer ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
n = currentWidth = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
for ( i = 0 ; i < len ; i + + )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
token [ n + + ] = drawTextBuffer [ i ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( drawTextBuffer [ i ] = = ' ' | | i = = len - 1 )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
calcTextDimensions ( token , size , & w , & h ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( currentWidth + w > app . textWidth )
{
2018-12-23 16:32:33 +01:00
drawTextLine ( x , y , size , align , line ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
currentWidth = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
y + = h ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( & line , ' \0 ' , sizeof ( line ) ) ;
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
strcat ( line , token ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
n = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( & token , ' \0 ' , sizeof ( token ) ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
currentWidth + = w ;
2018-01-21 10:31:38 +01:00
}
}
2019-06-02 17:13:34 +02:00
2018-12-23 16:32:33 +01:00
drawTextLine ( x , y , size , align , line ) ;
2018-01-21 10:31:38 +01:00
}
2018-12-23 16:32:33 +01:00
static void drawTextLine ( int x , int y , int size , int align , const char * line )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
int i , startX , n , w , h ;
char word [ MAX_WORD_LENGTH ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
scale = size / ( FONT_SIZE * 1.0f ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
startX = x ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( word , 0 , MAX_WORD_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
n = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
calcTextDimensions ( line , size , & w , & h ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( align = = TA_RIGHT )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
x - = w ;
}
else if ( align = = TA_CENTER )
{
x - = ( w / 2 ) ;
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
for ( i = 0 ; i < strlen ( line ) ; i + + )
{
word [ n + + ] = line [ i ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( line [ i ] = = ' ' )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
drawWord ( word , & x , & y , startX ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( word , 0 , MAX_WORD_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
n = 0 ;
2018-01-21 10:31:38 +01:00
}
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
drawWord ( word , & x , & y , startX ) ;
2018-01-21 10:31:38 +01:00
}
2018-12-22 23:46:38 +01:00
static void drawWord ( char * word , int * x , int * y , int startX )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
int i ;
char * character ;
SDL_Rect dest ;
Glyph * g ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
i = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character = nextCharacter ( word , & i ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
while ( character )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
g = findGlyph ( character ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
dest . x = * x ;
dest . y = * y ;
dest . w = g - > rect . w * scale ;
dest . h = g - > rect . h * scale ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
SDL_RenderCopy ( app . renderer , activeFont - > texture , & g - > rect , & dest ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
* x + = g - > rect . w * scale ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character = nextCharacter ( word , & i ) ;
2018-01-21 10:31:38 +01:00
}
}
2018-12-22 23:46:38 +01:00
static Glyph * findGlyph ( char * c )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
Glyph * g ;
int bucket ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
bucket = hashcode ( c ) % NUM_GLYPH_BUCKETS ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
for ( g = activeFont - > glyphHead [ bucket ] . next ; g ! = NULL ; g = g - > next )
{
if ( strcmp ( g - > character , c ) = = 0 )
{
return g ;
}
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
SDL_LogMessage ( SDL_LOG_CATEGORY_APPLICATION , SDL_LOG_PRIORITY_CRITICAL , " Couldn't find glyph for '%s' " , c ) ;
exit ( 1 ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
return NULL ;
2018-01-21 10:31:38 +01:00
}
2018-12-22 23:46:38 +01:00
void useFont ( char * name )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
Font * f ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
for ( f = fontHead . next ; f ! = NULL ; f = f - > next )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
if ( strcmp ( f - > name , name ) = = 0 )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
activeFont = f ;
return ;
2018-01-21 10:31:38 +01:00
}
}
}
2018-12-22 23:46:38 +01:00
void calcTextDimensions ( const char * text , int size , int * w , int * h )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
float scale ;
2018-01-21 10:31:38 +01:00
int i ;
2018-12-22 23:46:38 +01:00
char * character ;
Glyph * g ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
scale = size / ( FONT_SIZE * 1.0f ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
* w = 0 ;
* h = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
i = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character = nextCharacter ( text , & i ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
while ( character )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
g = findGlyph ( character ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
* w + = g - > rect . w * scale ;
* h = MAX ( g - > rect . h * scale , * h ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character = nextCharacter ( text , & i ) ;
2018-01-21 10:31:38 +01:00
}
}
2018-12-22 23:46:38 +01:00
int getWrappedTextHeight ( char * text , int size )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
char word [ MAX_WORD_LENGTH ] ;
int i , y , n , w , h , currentWidth , len ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
STRNCPY ( drawTextBuffer , text , MAX_LINE_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-01-21 10:31:38 +01:00
n = 0 ;
2018-12-22 23:46:38 +01:00
y = 0 ;
h = 0 ;
currentWidth = 0 ;
len = strlen ( drawTextBuffer ) ;
memset ( word , 0 , MAX_WORD_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
for ( i = 0 ; i < len ; i + + )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
word [ n + + ] = drawTextBuffer [ i ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( drawTextBuffer [ i ] = = ' ' | | i = = len - 1 )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
calcTextDimensions ( word , size , & w , & h ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( currentWidth + w > app . textWidth )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
currentWidth = 0 ;
y + = h ;
2018-01-21 10:31:38 +01:00
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
currentWidth + = w ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( word , 0 , MAX_WORD_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
n = 0 ;
2018-01-21 10:31:38 +01:00
}
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
return y + h ;
2018-01-21 10:31:38 +01:00
}
2018-12-22 23:46:38 +01:00
static char * nextCharacter ( const char * str , int * i )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
static char character [ MAX_NAME_LENGTH ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
unsigned char bit ;
int n ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
memset ( character , ' \0 ' , MAX_NAME_LENGTH ) ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
n = 0 ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
while ( 1 )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
bit = ( unsigned char ) str [ * i ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
if ( ( bit > = ' ' & & bit < = ' ~ ' ) | | bit > = 0xC0 | | bit = = ' \0 ' )
2018-01-21 10:31:38 +01:00
{
2018-12-22 23:46:38 +01:00
if ( n > 0 )
{
return character [ 0 ] ! = ' \0 ' ? character : NULL ;
}
2018-01-21 10:31:38 +01:00
}
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
character [ n + + ] = str [ * i ] ;
2019-06-02 17:13:34 +02:00
2018-12-22 23:46:38 +01:00
* i = * i + 1 ;
2018-01-21 10:31:38 +01:00
}
}
2022-09-19 20:29:41 +02:00