static spLetterPointer spFontInsert( spLetterPointer letter, spLetterPointer root ) { if( root == NULL ) { root = letter; letter->binary_height = 0; letter->left = NULL; letter->right = NULL; } else if( letter->character < root->character ) { root->left = spFontInsert( letter, root->left ); if( spLetterGetHeight( root->left ) - spLetterGetHeight( root->right ) == 2 ) if( letter->character < root->left->character ) root = spLetterRotateLeft( root ); else root = spLetterDoubleLeft( root ); } else if( letter->character > root->character ) { root->right = spFontInsert( letter, root->right ); if( spLetterGetHeight( root->right ) - spLetterGetHeight( root->left ) == 2 ) if( letter->character > root->right->character ) root = spLetterRotateRight( root ); else root = spLetterDoubleRight( root ); } root->binary_height = spMax( spLetterGetHeight( root->left ), spLetterGetHeight( root->right ) ) + 1; return root; }
PREFIX void spFontChangeLetter( spFontPointer font, spLetterPointer letter, Uint32 character, Uint16 color ) { letter->color = color; char buffer[5]; buffer[0] = character; buffer[1] = 0; //TODO: utf8 SDL_Color sdlcolor = {( color >> 11 ) << 3, ( ( color << 5 ) >> 10 ) << 2, ( ( color & 31 ) << 3 )}; SDL_Surface* surface = TTF_RenderUTF8_Solid( font->font, buffer, sdlcolor ); int width = surface->w + SP_FONT_EXTRASPACE * 2; if ( width & 1 ) width++; letter->surface = spCreateSurface(width, surface->h + SP_FONT_EXTRASPACE * 2); SDL_FillRect( letter->surface, NULL, SP_ALPHA_COLOR ); SDL_Rect DestR; DestR.x = SP_FONT_EXTRASPACE; DestR.y = SP_FONT_EXTRASPACE; DestR.w = surface->w; DestR.h = surface->h; SDL_BlitSurface( surface, NULL, letter->surface, &DestR ); SDL_FreeSurface( surface ); TTF_SizeUTF8( font->font, buffer, &( letter->width ), &( letter->height ) ); if ( font->maxheight < letter->height ) font->maxheight = letter->height; } PREFIX void spFontAdd( spFontPointer font, Uint32 character, Uint16 color ) { spLetterPointer letter = ( spLetterPointer )malloc( sizeof( spLetterStruct ) ); spFontChangeLetter( font, letter, character, color ); letter->character = character; //tree insert font->root = spFontInsert( letter, font->root ); }
PREFIX void spFontChangeLetter( spFontPointer font, spLetterPointer letter, Uint32 character, Uint16 color ) { letter->color = color; Uint16 buffer[2]; buffer[0] = character; buffer[1] = 0; SDL_Color sdlcolor = {( color >> 11 ) << 3, ( ( color << 5 ) >> 10 ) << 2, ( ( color & 31 ) << 3 )}; SDL_Surface* surface; if (spFontBackgroundColor == SP_FONT_NO_BORDER) surface = TTF_RenderUNICODE_Solid( font->font, buffer, sdlcolor ); else { SDL_Color background = {( spFontBackgroundColor >> 11 ) << 3, ( ( spFontBackgroundColor << 5 ) >> 10 ) << 2, ( ( spFontBackgroundColor & 31 ) << 3 )}; surface = TTF_RenderUNICODE_Shaded( font->font, buffer, sdlcolor ,background ); } if (!surface) surface = spCreateSurface(0,font->maxheight); int width = surface->w + SP_FONT_EXTRASPACE * 2; if ( width & 1 ) width++; letter->surface = spCreateSurface(width, surface->h + SP_FONT_EXTRASPACE * 2); SDL_FillRect( letter->surface, NULL, SP_ALPHA_COLOR ); SDL_Rect DestR; DestR.x = SP_FONT_EXTRASPACE; DestR.y = SP_FONT_EXTRASPACE; DestR.w = surface->w; DestR.h = surface->h; SDL_BlitSurface( surface, NULL, letter->surface, &DestR ); SDL_FreeSurface( surface ); //Setting every spFontBackgroundColor to the alpha color SDL_LockSurface( letter->surface ); Uint16* pixel = ( Uint16* )( letter->surface->pixels ); int scanline = letter->surface->pitch/letter->surface->format->BytesPerPixel; int x, y; for ( x = 0; x < letter->surface->w; x++ ) for ( y = 0; y < letter->surface->h; y++ ) if ( pixel[x + y * scanline] == spFontBackgroundColor ) pixel[x + y * scanline] = SP_ALPHA_COLOR; SDL_UnlockSurface( letter->surface ); TTF_SizeUNICODE( font->font, buffer, &( letter->width ), &( letter->height ) ); if ( font->maxheight < letter->height ) font->maxheight = letter->height; } static void spFontInternalAddOneCharacter( spFontPointer font, Uint32 character, Uint16 color ) { if (spFontGetLetter(font,character)) return; spLetterPointer letter = ( spLetterPointer )malloc( sizeof( spLetter ) ); spFontChangeLetter( font, letter, character, color ); letter->character = character; //tree insert font->root = spFontInsert( letter, font->root ); } PREFIX void spFontAdd( spFontPointer font, char* characters, Uint16 color ) { //parsing the characters string. int pos = 0; while (1) { Uint32 character = spFontGetUnicodeFromUTF8(&(characters[pos])); if (character == 0) break; pos+=spFontLastUTF8Length; spFontInternalAddOneCharacter(font,character,color); } } PREFIX void spFontAddRange( spFontPointer font, char* from, char* to, Uint16 color ) { //getting the characters strings Uint32 c_from = spFontGetUnicodeFromUTF8(from); if (c_from == 0) return; Uint32 c_to = spFontGetUnicodeFromUTF8(to); if (c_to == 0) return; Uint32 character; if (c_from > c_to) { character = c_from; c_from = c_to; c_to = character; } for (character = c_from; character <= c_to; character++) spFontInternalAddOneCharacter(font,character,color); }
PREFIX void spFontChangeButton( spFontPointer font, spLetterPointer letter, Uint32 character, char* caption, Uint16 fgColor, Uint16 bgColor ) { letter->color = fgColor; SDL_Color sdlcolor = {( fgColor >> 11 ) << 3, ( ( fgColor << 5 ) >> 10 ) << 2, ( ( fgColor & 31 ) << 3 )}; int width; if (spFontCorrectStrategy(caption) == SP_FONT_BUTTON) { char buffer[5]; buffer[0] = character; buffer[1] = 0; //TODO: utf8 SDL_Surface* surface = TTF_RenderUTF8_Solid( font->font, caption, sdlcolor ); width = font->maxheight + SP_FONT_EXTRASPACE * 2; if ( width & 1 ) width++; letter->surface = spCreateSurface(width, width); SDL_LockSurface(letter->surface); int x,y; Uint16* pixel = (Uint16*)letter->surface->pixels; int w = letter->surface->pitch/letter->surface->format->BytesPerPixel; for (x = 0; x < letter->surface->w; x++) for (y = 0; y < letter->surface->h; y++) { if ((x-width/2)*(x-width/2)+(y-width/2)*(y-width/2) <= width*width/4) { if ((x-width/2)*(x-width/2)+(y-width/2)*(y-width/2) <= width*width/5) pixel[x+y*w] = bgColor; else pixel[x+y*w] = fgColor; } else pixel[x+y*w] = SP_ALPHA_COLOR; } SDL_UnlockSurface(letter->surface); SDL_Rect DestR; DestR.x = width/2-surface->w/2; DestR.y = font->maxheight/2+SP_FONT_EXTRASPACE-surface->h/2; DestR.w = surface->w; DestR.h = surface->h; SDL_BlitSurface( surface, NULL, letter->surface, &DestR ); SDL_FreeSurface( surface ); } else { int buttonWidth = font->maxheight + SP_FONT_EXTRASPACE * 2; int border = buttonWidth/14; SDL_Surface* surface = TTF_RenderUTF8_Solid( font->font, caption, sdlcolor ); width = surface->w+2*SP_FONT_EXTRASPACE+2*border; if ( width & 1 ) width++; letter->surface = spCreateSurface(width, font->maxheight+SP_FONT_EXTRASPACE*2); SDL_LockSurface(letter->surface); int x,y; Uint16* pixel = (Uint16*)letter->surface->pixels; int w = letter->surface->pitch/letter->surface->format->BytesPerPixel; for (x = 0; x < letter->surface->w; x++) for (y = 0; y < letter->surface->h; y++) { if (x < border || y < border || x >= width-border || y >= letter->surface->h-border) pixel[x+y*w] = fgColor; else pixel[x+y*w] = bgColor; } SDL_UnlockSurface(letter->surface); SDL_Rect DestR; DestR.x = SP_FONT_EXTRASPACE+border; DestR.y = font->maxheight/2+SP_FONT_EXTRASPACE-surface->h/2; DestR.w = surface->w; DestR.h = surface->h; SDL_BlitSurface( surface, NULL, letter->surface, &DestR ); SDL_FreeSurface( surface ); } letter->height = font->maxheight; letter->width = width; } PREFIX void spFontAddButton( spFontPointer font, Uint32 character, char* caption, Uint16 fgColor, Uint16 bgColor ) { spLetterPointer letter = ( spLetterPointer )malloc( sizeof( spLetterStruct ) ); spFontChangeButton( font, letter, character, caption, fgColor, bgColor ); letter->character = character; //tree insert font->buttonRoot = spFontInsert( letter, font->buttonRoot ); }