BeanCountersClassic/src/draw-text.c

151 lines
4.2 KiB
C

/*
* draw-text.c
* This file is part of Find Four
*
* Copyright (C) 2015 - Félix Arreola Rodríguez
*
* Find Four 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.
*
* Find Four 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 Find Four. If not, see <http://www.gnu.org/licenses/>.
*/
#include <SDL.h>
#include <SDL_ttf.h>
#include "gfx_blit_func.h"
#include "draw-text.h"
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define RMASK 0xff000000
#define GMASK 0x00ff0000
#define BMASK 0x0000ff00
#define AMASK 0x000000ff
#else
#define RMASK 0x000000ff
#define GMASK 0x0000ff00
#define BMASK 0x00ff0000
#define AMASK 0xff000000
#endif
static char *l_strsep(char **from, const char *delim) {
char *s, *dp, *ret;
if ((s = *from) == NULL)
return NULL;
ret = s;
while (*s != '\0') {
/* loop until the end of s, checking against each delimiting character,
* if we find a delimiter set **s to '\0' and return our previous token
* to the user. */
dp = (char *)delim;
while (*dp != '\0') {
if (*s == *dp) {
*s = '\0';
*from = s + 1;
return ret;
}
dp++;
}
s++;
}
/* end of string case */
*from = NULL;
return ret;
}
SDL_Surface *draw_text (TTF_Font *font, const char *cadena, SDL_Color *color) {
SDL_Surface *final, **text;
SDL_Rect dest_rect;
int n_tokens;
int g, len, maxw;
char *dup, *str_token, *original;
/* Si contiene saltos de linea, llamar a la otra función */
if (strchr (cadena, '\n') != NULL) {
len = strlen (cadena);
for (g = 0, n_tokens = 1; g < len; g++) {
if (cadena[g] == '\n') n_tokens++;
}
len = TTF_FontLineSkip (font) * n_tokens;
text = (SDL_Surface **) malloc (sizeof (SDL_Surface *) * n_tokens);
original = dup = strdup (cadena);
str_token = l_strsep (&dup, "\n");
g = 0; maxw = 0;
while (str_token != NULL) {
if (str_token[0] != '\0') {
text[g] = TTF_RenderUTF8_Blended (font, str_token, *color);
if (text[g]->w > maxw) maxw = text[g]->w;
} else {
text[g] = NULL;
}
g++;
str_token = l_strsep (&dup, "\n");
};
final = SDL_CreateRGBSurface (SDL_SWSURFACE, maxw, len, 32, RMASK, GMASK, BMASK, AMASK);
SDL_FillRect (final, NULL, SDL_MapRGBA (final->format, 0, 0, 0, 0));
/*SDL_SetAlpha(final, 0, SDL_ALPHA_OPAQUE);*/
len = TTF_FontLineSkip (font);
for (g = 0; g < n_tokens; g++) {
if (text[g] == NULL) continue;
SDL_SetAlpha (text[g], 0, SDL_ALPHA_OPAQUE);
dest_rect.x = (maxw - text[g]->w) / 2;
dest_rect.y = len * g;
dest_rect.w = text[g]->w;
dest_rect.h = text[g]->h;
/*fprintf (stdout, "UMASK, R: %i, G: %i, B: %i, A: %i\n", text->format->Rmask, text->format->Gmask, text->format->Bmask, text->format->Amask);*/
SDL_BlitSurface (text[g], NULL, final, &dest_rect);
SDL_FreeSurface (text[g]);
}
SDL_SetAlpha(final, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
free (text);
free (original);
return final;
} else {
/* En caso contrario, renderizarla nosotros mismos */
return TTF_RenderUTF8_Blended (font, cadena, *color);
}
}
SDL_Surface *draw_text_with_shadow (TTF_Font *font, int outline, const char *text, SDL_Color foreground, SDL_Color background) {
SDL_Surface *black_letters, *white_letters;
SDL_Rect rect;
/* Algunas validaciones */
if (!font) {
return NULL;
}
if (!text || text[0] == '\0') {
/* Texto vacio */
return NULL;
}
TTF_SetFontOutline (font, outline);
black_letters = draw_text (font, text, &background);
TTF_SetFontOutline (font, 0);
white_letters = draw_text (font, text, &foreground);
rect.w = white_letters->w; rect.h = white_letters->h;
rect.x = rect.y = outline;
SDL_gfxBlitRGBA (white_letters, NULL, black_letters, &rect);
SDL_FreeSurface (white_letters);
return black_letters;
}