Пример #1
0
Texture TextGenerator::Generate(const std::string &data, int size, float width) {
	Texture texture;
	TTF_Font *font = Font(size);
	if (font) {
		TTF_SetFontOutline(font, 0);
		int w = width == 0 ? INT_MAX : g_Graphics()->to_pixels(width);
		SDL_Surface *surface =
		    TTF_RenderUTF8_Blended_Wrapped(font, data.c_str(), SDL_Color{255, 255, 255, 255}, w); // TODO: fix shadow wrapping
		TTF_SetFontOutline(font, outline);
		SDL_Surface *shadowSurface =
		    TTF_RenderUTF8_Blended_Wrapped(font, data.c_str(), SDL_Color{96, 96, 96, 255}, w);
		if (surface && shadowSurface) {
			SDL_Rect dest;
			dest.x = outline;
			dest.y = outline;
			dest.w = surface->w;
			dest.h = surface->h;
			SDL_BlitSurface(surface, 0, shadowSurface, &dest);
			texture = Texture(shadowSurface);
		}
		if (surface)
			SDL_FreeSurface(surface);
		if (shadowSurface)
			SDL_FreeSurface(shadowSurface);
	}
	return texture;
}
Пример #2
0
FontHelper::FontHelper(const string &font, int size, RGBAColor textColor, RGBAColor outlineColor) {
	this->textColor = textColor;
	this->outlineColor = outlineColor;

	if (!TTF_WasInit()) {
		DEBUG("Initializing font");
		if (TTF_Init() == -1) {
			ERROR("TTF_Init: %s", TTF_GetError());
			exit(2);
		}
	}
	this->font = TTF_OpenFont(font.c_str(), size);
	if (!this->font) {
		ERROR("TTF_OpenFont %s: %s", font.c_str(), TTF_GetError());
		exit(2);
	}
	fontOutline = TTF_OpenFont(font.c_str(), size);
	if (!fontOutline) {
		ERROR("TTF_OpenFont %s: %s", font.c_str(), TTF_GetError());
		exit(2);
	}
	TTF_SetFontHinting(this->font, TTF_HINTING_NORMAL);
	TTF_SetFontHinting(fontOutline, TTF_HINTING_NORMAL);
	TTF_SetFontOutline(fontOutline, 1);
	height = 0;
	// Get maximum line height with a sample text
	TTF_SizeUTF8(fontOutline, "AZ|¹0987654321", NULL, &height);
	halfHeight = height/2;
}
Пример #3
0
//Sets the outline around the font
//param:fontIndex->The index of the font to modify
//param:outlineSize->The size to set the outline
void SpriteFont::SetFontOutline(int fontIndex, int outlineSize)
{
	//Try block to make sure index is valid
	try
	{
		//Get the font to modify
		TTF_Font* font = fontList.at(fontIndex);

		if(font)
		{
			//Get the current style
			int currentOutline = TTF_GetFontOutline(font);

			//Save processing by not changing style if they are identical
			if(currentOutline != outlineSize)
			{
				//Otherwise, set the style
				TTF_SetFontOutline(font, outlineSize);
			}		
		}
		else
		{
			std::cout<<"SetFontOutline error: Provided index is NULL"<<std::endl;
			return;
		}
	}
	catch(std::out_of_range problem)
	{
		//display invalid index
		std::cout<<"SetFontOutline error: font index invalid"<<std::endl;
		return;
	}
}
Пример #4
0
static mrb_value
mrb_sdl2_ttf_font_set_outline(mrb_state *mrb, mrb_value self)
{
  mrb_int outline;
  mrb_get_args(mrb, "i", &outline);
  TTF_SetFontOutline(mrb_sdl2_font_get_ptr(mrb, self), outline);
  return mrb_nil_value();
}
Пример #5
0
		int LOBJECT_METHOD(setFontOutline, TTF_Font * font){
			int style = 0;
			if (state.is_number(1)){
				style = state.to_integer(1);
			}
			TTF_SetFontOutline(font, style);
			return 0;
		}
Пример #6
0
void Font::printDamages(u16 damages, u16 x, u16 y, Color color) {
	TTF_SetFontKerning(m_fontLarge, 0);
	TTF_SetFontHinting(m_fontLarge, TTF_HINTING_NONE);
	
	TTF_SetFontOutline(m_fontLarge, 3);
	
	print(to_string(damages).c_str(), x - 3, y - 3, FONT_LARGE, Color::black);
	
	TTF_SetFontOutline(m_fontLarge, 2);
	
	print(to_string(damages).c_str(), x - 2, y - 2, FONT_LARGE, Color::white);
	
	TTF_SetFontOutline(m_fontLarge, 0);
	
	print(to_string(damages).c_str(), x, y, FONT_LARGE, color);
	
	TTF_SetFontHinting(m_fontLarge, TTF_HINTING_NORMAL);
	TTF_SetFontKerning(m_fontLarge, 1);
}
Пример #7
0
FontAdapter_SDL_ttf::FontAdapter_SDL_ttf(GraphicsContext* gc, const FontDescriptor& fontDescriptor)
{
	const float scaling = 1.2f;

	if (!TTF_WasInit())
		TTF_Init();

	int size = (int)(scaling * fontDescriptor.size * gc->GetCombinedScaling());
	if (size == 0)
		size = (int)(scaling * 12 * gc->GetCombinedScaling());

	_font1 = TTF_OpenFont(fontDescriptor.bold ? FONTNAME_BOLD : FONTNAME_REGULAR, size);
	_font2 = TTF_OpenFont(FONTNAME_FALLBACK, size);
	//_emoji = TTF_OpenFont(FONTNAME_EMOJI, size);

	int style = fontDescriptor.bold ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL;
	int hinting = TTF_HINTING_NORMAL;

	if (_font1 != NULL)
	{
		//TTF_SetFontStyle(_font1, style);
		TTF_SetFontOutline(_font1, 0);
		TTF_SetFontKerning(_font1, 1);
		TTF_SetFontHinting(_font1, hinting);
	}

	if (_font2 != NULL)
	{
		//TTF_SetFontStyle(_font2, style);
		TTF_SetFontOutline(_font2, 0);
		TTF_SetFontKerning(_font2, 1);
		TTF_SetFontHinting(_font2, hinting);
	}

	if (_emoji != NULL)
	{
		//TTF_SetFontStyle(_emoji, style);
		TTF_SetFontOutline(_emoji, 0);
		TTF_SetFontKerning(_emoji, 1);
		TTF_SetFontHinting(_emoji, hinting);
	}
}
Пример #8
0
void cache_glyphs()
{
    int i;
    char title[800];
    SDL_Color fg={0,0,0,255};
#if RENDER_MODE==1
    SDL_Color bg={255,255,255,255};
#endif

    free_glyphs();
    if(!font)
        return;
    if(style!=TTF_GetFontStyle(font))
        TTF_SetFontStyle(font,style);
    if(kerning != !!TTF_GetFontKerning(font))
        TTF_SetFontKerning(font,kerning);
    if(hinting != TTF_GetFontHinting(font))
        TTF_SetFontHinting(font,hinting);
    if(outline != TTF_GetFontOutline(font))
        TTF_SetFontOutline(font,outline);
    for(i=0; i<128; i++)
    {
        /* cache rendered surface */
#if RENDER_MODE==0
        text[i]=TTF_RenderGlyph_Solid(font,i+start_glyph,fg);
#elif RENDER_MODE==1
        text[i]=TTF_RenderGlyph_Shaded(font,i+start_glyph,fg,bg);
#elif RENDER_MODE==2
        text[i]=TTF_RenderGlyph_Blended(font,i+start_glyph,fg);
#endif
        if(!text[i])
        {
            printf("TTF_RenderGlyph_Shaded: %s\n", TTF_GetError());
            exit(4);
        }
        /* cache metrics */
        TTF_GlyphMetrics(font, i+start_glyph,
            &gm[i].minx, &gm[i].maxx,
            &gm[i].miny, &gm[i].maxy,
            &gm[i].advance);
    }

    sprintf(title,"%s-%s:%d+0x%04x",TTF_FontFaceFamilyName(font),
        TTF_FontFaceStyleName(font),font_size,start_glyph);
    SDL_WM_SetCaption(title,"latin1");
}
Пример #9
0
void cache_glyphs()
{
	SDL_Color fg={0,0,0,255};

#if RENDER_MODE==1
	SDL_Color bg={255,255,255,255};
#endif

	if (!font) return;
	
	if (style!=TTF_GetFontStyle(font)) TTF_SetFontStyle(font,style);

	if (kerning != !!TTF_GetFontKerning(font)) TTF_SetFontKerning(font,kerning);

	if (hinting != TTF_GetFontHinting(font)) TTF_SetFontHinting(font,hinting);
	if (outline != TTF_GetFontOutline(font)) TTF_SetFontOutline(font,outline);
}
Пример #10
0
// Load TTF font from file.
INT32 I_TTFLoadFont(const char *file, UINT32 ptsize)
{
	TTF_Font *tmpfont = NULL;
	float fontsize;

	// If a font is currently loaded, unload it.
	if (currentfont)
	{
		TTF_CloseFont(currentfont);
	}

	// Scale the specified font point size for the current resolution.
	fontsize = (ptsize * 0.005f) * (res.width - res.height);

	tmpfont = TTF_OpenFont(file, fontsize);

	if (!tmpfont)
		return FONTHANDLE;

	// set pointer for current font
	currentfont = tmpfont;

	// set current font point size
	currentfontpoint = ptsize;

	// get font properties, and set them
	currentfontstyle = TTF_GetFontStyle(currentfont);
	TTF_SetFontStyle(currentfont, currentfontstyle);

	// these functions only exist in SDL_ttf 2.0.10 onwards
#if SDL_TTF_VERSION_ATLEAST(2,0,10)
	currentfontkerning = TTF_GetFontKerning(currentfont);
	TTF_SetFontKerning(currentfont, currentfontkerning);

	currentfonthinting = TTF_GetFontHinting(currentfont);
	TTF_SetFontHinting(currentfont, currentfonthinting);

	currentfontoutline = TTF_GetFontOutline(currentfont);
	TTF_SetFontOutline(currentfont, currentfontoutline);
#endif

	return 0;
}
Пример #11
0
/* THIS CLASS IS DEPENDENT ON THE IMAGE CLASS */
SDL_Texture *renderFont(TTF_Font *fontObject,char *txt,int colour,int flags,int size, bool antialias, int outline, bool kerning){
	if(fontObject){
		TTF_SetFontStyle(fontObject,flags);
		SDL_Surface *surface = NULL;
		SDL_Color colourOb;
		colourOb.r = (colour & 0xFF0000)>>16;
		colourOb.g = (colour & 0x00FF00)>>8;
		colourOb.b = (colour & 0xFF);
		TTF_SetFontOutline(fontObject, outline);
		TTF_SetFontKerning(fontObject, (int) kerning);
		
		if(antialias)
			surface = TTF_RenderText_Blended(fontObject,(const char *)txt, colourOb);
		else
			surface = TTF_RenderText_Solid(fontObject,(const char *) txt, colourOb);

		SDL_Texture *tx = NULL;
		tx = SDL_CreateTextureFromSurface(renderer,surface);
		SDL_FreeSurface(surface);
		return tx;
	} else
		return NULL;
Пример #12
0
//
// Load a new font and create textures for each glyph
//
font *ttf_new (const char *name, int pointSize, int style)
{
    uint8 c;
    font *f;
    
    f = (fontp)zalloc(sizeof(*f));
    if (!f) {
        return (NULL);
    }

    f->name = strdup(name);
    f->ttf = TTF_OpenFont(name, pointSize);
    if (!f->ttf) {
        DIE("cannot open font file %s", name);
    }

    f->foreground.r = 255;
    f->foreground.g = 255;
    f->foreground.b = 255;
    f->background.r = 0;
    f->background.g = 0;
    f->background.b = 0;

    TTF_SetFontStyle(f->ttf, style);
    TTF_SetFontOutline(f->ttf, 0.5);
    f->height = TTF_FontHeight(f->ttf);
    f->ascent = TTF_FontAscent(f->ttf);
    f->descent = TTF_FontDescent(f->ttf);
    f->lineSkip = TTF_FontLineSkip(f->ttf);

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {
        ttf_create_tex_from_char(f, c);
    }

    return (f);
}
Пример #13
0
int main(int argc, char *argv[])
{
	char *argv0 = argv[0];
	SDL_Surface *screen;
	TTF_Font *font;
	SDL_Surface *text, *temp;
	int ptsize;
	int i, done;
	int rdiff, gdiff, bdiff;
	SDL_Color colors[NUM_COLORS];
	SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
	SDL_Color black = { 0x00, 0x00, 0x00, 0 };
	SDL_Color *forecol;
	SDL_Color *backcol;
	SDL_Rect dstrect;
	SDL_Event event;
	int rendersolid;
	int renderstyle;
	int outline;
	int hinting;
	int kerning;
	int dump;
	enum {
		RENDER_LATIN1,
		RENDER_UTF8,
		RENDER_UNICODE
	} rendertype;
	char *message, string[128];

	/* Look for special execution mode */
	dump = 0;
	/* Look for special rendering types */
	rendersolid = 0;
	renderstyle = TTF_STYLE_NORMAL;
	rendertype = RENDER_LATIN1;
	outline = 0;
	hinting = TTF_HINTING_NORMAL;
	kerning = 1;
	/* Default is black and white */
	forecol = &black;
	backcol = &white;
	for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) {
		if ( strcmp(argv[i], "-solid") == 0 ) {
			rendersolid = 1;
		} else
		if ( strcmp(argv[i], "-utf8") == 0 ) {
			rendertype = RENDER_UTF8;
		} else
		if ( strcmp(argv[i], "-unicode") == 0 ) {
			rendertype = RENDER_UNICODE;
		} else
		if ( strcmp(argv[i], "-b") == 0 ) {
			renderstyle |= TTF_STYLE_BOLD;
		} else
		if ( strcmp(argv[i], "-i") == 0 ) {
			renderstyle |= TTF_STYLE_ITALIC;
		} else
		if ( strcmp(argv[i], "-u") == 0 ) {
			renderstyle |= TTF_STYLE_UNDERLINE;
		} else
		if ( strcmp(argv[i], "-s") == 0 ) {
			renderstyle |= TTF_STYLE_STRIKETHROUGH;
		} else
		if ( strcmp(argv[i], "-outline") == 0 ) {
			if ( sscanf (argv[++i], "%d", &outline) != 1 ) {
				fprintf(stderr, Usage, argv0);
				return(1);
			}
		} else
		if ( strcmp(argv[i], "-hintlight") == 0 ) {
			hinting = TTF_HINTING_LIGHT;
		} else
		if ( strcmp(argv[i], "-hintmono") == 0 ) {
			hinting = TTF_HINTING_MONO;
		} else
		if ( strcmp(argv[i], "-hintnone") == 0 ) {
			hinting = TTF_HINTING_NONE;
		} else
		if ( strcmp(argv[i], "-nokerning") == 0 ) {
			kerning = 0;
		} else
		if ( strcmp(argv[i], "-dump") == 0 ) {
			dump = 1;
		} else
		if ( strcmp(argv[i], "-fgcol") == 0 ) {
			int r, g, b;
			if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
				fprintf(stderr, Usage, argv0);
				return(1);
			}
			forecol->r = (Uint8)r;
			forecol->g = (Uint8)g;
			forecol->b = (Uint8)b;
		} else
		if ( strcmp(argv[i], "-bgcol") == 0 ) {
			int r, g, b;
			if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
				fprintf(stderr, Usage, argv0);
				return(1);
			}
			backcol->r = (Uint8)r;
			backcol->g = (Uint8)g;
			backcol->b = (Uint8)b;
		} else {
			fprintf(stderr, Usage, argv0);
			return(1);
		}
	}
	argv += i;
	argc -= i;

	/* Check usage */
	if ( ! argv[0] ) {
		fprintf(stderr, Usage, argv0);
		return(1);
	}

	/* Initialize SDL */
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
		return(2);
	}

	/* Initialize the TTF library */
	if ( TTF_Init() < 0 ) {
		fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
		SDL_Quit();
		return(2);
	}

	/* Open the font file with the requested point size */
	ptsize = 0;
	if ( argc > 1 ) {
		ptsize = atoi(argv[1]);
	}
	if ( ptsize == 0 ) {
		i = 2;
		ptsize = DEFAULT_PTSIZE;
	} else {
		i = 3;
	}
	font = TTF_OpenFont(argv[0], ptsize);
	if ( font == NULL ) {
		fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
					ptsize, argv[0], SDL_GetError());
		cleanup(2);
	}
	TTF_SetFontStyle(font, renderstyle);
	TTF_SetFontOutline(font, outline);
	TTF_SetFontKerning(font, kerning);
	TTF_SetFontHinting(font, hinting);

	if( dump ) {
		for( i = 48; i < 123; i++ ) {
			SDL_Surface* glyph = NULL;

			glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol );

			if( glyph ) {
				char outname[64];
				sprintf( outname, "glyph-%d.bmp", i );
				SDL_SaveBMP( glyph, outname );
			}

		}
		cleanup(0);
	}

	/* Set a 640x480x8 video mode */
	screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
	if ( screen == NULL ) {
		fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
							SDL_GetError());
		cleanup(2);
	}

	/* 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; i<NUM_COLORS; ++i ) {
		colors[i].r = forecol->r + (i*rdiff)/4;
		colors[i].g = forecol->g + (i*gdiff)/4;
		colors[i].b = forecol->b + (i*bdiff)/4;
	}
	SDL_SetColors(screen, colors, 0, NUM_COLORS);

	/* Clear the background to background color */
	SDL_FillRect(screen, NULL,
			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]);  /* possible overflow */
	if ( rendersolid ) {
		text = TTF_RenderText_Solid(font, string, *forecol);
	} else {
		text = TTF_RenderText_Shaded(font, string, *forecol, *backcol);
	}
	if ( text != NULL ) {
		dstrect.x = 4;
		dstrect.y = 4;
		dstrect.w = text->w;
		dstrect.h = text->h;
		SDL_BlitSurface(text, NULL, screen, &dstrect);
		SDL_FreeSurface(text);
	}
	
	/* Render and center the message */
	if ( argc > 2 ) {
		message = argv[2];
	} else {
		message = DEFAULT_TEXT;
	}
	switch (rendertype) {
	    case RENDER_LATIN1:
		if ( rendersolid ) {
			text = TTF_RenderText_Solid(font,message,*forecol);
		} else {
			text = TTF_RenderText_Shaded(font,message,*forecol,*backcol);
		}
		break;

	    case RENDER_UTF8:
		if ( rendersolid ) {
			text = TTF_RenderUTF8_Solid(font,message,*forecol);
		} else {
			text = TTF_RenderUTF8_Shaded(font,message,*forecol,*backcol);
		}
		break;

	    case RENDER_UNICODE:
		{
			Uint16 unicode_text[BUFSIZ];
			int index;
#ifdef HAVE_ICONV
			/* Use iconv to convert the message into utf-16.
			 * "char" and "" are aliases for the local 8-bit encoding */
			iconv_t cd;
			/*ICONV_CONST*/ char *from_str = message;
			char *to_str = (char*)unicode_text;
			size_t from_sz = strlen(message) + 1;
			size_t to_sz = sizeof(unicode_text);
			size_t res;
			int i;

			if ((cd = iconv_open("UTF-16", "char")) == (iconv_t)-1
			    && (cd = iconv_open("UTF-16", "")) == (iconv_t)-1) {
				perror("Couldn't open iconv");
				exit(1);
			}

			res = iconv(cd, &from_str, &from_sz, &to_str, &to_sz);
			if (res == -1) {
				perror("Couldn't use iconv");
				exit(1);
			}

			iconv_close(cd);
#else
			/* Convert the message from ascii into utf-16.
			 * This is unreliable as a test because it always
			 * gives the local ordering. */
			for (index = 0; message[index]; index++) {
				unicode_text[index] = message[index];
			}
			unicode_text[index] = 0;
#endif

			if ( rendersolid ) {
				text = TTF_RenderUNICODE_Solid(font,
					unicode_text, *forecol);
			} else {
				text = TTF_RenderUNICODE_Shaded(font,
					unicode_text, *forecol, *backcol);
			}
		}
		break;
	    default:
		text = NULL; /* This shouldn't happen */
		break;
	}
	if ( text == NULL ) {
		fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
		TTF_CloseFont(font);
		cleanup(2);
	}
	dstrect.x = (screen->w - text->w)/2;
	dstrect.y = (screen->h - text->h)/2;
	dstrect.w = text->w;
	dstrect.h = text->h;
	printf("Font is generally %d big, and string is %hd big\n",
						TTF_FontHeight(font), text->h);

	/* Blit the text surface */
	if ( SDL_BlitSurface(text, NULL, screen, &dstrect) < 0 ) {
		fprintf(stderr, "Couldn't blit text to display: %s\n", 
								SDL_GetError());
		TTF_CloseFont(font);
		cleanup(2);
	}
	SDL_UpdateRect(screen, 0, 0, 0, 0);

	/* Set the text colorkey and convert to display format */
	if ( SDL_SetColorKey(text, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0) < 0 ) {
		fprintf(stderr, "Warning: Couldn't set text colorkey: %s\n",
								SDL_GetError());
	}
	temp = SDL_DisplayFormat(text);
	if ( temp != NULL ) {
		SDL_FreeSurface(text);
		text = temp;
	}

	/* Wait for a keystroke, and blit text on mouse press */
	done = 0;
	while ( ! done ) {
		if ( SDL_WaitEvent(&event) < 0 ) {
			fprintf(stderr, "SDL_PullEvent() error: %s\n",
								SDL_GetError());
			done = 1;
			continue;
		}
		switch (event.type) {
			case SDL_MOUSEBUTTONDOWN:
				dstrect.x = event.button.x - text->w/2;
				dstrect.y = event.button.y - text->h/2;
				dstrect.w = text->w;
				dstrect.h = text->h;
				if ( SDL_BlitSurface(text, NULL, screen,
							&dstrect) == 0 ) {
					SDL_UpdateRects(screen, 1, &dstrect);
				} else {
					fprintf(stderr,
					"Couldn't blit text to display: %s\n", 
								SDL_GetError());
				}
				break;
				
			case SDL_KEYDOWN:
			case SDL_QUIT:
				done = 1;
				break;
			default:
				break;
		}
	}
	SDL_FreeSurface(text);
	TTF_CloseFont(font);
	cleanup(0);

	/* Not reached, but fixes compiler warnings */
	return 0;
}
Пример #14
0
//------------------------------------------------------------------------------
void CFont::SetFontOutline(int outline, unsigned int FontIndex) {
	if( outline < 0 || !ValidIndex(FontIndex) ) return;
	TTF_SetFontOutline(Fonts.at(FontIndex).Font, outline);
}
Пример #15
0
Image *MLIFont::RenderGlyph(uint32_t c)
{
    EnsureUIThread();
    CheckScale();

    // render char
    SDL_Color whiteColor = {255, 255, 255, 255};
    if (invertedColors)
    {
        whiteColor.b = 255 - whiteColor.b;
        whiteColor.g = 255 - whiteColor.g;
        whiteColor.a = 255 - whiteColor.a;
    }

    string utf8string;
    utf8::unchecked::append(c, back_inserter(utf8string));

    SDL_Surface *pSurface = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), whiteColor);
    if (pSurface == NULL)
    {
        return NULL;
    }

    int scaledStrokeWidth = strokeWidth * GetFontScale() + 0.5;

    // render outlines
    if (strokeWidth > 0)
    {
        SDL_Color blackColor = {0, 0, 0, 255};
        if (invertedColors)
        {
            blackColor.b = 255 - blackColor.b;
            blackColor.g = 255 - blackColor.g;
            blackColor.a = 255 - blackColor.a;
        }

#ifndef MLI_SDL_FONT_OUTLINING
        SDL_Surface *pSurfaceOutline = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor);

        SDL_Surface *pSurfaceOutlinedText = SDL_CreateRGBSurface(
                    0,
                    pSurface->w + scaledStrokeWidth * 2,
                    pSurface->h + scaledStrokeWidth * 2,
                    pSurface->format->BitsPerPixel,
                    pSurface->format->Rmask,
                    pSurface->format->Gmask,
                    pSurface->format->Bmask,
                    pSurface->format->Amask);

        SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND);

        SDL_Rect dstRect = {0, 0, pSurface->w, pSurface->h};

        for (dstRect.x = 0; dstRect.x <= scaledStrokeWidth * 2; dstRect.x++)
        {
            for (dstRect.y = 0; dstRect.y <= scaledStrokeWidth * 2; dstRect.y++)
            {
                SDL_BlitSurface(pSurfaceOutline, NULL, pSurfaceOutlinedText, &dstRect);
            }
        }

        dstRect.x = scaledStrokeWidth;
        dstRect.y = scaledStrokeWidth;
        SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND);
        SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect);

        SDL_FreeSurface(pSurface);
        SDL_FreeSurface(pSurfaceOutline);

        pSurface = pSurfaceOutlinedText;
#else
        TTF_SetFontOutline(pTtfFont, scaledStrokeWidth);

        SDL_Surface *pSurfaceOutlinedText = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor);

        SDL_SetSurfaceBlendMode(pSurfaceOutlinedText, SDL_BLENDMODE_BLEND);
        SDL_Rect dstRect = {scaledStrokeWidth, scaledStrokeWidth, pSurface->w, pSurface->h};
        SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect);

        SDL_FreeSurface(pSurface);

        pSurface = pSurfaceOutlinedText;

        TTF_SetFontOutline(pTtfFont, 0);
#endif
    }

    // create image
    Image *pImage = Image::Load(pSurface, true);
    pImage->FlagFontSource(this);
    pImage->SetUseScreenScaling(false);

    return pImage;
}
Пример #16
0
void Bitmap::drawText(const IntRect &rect, const char *str, int align)
{
	guardDisposed();

	GUARD_MEGA;

	std::string fixed = fixupString(str);
	str = fixed.c_str();

	if (*str == '\0')
		return;

	if (str[0] == ' ' && str[1] == '\0')
		return;

	TTF_Font *font = p->font->getSdlFont();
	const Color &fontColor = p->font->getColor();
	const Color &outColor = p->font->getOutColor();

	SDL_Color c = fontColor.toSDLColor();
	c.a = 255;

	float txtAlpha = fontColor.norm.w;

	SDL_Surface *txtSurf;

	if (shState->rtData().config.solidFonts)
		txtSurf = TTF_RenderUTF8_Solid(font, str, c);
	else
		txtSurf = TTF_RenderUTF8_Blended(font, str, c);

	p->ensureFormat(txtSurf, SDL_PIXELFORMAT_ABGR8888);

	int rawTxtSurfH = txtSurf->h;

	if (p->font->getShadow())
		applyShadow(txtSurf, *p->format, c);

	/* outline using TTF_Outline and blending it together with SDL_BlitSurface
	 * FIXME: outline is forced to have the same opacity as the font color */
	if (p->font->getOutline())
	{
		SDL_Color co = outColor.toSDLColor();
		co.a = 255;
		SDL_Surface *outline;
		/* set the next font render to render the outline */
		TTF_SetFontOutline(font, OUTLINE_SIZE);
		if (shState->rtData().config.solidFonts)
			outline = TTF_RenderUTF8_Solid(font, str, co);
		else
			outline = TTF_RenderUTF8_Blended(font, str, co);

		p->ensureFormat(outline, SDL_PIXELFORMAT_ABGR8888);
		SDL_Rect outRect = {OUTLINE_SIZE, OUTLINE_SIZE, txtSurf->w, txtSurf->h}; 

		SDL_SetSurfaceBlendMode(txtSurf, SDL_BLENDMODE_BLEND);
		SDL_BlitSurface(txtSurf, NULL, outline, &outRect);
		SDL_FreeSurface(txtSurf);
		txtSurf = outline;
		/* reset outline to 0 */
		TTF_SetFontOutline(font, 0);
	}

	int alignX = rect.x;

	switch (align)
	{
	default:
	case Left :
		break;

	case Center :
		alignX += (rect.w - txtSurf->w) / 2;
		break;

	case Right :
		alignX += rect.w - txtSurf->w;
		break;
	}

	if (alignX < rect.x)
		alignX = rect.x;

	int alignY = rect.y + (rect.h - rawTxtSurfH) / 2;

	float squeeze = (float) rect.w / txtSurf->w;

	if (squeeze > 1)
		squeeze = 1;

	FloatRect posRect(alignX, alignY, txtSurf->w * squeeze, txtSurf->h);

	Vec2i gpTexSize;
	shState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize);

	bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0f;

	if (fastBlit)
	{
		if (squeeze == 1.0f && !shState->config().subImageFix)
		{
			/* Even faster: upload directly to bitmap texture.
			 * We have to make sure the posRect lies within the texture
			 * boundaries or texSubImage will generate errors.
			 * If it partly lies outside bounds we have to upload
			 * the clipped visible part of it. */
			SDL_Rect btmRect;
			btmRect.x = btmRect.y = 0;
			btmRect.w = width();
			btmRect.h = height();

			SDL_Rect txtRect;
			txtRect.x = posRect.x;
			txtRect.y = posRect.y;
			txtRect.w = posRect.w;
			txtRect.h = posRect.h;

			SDL_Rect inters;

			/* If we have no intersection at all,
			 * there's nothing to upload to begin with */
			if (SDL_IntersectRect(&btmRect, &txtRect, &inters))
			{
				bool subImage = false;
				int subSrcX = 0, subSrcY = 0;

				if (inters.w != txtRect.w || inters.h != txtRect.h)
				{
					/* Clip the text surface */
					subSrcX = inters.x - txtRect.x;
					subSrcY = inters.y - txtRect.y;
					subImage = true;

					posRect.x = inters.x;
					posRect.y = inters.y;
					posRect.w = inters.w;
					posRect.h = inters.h;
				}

				TEX::bind(p->gl.tex);

				if (!subImage)
				{
					TEX::uploadSubImage(posRect.x, posRect.y,
					                    posRect.w, posRect.h,
					                    txtSurf->pixels, GL_RGBA);
				}
				else
				{
					GLMeta::subRectImageUpload(txtSurf->w, subSrcX, subSrcY,
					                           posRect.x, posRect.y,
					                           posRect.w, posRect.h,
					                           txtSurf, GL_RGBA);
					GLMeta::subRectImageEnd();
				}
			}
		}
		else
		{
			/* Squeezing involved: need to use intermediary TexFBO */
			TEXFBO &gpTF = shState->gpTexFBO(txtSurf->w, txtSurf->h);

			TEX::bind(gpTF.tex);
			TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_RGBA);

			GLMeta::blitBegin(p->gl);
			GLMeta::blitSource(gpTF);
			GLMeta::blitRectangle(IntRect(0, 0, txtSurf->w, txtSurf->h),
			                      posRect, true);
			GLMeta::blitEnd();
		}
	}
	else
	{
		/* Aquire a partial copy of the destination
		 * buffer we're about to render to */
		TEXFBO &gpTex2 = shState->gpTexFBO(posRect.w, posRect.h);

		GLMeta::blitBegin(gpTex2);
		GLMeta::blitSource(p->gl);
		GLMeta::blitRectangle(posRect, Vec2i());
		GLMeta::blitEnd();

		FloatRect bltRect(0, 0,
		                  (float) (gpTexSize.x * squeeze) / gpTex2.width,
		                  (float) gpTexSize.y / gpTex2.height);

		BltShader &shader = shState->shaders().blt;
		shader.bind();
		shader.setTexSize(gpTexSize);
		shader.setSource();
		shader.setDestination(gpTex2.tex);
		shader.setSubRect(bltRect);
		shader.setOpacity(txtAlpha);

		shState->bindTex();
		TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_RGBA);
		TEX::setSmooth(true);

		Quad &quad = shState->gpQuad();
		quad.setTexRect(FloatRect(0, 0, txtSurf->w, txtSurf->h));
		quad.setPosRect(posRect);

		p->bindFBO();
		p->pushSetViewport(shader);

		p->blitQuad(quad);

		p->popViewport();
	}

	SDL_FreeSurface(txtSurf);
	p->addTaintedArea(posRect);

	p->onModified();
}
Пример #17
0
void SDLFont::setOutline(int outline) {
    TTF_SetFontOutline(this->fontContext, outline);
}
Пример #18
0
void setup (void) {
	SDL_Surface * image;
	TTF_Font *temp1, *temp2;
	SDL_Color color;
	SDL_Rect rect, rect2;
	int g;
	char buffer_file[8192];
	char *systemdata_path = get_systemdata_path ();
	
	/* Inicializar el Video SDL */
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		fprintf (stderr,
			_("Error: Can't initialize the video subsystem\n"
			"The error returned by SDL is:\n"
			"%s\n"), SDL_GetError());
		exit (1);
	}
	sprintf (buffer_file, "%simages/icon.png", systemdata_path);
	image = IMG_Load (buffer_file);
	if (image) {
		SDL_WM_SetIcon (image, NULL);
		SDL_FreeSurface (image);
	}
	SDL_WM_SetCaption (_("Paddle Puffle"), _("Paddle Puffle"));
	
	/* Crear la pantalla de dibujado */
	screen = set_video_mode (0);
	
	if (screen == NULL) {
		fprintf (stderr,
			_("Error: Can't setup 760x480 video mode.\n"
			"The error returned by SDL is:\n"
			"%s\n"), SDL_GetError());
		exit (1);
	}
	
	use_sound = 1;
	if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0) {
		fprintf (stdout,
			_("Warning: Can't initialize the audio subsystem\n"
			"Continuing...\n"));
		use_sound = 0;
	}
	
	if (use_sound) {
		/* Inicializar el sonido */
		if (Mix_OpenAudio (22050, AUDIO_S16, 2, 4096) < 0) {
			fprintf (stdout,
				_("Warning: Can't initialize the SDL Mixer library\n"));
			use_sound = 0;
		}
	}
	
	for (g = 0; g < NUM_IMAGES; g++) {
		sprintf (buffer_file, "%s%s", systemdata_path, images_names[g]);
		image = IMG_Load (buffer_file);
		
		if (image == NULL) {
			fprintf (stderr,
				_("Failed to load data file:\n"
				"%s\n"
				"The error returned by SDL is:\n"
				"%s\n"), buffer_file, SDL_GetError());
			SDL_Quit ();
			exit (1);
		}
		
		images[g] = image;
		/* TODO: Mostrar la carga de porcentaje */
	}
	
	/* Pre-Dibujar la pantalla gris */
	grey_screen = SDL_CreateRGBSurface (SDL_SWSURFACE | SDL_SRCALPHA, 760, 480, 32, 0, 0, 0, 0);
	SDL_FillRect (grey_screen, NULL,
	              SDL_MapRGB (grey_screen->format, 0, 0, 0)); /* Negro */
	SDL_SetAlpha (grey_screen, SDL_SRCALPHA, 128); /* Alpha al 50 % */
	
	if (use_sound) {
		for (g = 0; g < NUM_SOUNDS; g++) {
			sprintf (buffer_file, "%s%s", systemdata_path, sound_names[g]);
			sounds[g] = Mix_LoadWAV (buffer_file);
			
			if (sounds[g] == NULL) {
				fprintf (stderr,
					_("Failed to load data file:\n"
					"%s\n"
					"The error returned by SDL is:\n"
					"%s\n"), buffer_file, SDL_GetError ());
				SDL_Quit ();
				exit (1);
			}
			Mix_VolumeChunk (sounds[g], MIX_MAX_VOLUME / 2);
		}
		
		/* Cargar la música */
		sprintf (buffer_file, "%s%s", systemdata_path, MUS_CARNIE);
		mus_carnie = Mix_LoadMUS (buffer_file);
		
		if (mus_carnie == NULL) {
			fprintf (stderr,
				_("Failed to load data file:\n"
				"%s\n"
				"The error returned by SDL is:\n"
				"%s\n"), buffer_file, SDL_GetError ());
			SDL_Quit ();
			exit (1);
		}
		
	}
	
	if (TTF_Init () < 0) {
		fprintf (stderr,
			_("Error: Can't initialize the SDL TTF library\n"
			"%s\n"), TTF_GetError ());
		SDL_Quit ();
		exit (1);
	}
	
	/* Tipografias 10, 14, 16, 26 */
	sprintf (buffer_file, "%s%s", systemdata_path, "ccfacefront.ttf");
	ttf_facefront = SDL_RWFromFile (buffer_file, "rb");
	
	if (ttf_facefront == NULL) {
		fprintf (stderr,
			_("Failed to load font file 'CCFaceFront'\n"
			"The error returned by SDL is:\n"
			"%s\n"), TTF_GetError ());
		SDL_Quit ();
		exit (1);
	}
	
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	temp1 = TTF_OpenFontRW (ttf_facefront, 0, 10);
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	ttf14_normal = TTF_OpenFontRW (ttf_facefront, 0, 14);
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	ttf16_normal = TTF_OpenFontRW (ttf_facefront, 0, 16);
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	ttf26_normal = TTF_OpenFontRW (ttf_facefront, 0, 26);
	
	if (!temp1 || !ttf14_normal || !ttf16_normal || !ttf26_normal) {
		SDL_Quit ();
		exit (1);
	}
	
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	ttf20_normal = TTF_OpenFontRW (ttf_facefront, 0, 20);
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	ttf20_outline = TTF_OpenFontRW (ttf_facefront, 0, 20);
	SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET);
	ttf16_outline = TTF_OpenFontRW (ttf_facefront, 1, 16);
	
	if (!ttf20_normal || !ttf20_outline || !ttf16_outline) {
		SDL_Quit ();
		exit (1);
	}
	
	TTF_SetFontStyle (temp1, TTF_STYLE_ITALIC);
	TTF_SetFontStyle (ttf14_normal, TTF_STYLE_ITALIC);
	TTF_SetFontStyle (ttf16_normal, TTF_STYLE_ITALIC);
	TTF_SetFontStyle (ttf26_normal, TTF_STYLE_ITALIC);
	TTF_SetFontStyle (ttf16_outline, TTF_STYLE_ITALIC);
	TTF_SetFontStyle (ttf20_outline, TTF_STYLE_ITALIC);
	TTF_SetFontStyle (ttf20_normal, TTF_STYLE_ITALIC);
	
	TTF_SetFontOutline (ttf16_outline, OUTLINE_TEXT);
	TTF_SetFontOutline (ttf20_outline, OUTLINE_TEXT);
	
	/* Generar textos */
	bind_textdomain_codeset (PACKAGE, "UTF-8");
	color.r = color.g = color.b = 0; /* Negro */
	
	for (g = 0; g < NUM_TEXTS; g++) {
		switch (text_info [g]) {
			case 10: temp2 = temp1; break;
			case 14: temp2 = ttf14_normal; break;
			case 16: temp2 = ttf16_normal; break;
			case 26: temp2 = ttf26_normal; break;
			default: temp2 = ttf16_normal;
		}
		
		texts[g] = draw_text (temp2, _(text_strings[g]), &color);
	}
	
	/* Copiar la palabra "Tickets" en el background */
	/* También copiar el nombre del juego al titulo y al fondo */
	rect.x = 607 + ((135 - texts[TEXT_TICKETS]->w) / 2); rect.y = 38;
	rect.w = texts[TEXT_TICKETS]->w; rect.h = texts[TEXT_TICKETS]->h;
	rect2.x = 191; rect2.y = 96;
	rect2.w = images[IMG_TITLE]->w; rect2.h = images[IMG_TITLE]->h;
	for (g = IMG_BACKGROUND_NORMAL; g <= IMG_BACKGROUND_FAIL_1; g++) {
		SDL_BlitSurface (texts[TEXT_TICKETS], NULL, images[g], &rect);
		SDL_BlitSurface (images[IMG_TITLE], NULL, images[g], &rect2);
	}
	
	/* X = 84.35, Y = 50.85 */
	rect2.x = 84; rect2.y = 51;
	SDL_BlitSurface (images[IMG_TITLE], NULL, images[IMG_TITLE_OPENING], &rect2);
	
	TTF_CloseFont (temp1);
	/* Generador de números aleatorios */
	srand ((unsigned int) getpid ());
}
Пример #19
0
int main(int argc, char *argv[])
{
    char *argv0 = argv[0];
    SDL_Window *window;
    SDL_Renderer *renderer;
    TTF_Font *font;
    SDL_Surface *text;
    Scene scene;
    int ptsize;
    int i, done;
    SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
    SDL_Color black = { 0x00, 0x00, 0x00, 0 };
    SDL_Color *forecol;
    SDL_Color *backcol;
    SDL_Event event;
    int rendersolid;
    int renderstyle;
    int outline;
    int hinting;
    int kerning;
    int dump;
    enum {
        RENDER_LATIN1,
        RENDER_UTF8,
        RENDER_UNICODE
    } rendertype;
    char *message, string[128];

    /* Look for special execution mode */
    dump = 0;
    /* Look for special rendering types */
    rendersolid = 0;
    renderstyle = TTF_STYLE_NORMAL;
    rendertype = RENDER_LATIN1;
    outline = 0;
    hinting = TTF_HINTING_NORMAL;
    kerning = 1;
    /* Default is black and white */
    forecol = &black;
    backcol = &white;
    for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) {
        if ( strcmp(argv[i], "-solid") == 0 ) {
            rendersolid = 1;
        } else
        if ( strcmp(argv[i], "-utf8") == 0 ) {
            rendertype = RENDER_UTF8;
        } else
        if ( strcmp(argv[i], "-unicode") == 0 ) {
            rendertype = RENDER_UNICODE;
        } else
        if ( strcmp(argv[i], "-b") == 0 ) {
            renderstyle |= TTF_STYLE_BOLD;
        } else
        if ( strcmp(argv[i], "-i") == 0 ) {
            renderstyle |= TTF_STYLE_ITALIC;
        } else
        if ( strcmp(argv[i], "-u") == 0 ) {
            renderstyle |= TTF_STYLE_UNDERLINE;
        } else
        if ( strcmp(argv[i], "-s") == 0 ) {
            renderstyle |= TTF_STYLE_STRIKETHROUGH;
        } else
        if ( strcmp(argv[i], "-outline") == 0 ) {
            if ( sscanf (argv[++i], "%d", &outline) != 1 ) {
                fprintf(stderr, Usage, argv0);
                return(1);
            }
        } else
        if ( strcmp(argv[i], "-hintlight") == 0 ) {
            hinting = TTF_HINTING_LIGHT;
        } else
        if ( strcmp(argv[i], "-hintmono") == 0 ) {
            hinting = TTF_HINTING_MONO;
        } else
        if ( strcmp(argv[i], "-hintnone") == 0 ) {
            hinting = TTF_HINTING_NONE;
        } else
        if ( strcmp(argv[i], "-nokerning") == 0 ) {
            kerning = 0;
        } else
        if ( strcmp(argv[i], "-dump") == 0 ) {
            dump = 1;
        } else
        if ( strcmp(argv[i], "-fgcol") == 0 ) {
            int r, g, b;
            if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
                fprintf(stderr, Usage, argv0);
                return(1);
            }
            forecol->r = (Uint8)r;
            forecol->g = (Uint8)g;
            forecol->b = (Uint8)b;
        } else
        if ( strcmp(argv[i], "-bgcol") == 0 ) {
            int r, g, b;
            if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
                fprintf(stderr, Usage, argv0);
                return(1);
            }
            backcol->r = (Uint8)r;
            backcol->g = (Uint8)g;
            backcol->b = (Uint8)b;
        } else {
            fprintf(stderr, Usage, argv0);
            return(1);
        }
    }
    argv += i;
    argc -= i;

    /* Check usage */
    if ( ! argv[0] ) {
        fprintf(stderr, Usage, argv0);
        return(1);
    }

    /* Initialize the TTF library */
    if ( TTF_Init() < 0 ) {
        fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
        SDL_Quit();
        return(2);
    }

    /* Open the font file with the requested point size */
    ptsize = 0;
    if ( argc > 1 ) {
        ptsize = atoi(argv[1]);
    }
    if ( ptsize == 0 ) {
        i = 2;
        ptsize = DEFAULT_PTSIZE;
    } else {
        i = 3;
    }
    font = TTF_OpenFont(argv[0], ptsize);
    if ( font == NULL ) {
        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
                ptsize, argv[0], SDL_GetError());
        cleanup(2);
    }
    TTF_SetFontStyle(font, renderstyle);
    TTF_SetFontOutline(font, outline);
    TTF_SetFontKerning(font, kerning);
    TTF_SetFontHinting(font, hinting);

    if( dump ) {
        for( i = 48; i < 123; i++ ) {
            SDL_Surface* glyph = NULL;

            glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol );

            if( glyph ) {
                char outname[64];
                sprintf( outname, "glyph-%d.bmp", i );
                SDL_SaveBMP( glyph, outname );
            }

        }
        cleanup(0);
    }

    /* Create a window */
    if (SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, 0, &window, &renderer) < 0) {
        fprintf(stderr, "SDL_CreateWindowAndRenderer() failed: %s\n", SDL_GetError());
        cleanup(2);
    }

    /* Show which font file we're looking at */
    sprintf(string, "Font file: %s", argv[0]);  /* possible overflow */
    if ( rendersolid ) {
        text = TTF_RenderText_Solid(font, string, *forecol);
    } else {
        text = TTF_RenderText_Shaded(font, string, *forecol, *backcol);
    }
    if ( text != NULL ) {
        scene.captionRect.x = 4;
        scene.captionRect.y = 4;
        scene.captionRect.w = text->w;
        scene.captionRect.h = text->h;
        scene.caption = SDL_CreateTextureFromSurface(renderer, text);
        SDL_FreeSurface(text);
    }

    /* Render and center the message */
    if ( argc > 2 ) {
        message = argv[2];
    } else {
        message = DEFAULT_TEXT;
    }
    switch (rendertype) {
        case RENDER_LATIN1:
            if ( rendersolid ) {
                text = TTF_RenderText_Solid(font,message,*forecol);
            } else {
                text = TTF_RenderText_Shaded(font,message,*forecol,*backcol);
            }
            break;

        case RENDER_UTF8:
            if ( rendersolid ) {
                text = TTF_RenderUTF8_Solid(font,message,*forecol);
            } else {
                text = TTF_RenderUTF8_Shaded(font,message,*forecol,*backcol);
            }
            break;

        case RENDER_UNICODE:
        {
            Uint16 *unicode_text = SDL_iconv_utf8_ucs2(message);
            if ( rendersolid ) {
                text = TTF_RenderUNICODE_Solid(font,
                                               unicode_text, *forecol);
            } else {
                text = TTF_RenderUNICODE_Shaded(font,
                                                unicode_text, *forecol, *backcol);
            }
            SDL_free(unicode_text);
        }
            break;
        default:
            text = NULL; /* This shouldn't happen */
            break;
    }
    if ( text == NULL ) {
        fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
        TTF_CloseFont(font);
        cleanup(2);
    }
    scene.messageRect.x = (WIDTH - text->w)/2;
    scene.messageRect.y = (HEIGHT - text->h)/2;
    scene.messageRect.w = text->w;
    scene.messageRect.h = text->h;
    scene.message = SDL_CreateTextureFromSurface(renderer, text);
    printf("Font is generally %d big, and string is %d big\n",
           TTF_FontHeight(font), text->h);

    draw_scene(renderer, &scene);

    /* Wait for a keystroke, and blit text on mouse press */
    done = 0;
    while ( ! done ) {
        if ( SDL_WaitEvent(&event) < 0 ) {
            fprintf(stderr, "SDL_PullEvent() error: %s\n",
                    SDL_GetError());
            done = 1;
            continue;
        }
        switch (event.type) {
            case SDL_MOUSEBUTTONDOWN:
                scene.messageRect.x = event.button.x - text->w/2;
                scene.messageRect.y = event.button.y - text->h/2;
                scene.messageRect.w = text->w;
                scene.messageRect.h = text->h;
                draw_scene(renderer, &scene);
                break;

            case SDL_KEYDOWN:
            case SDL_QUIT:
                done = 1;
                break;
            default:
                break;
        }
    }
    SDL_FreeSurface(text);
    TTF_CloseFont(font);
    SDL_DestroyTexture(scene.caption);
    SDL_DestroyTexture(scene.message);
    cleanup(0);

    /* Not reached, but fixes compiler warnings */
    return 0;
}