示例#1
0
文件: font.c 项目: LibreGames/edgar
SDL_Surface *generateTextSurface(char *text, TTF_Font *font, int fr, int fg, int fb, int br, int bg, int bb)
{
	SDL_Surface *surface;
	SDL_Color foregroundcolour, backgroundcolour;

	foregroundcolour.r = fr;
	foregroundcolour.g = fg;
	foregroundcolour.b = fb;

	backgroundcolour.r = br;
	backgroundcolour.g = bg;
	backgroundcolour.b = bb;

	/* Use SDL_TTF to generate a string image, this returns an SDL_Surface */

	surface = TTF_RenderUTF8_Shaded(font, text, foregroundcolour, backgroundcolour);

	if (surface == NULL)
	{
		printf("Couldn't create String %s: %s\n", text, SDL_GetError());

		return NULL;
	}

	/* Return the generated string image */

	return surface;
}
示例#2
0
文件: tfont.cpp 项目: albinoz/raine
void TFont_ttf::surf_string(SDL_Surface *surf,int x, int y, const char *s, int color, int bgcolor, int w) {
    if (!s[0]) return;
  if (!ttf)
    return TFont::surf_string(surf,x,y,s,color,bgcolor,w);
  if (!bgcolor) // 0 is totally transparent in sdl_gfx -> no bg
    return surf_string_tr(surf,x,y,s,color,w);
  SDL_Rect dest;
  SDL_Color sc,bg;
  sc.b = (color >> 8) & 0xff;
  sc.g = (color >> 16) & 0xff;
  sc.r = (color >> 24) & 0xff;
  bg.b = (bgcolor >> 8) & 0xff;
  bg.g = (bgcolor >> 16) & 0xff;
  bg.r = (bgcolor >> 24) & 0xff;
  SDL_Surface *sf;
  if (is_utf)
      sf = TTF_RenderUTF8_Shaded(ttf,s,sc,bg);
  else
      sf = TTF_RenderText_Shaded(ttf,s,sc,bg);
  // SDL_SetColorKey(sf,SDL_SRCCOLORKEY | SDL_RLEACCEL,0);
  dest.x = x; dest.y = y;
  if (w && w < sf->w) {
      SDL_Rect src;
      src.w = w;
      src.h = sf->h;
      src.x = src.y = 0;
      SDL_BlitSurface(sf,&src,surf,&dest);
  } else
      SDL_BlitSurface(sf,NULL,surf,&dest);
  SDL_FreeSurface(sf);
}
示例#3
0
extern DECLSPEC SDL_Surface * SDLCALL
  TTF_RenderUTF8_Shaded_p(
    TTF_Font *font,
    const char *text,
    SDL_Color *fg,
    SDL_Color *bg) {

  return TTF_RenderUTF8_Shaded(font, text, *fg, *bg);
}
示例#4
0
文件: screen.cpp 项目: eanger/eggs
void Screen::print_line_at(const std::string& line,
                           unsigned int y,
                           unsigned int x) {
  auto surf = TTF_RenderUTF8_Shaded(font_.get(), line.c_str(), text_color_, empty_);
  SDL_Rect position{(int) x, (int) y, surf->w, surf->h};
  auto texture = SDL_CreateTextureFromSurface(renderer_.get(), surf);
  SDL_RenderCopy(renderer_.get(), texture, nullptr /* whole text texture */, &position);
  SDL_DestroyTexture(texture);
  SDL_FreeSurface(surf);
}
示例#5
0
/**
 * Constructs a broadcast message. It may consist of up to three "parts".
 * When numbers 1 to MAX_PLAYERS are used, the number is exchanged for a
 * "PlayerN" string, and colored according the current player color.
 *
 * @param msg Message string to be displayed.
 * @param pcolors An array of the current player colors.
 * @return The constructed broadcast message.
 */
SDL_Surface *makeBroadcast(char *msg, SDL_Color pcolors[MAX_PLAYERS])
{
    extern struct player players[MAX_PLAYERS];
    SDL_Surface *broadcast;
    unsigned int i;
    char *strings[BROADC_PARTS];
    SDL_Surface *parts[BROADC_PARTS];
    unsigned int width = 0;

    /* Split message string */
    strings[0] = strtok(msg, ";");
    for (i = 1; (strings[i] = strtok(NULL, ";")) != NULL; ++i) {}

    for (i = 0; i < BROADC_PARTS && strings[i] != NULL; ++i) {

        char pstring[PLAYER_NAME_LEN];
        if (strlen(strings[i]) == 1) {
            int pnum = atoi(strings[i]);
            snprintf(pstring, PLAYER_NAME_LEN, "%s", (&players[pnum - 1])->name);
            parts[i] = TTF_RenderUTF8_Shaded(font_broadc, pstring,
                                             pcolors[pnum - 1], cMenuBG);
        } else
            parts[i] = TTF_RenderUTF8_Shaded(font_broadc, strings[i],
                                             cBroadcast, cMenuBG);

        width += parts[i]->w;
    }

    broadcast = SDL_CreateRGBSurface(SDL_HWSURFACE, width, parts[0]->h,
                                     SCREEN_BPP, 0, 0, 0, 0);

    unsigned int nparts = i;
    int hoffset = 0;
    for (i = 0; i < nparts; ++i) {
        SDL_Rect offset = {hoffset, 0, 0, 0};
        SDL_BlitSurface(parts[i], NULL, broadcast, &offset);
        hoffset += parts[i]->w;
        SDL_FreeSurface(parts[i]);
    }

    return broadcast;
}
示例#6
0
void Font::DrawText(SDL_Surface* surface, const SDL_Color& color, const SDL_Color& back_color, const std::string& font_text, const Sint16 x, const Sint16 y) const // TODO
{
	BOOST_ASSERT(surface);
	BOOST_ASSERT(Point(x, y) == Point(x, y));
	SDL_Surface *sText = TTF_RenderUTF8_Shaded( font, font_text.c_str(), color, back_color);
	BOOST_ASSERT(sText);

	SDL_Rect rcDest = {x, static_cast<Sint16>(y-4), 0, 0};
	SDL_BlitSurface( sText, NULL, surface, &rcDest );
	SDL_FreeSurface( sText );
}
示例#7
0
  SDL_Surface * TTF_RenderText_Shaded_FAST(TTF_Font *font, const char *text, Uint8 fr, Uint8 fg, Uint8 fb, Uint8 br, Uint8 bg, Uint8 bb) {
    color.r = fr;
    color.g = fg;
    color.b = fb;

    back.r = br;
    back.g = bg;
    back.b = bb;

    return TTF_RenderUTF8_Shaded(font, text, color, back);
    
  }
示例#8
0
		void text::quick_draw(render& render_obj, 
			GLfloat x, 
			GLfloat y, 
			const std::string& str, 
			const std::string& font, 
			int size, 
			const color& c)
		{
			SDL_Color bg = {0, 0, 0, 255};
			surface_ptr surf = surface_ptr(TTF_RenderUTF8_Shaded(font::get_font(font, size).get(), str.c_str(), c.as_sdl_color(), bg), SDL_FreeSurface);
			ASSERT_LOG(surf != NULL, "Couldn't render text into texture");
			render_obj.blit_2d_texture(texture::get(surf), x, y);
		}
示例#9
0
			rect quick_draw(int x, 
				int y,
				const std::string& str, 
				const std::string& font, 
				int size, 
				const color& c)
			{
				SDL_Color bg = {0, 0, 0, 255};
				surface_ptr surf = surface_ptr(new surface(TTF_RenderUTF8_Shaded(font::get_font(font, size).get(), str.c_str(), c.as_sdl_color(), bg)));
				ASSERT_LOG(surf != NULL, "Couldn't render text into texture");
				blit_2d_texture(texture::get(surf), static_cast<float>(x), static_cast<float>(y), static_cast<float>(surf->width()), static_cast<float>(surf->height()));
				return rect(x, y, surf->width(), surf->height());
			}
/**
* Method used to display on a screen only one string.
* @param	font is the pointer to TTF_Font which will be used to type a text on the screen.
* @param	screen is the pointer to the screen on which we will type.
* @param	text is the text to type.
* @param	foregroundColor is the color which will be used to type not active options.
* @param	x is the x axis location.
* @param	y is the y axis location.
*/
void IMenuState::displayOneText(TTF_Font* font, SDL_Surface* screen, const char* text, SDL_Color foregroundColor, int x, int y) throw(TextCreationException)
{
	SDL_Surface *sText;
	SDL_Rect dest = {x, y, 0, 0};

	if (!(sText= TTF_RenderUTF8_Shaded(font, text, foregroundColor, backgroundColor)))
	{
		if(sText != NULL)
				SDL_FreeSurface(sText);
		throw new TextCreationException();
	}

	SDL_BlitSurface( sText, NULL, screen, &dest );
	SDL_FreeSurface( sText );
}
示例#11
0
int
render_glyph(Glyph *g, SDL_Surface **ret) {
	SDL_Color color = {0,0,0}, bgcolor={0xff,0xff,0xff};
	int bold, italic, underline, strikethrough, sup, sub, supsub;
	int font;
	int baseline;
	char *byte;
	TTF_Font **fs;
	
	byte = g->bytes;
	if (format_byte(*byte, &bold, &italic, &underline, &strikethrough, &sup, &sub, &supsub))
		byte++;
	
	if (sup || sub || supsub)
		fs = su_fonts;
	else
		fs = fonts;
		
	baseline = 0;
	if (sub)
		baseline = 9;
	else if(supsub)
		baseline = 3;
	
	if (bold && italic)
		font = FONT_BOLD_ITALIC;
	else if (bold)
		font = FONT_BOLD;
	else if (italic)
		font = FONT_ITALIC;
	else
		font = FONT_NORMAL;
		
	if (underline && strikethrough)
		TTF_SetFontStyle(fs[font], TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH);
	else if (underline)
		TTF_SetFontStyle(fs[font], TTF_STYLE_UNDERLINE);
	else if (strikethrough)
		TTF_SetFontStyle(fs[font], TTF_STYLE_STRIKETHROUGH);
	
	*ret = TTF_RenderUTF8_Shaded(fs[font], byte, color, bgcolor);
	TTF_SetFontStyle(fs[font], TTF_STYLE_NORMAL);
	
	return baseline;
}
示例#12
0
SDL_Surface * Font::renderShadedText(const char * text, int style, SDL_Color * c, SDL_Color * s) {
  SDL_Surface * surf;

  int old = this->setStyle(style);

  SDL_Color color = {0,0,0};
  SDL_Color bg = {0,0,0};
  if (c == NULL) c = &color;
  if (s == NULL) s = &bg;

  surf = TTF_RenderUTF8_Shaded(this->font, text, *c, *s);
  if (surf == NULL)
    throw SDLException("Nie mogę utworzyć powieszchni tekstowej");

  this->setStyle(old);

  return surf;
}
示例#13
0
文件: TText.cpp 项目: doremi/pxgui
SDL_Surface *TText::render()
{
    if (strlen(str) == 0) {
        setAspect(0, 0);
        return NULL;
    }

    SDL_Surface *t = TTF_RenderUTF8_Shaded(font, str, forecolor, backcolor);

    if ( t == NULL ) {
        fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
        TTF_CloseFont(font);
    }

    setAspect(t->w, t->h);

    return t;
}
示例#14
0
JNIEXPORT jlong JNICALL Java_sdljava_x_swig_SWIG_1SDLTTFJNI_TTF_1RenderUTF8_1Shaded(JNIEnv *jenv, jclass jcls, jlong jarg1, jstring jarg2, jlong jarg3, jlong jarg4) {
    jlong jresult = 0 ;
    TTF_Font *arg1 = (TTF_Font *) 0 ;
    char *arg2 ;
    SDL_Color arg3 ;
    SDL_Color arg4 ;
    SDL_Surface *result;
    SDL_Color *argp3 ;
    SDL_Color *argp4 ;
    
    (void)jenv;
    (void)jcls;
    arg1 = *(TTF_Font **)&jarg1; 
    {
        arg2 = 0;
        if (jarg2) {
            arg2 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg2, 0);
            if (!arg2) return 0;
        }
    }
    argp3 = *(SDL_Color **)&jarg3; 
    if (!argp3) {
        SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null SDL_Color");
        return 0;
    }
    arg3 = *argp3; 
    argp4 = *(SDL_Color **)&jarg4; 
    if (!argp4) {
        SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null SDL_Color");
        return 0;
    }
    arg4 = *argp4; 
    result = (SDL_Surface *)TTF_RenderUTF8_Shaded(arg1,(char const *)arg2,arg3,arg4);
    
    *(SDL_Surface **)&jresult = result; 
    {
        if (arg2) (*jenv)->ReleaseStringUTFChars(jenv, jarg2, arg2); 
    }
    return jresult;
}
示例#15
0
static mrb_value
mrb_sdl2_ttf_font_render_UTF8_shaded(mrb_state *mrb, mrb_value self)
{
  mrb_value text; 
  mrb_int fgr, fgg, fgb, fga, bgr, bgg, bgb, bga;
  SDL_Surface * c;
  SDL_Color fgcolor;
  SDL_Color bgcolor;
  mrb_get_args(mrb, "Siiiiiiii", &text, &fgr, &fgg, &fgb, &fga, &bgr, &bgg, &bgb, &bga);
  fgcolor.r = fgr;
  fgcolor.g = fgg;
  fgcolor.b = fgb;
  fgcolor.a = fga;
  bgcolor.r = bgr;
  bgcolor.g = bgg;
  bgcolor.b = bgb;
  bgcolor.a = bga;
  c = TTF_RenderUTF8_Shaded(mrb_sdl2_font_get_ptr(mrb, self), RSTRING_PTR(text), fgcolor, bgcolor);
  if (c == NULL) {
    mruby_sdl2_raise_error(mrb);
    return mrb_false_value();
  }
  return mrb_sdl2_video_surface(mrb, c, 0);
}
示例#16
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;
}
示例#17
0
/**
 * @brief Creates the text surface.
 *
 * This function is called when there is a change.
 */
void TextSurface::rebuild() {

  if (surface != NULL) {
    // another text was previously set: delete it
    SDL_FreeSurface(surface->get_internal_surface());
    delete surface;
    surface = NULL;
  }

  if (is_empty()) {
    // empty string: no surface to create
    return;
  }

  // create the text surface

  SDL_Surface *internal_surface = NULL;
  switch (rendering_mode) {

  case TEXT_SOLID:
    internal_surface = TTF_RenderUTF8_Solid(fonts[font_id].internal_font, text.c_str(), *text_color.get_internal_color());
    break;

  case TEXT_SHADED:
    internal_surface = TTF_RenderUTF8_Shaded(fonts[font_id].internal_font, text.c_str(), *text_color.get_internal_color(),
	*background_color.get_internal_color());
    break;

  case TEXT_BLENDED:
    internal_surface = TTF_RenderUTF8_Blended(fonts[font_id].internal_font, text.c_str(), *text_color.get_internal_color());
    break;
  }

  Debug::check_assertion(internal_surface != NULL, StringConcat()
      << "Cannot create the text surface for string '" << text << "': " << SDL_GetError());
  surface = new Surface(internal_surface);

  // calculate the coordinates of the top-left corner
  int x_left = 0, y_top = 0;

  switch (horizontal_alignment) {

  case ALIGN_LEFT:
    x_left = x;
    break;

  case ALIGN_CENTER:
    x_left = x - surface->get_width() / 2;
    break;

  case ALIGN_RIGHT:
    x_left = x - surface->get_width();
    break;
  }

  switch (vertical_alignment) {

  case ALIGN_TOP:
    y_top = y;
    break;

  case ALIGN_MIDDLE:
    y_top = y - surface->get_height() / 2;
    break;

  case ALIGN_BOTTOM:
    y_top = y - surface->get_height();
    break;
  }

  text_position.set_xy(x_left, y_top);
}
示例#18
0
static PyObject*
font_render(PyObject* self, PyObject* args)
{
    TTF_Font* font = PyFont_AsFont (self);
    int aa;
    PyObject* text, *final;
    PyObject* fg_rgba_obj, *bg_rgba_obj = NULL;
    Uint8 rgba[] = {0, 0, 0, 0};
    SDL_Surface* surf;
    SDL_Color foreg, backg;
    int just_return;

    if (!PyArg_ParseTuple(args, "OiO|O", &text, &aa, &fg_rgba_obj,
                          &bg_rgba_obj)) {
        return NULL;
    }

    if (!RGBAFromColorObj(fg_rgba_obj, rgba)) {
        return RAISE(PyExc_TypeError, "Invalid foreground RGBA argument");
    }
    foreg.r = rgba[0];
    foreg.g = rgba[1];
    foreg.b = rgba[2];
    foreg.unused = 0;
    if (bg_rgba_obj != NULL) {
        if (!RGBAFromColorObj(bg_rgba_obj, rgba)) {
            bg_rgba_obj = NULL;
            backg.r = 0;
            backg.g = 0;
            backg.b = 0;
            backg.unused = 0;
        }
        else
        {
            backg.r = rgba[0];
            backg.g = rgba[1];
            backg.b = rgba[2];
            backg.unused = 0;
        }
    }
    else {
        backg.r = 0;
        backg.g = 0;
        backg.b = 0;
        backg.unused = 0;
    }

    just_return = PyObject_Not(text);
    if (just_return) {
        int height = TTF_FontHeight(font);

        if (just_return == -1 ||
            !(PyUnicode_Check(text) || Bytes_Check(text) || text == Py_None)) {
            PyErr_Clear();
            return RAISE_TEXT_TYPE_ERROR();
        }
        surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, height, 32,
                                    0xff<<16, 0xff<<8, 0xff, 0);
        if (surf == NULL) {
            return RAISE(PyExc_SDLError, SDL_GetError());
        }
        if (bg_rgba_obj != NULL) {
            Uint32 c = SDL_MapRGB(surf->format, backg.r, backg.g, backg.b);
            SDL_FillRect(surf, NULL, c);
        }
        else {
            SDL_SetColorKey(surf, SDL_SRCCOLORKEY, 0);
        }
    }
    else if (PyUnicode_Check(text)) {
        PyObject *bytes = PyUnicode_AsEncodedString(text, "utf-8", "replace");
        const char *astring = NULL;

        if (!bytes) {
            return NULL;
        }
        astring = Bytes_AsString(bytes);
        if (strlen(astring) != Bytes_GET_SIZE(bytes)) {
            Py_DECREF(bytes);
            return RAISE(PyExc_ValueError,
                         "A null character was found in the text");
        }
        if (utf_8_needs_UCS_4(astring)) {
            Py_DECREF(bytes);
            return RAISE(PyExc_UnicodeError,
                         "A Unicode character above '\\uFFFF' was found;"
                         " not supported");
        }
        if (aa) {
            if (bg_rgba_obj == NULL) {
                surf = TTF_RenderUTF8_Blended(font, astring, foreg);
            }
            else {
                surf = TTF_RenderUTF8_Shaded(font, astring, foreg, backg);
            }
        }
        else {
            surf = TTF_RenderUTF8_Solid(font, astring, foreg);
        }
        Py_DECREF(bytes);
    }
    else if (Bytes_Check(text)) {
        const char *astring = Bytes_AsString(text);

        if (strlen(astring) != Bytes_GET_SIZE(text)) {
            return RAISE(PyExc_ValueError,
                         "A null character was found in the text");
        }
        if (aa) {
            if (bg_rgba_obj == NULL) {
                surf = TTF_RenderText_Blended(font, astring, foreg);
            }
            else {
                surf = TTF_RenderText_Shaded(font, astring, foreg, backg);
            }
        }
        else {
            surf = TTF_RenderText_Solid(font, astring, foreg);
        }
    }
    else {
        return RAISE_TEXT_TYPE_ERROR();
    }
    if (surf == NULL) {
        return RAISE(PyExc_SDLError, TTF_GetError());
    }
    if (!aa && (bg_rgba_obj != NULL) && !just_return) {
        /* turn off transparancy */
        SDL_SetColorKey(surf, 0, 0);
        surf->format->palette->colors[0].r = backg.r;
        surf->format->palette->colors[0].g = backg.g;
        surf->format->palette->colors[0].b = backg.b;
    }
    final = PySurface_New(surf);
示例#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;
}
示例#20
0
文件: text.cpp 项目: ALEXLCC/pyland
// WARNING:
//      This function contains an unusual amount of raw pointers, and is
//      the most C-like function you can get without being C++.
//      Sorry Joshua.
void Text::render() {
    int width = this->width;
    int height = this->height;
    std::pair<int,int> window_size = window->get_window_size();
    // Automatic sizing if dimension is 0.
    if (width == 0) {
        switch (alignment_h) {
        default:
        case Alignment::LEFT:
            width = window_size.first - this->x;
            break;
        case Alignment::CENTRE:
            width = ((window_size.first / 2) < this->x) ? this->x
                                                        : window_size.first - this->x;
            break;
        case Alignment::RIGHT:
            width = this->x;
            break;
        }
    }
    if (height == 0) {
        switch (alignment_v) {
        default:
        case Alignment::TOP:
            height = this->y;
            break;
        case Alignment::CENTRE:
            height = ((window_size.second / 2) < this->y) ? window_size.second - this->y
                                                          : this->y;
            break;
        case Alignment::BOTTOM:
            height = window_size.second - this->y;
            break;
        }
    }

    // If they are still zero, don't continue.
    if (width == 0 || height == 0) {
        throw Text::RenderException("Invalid dimensions after auto-sizing.");
    }

    int available_width = width;
    // It took a whole day to discover that there was a bug in
    // SDL_ttf. Starting with certain characters on certain
    // fonts seems to break it. :(
    // As a hack, prepend and (for balance) append a space.
    int border;
    TTF_SizeUTF8(font.font, " ", &border, NULL);
    border *= 2;

    // If they are still zero, don't continue.
    if (available_width <= 0) {
        throw Text::RenderException("No available width for rendering text.");
    }

    int line_height = TTF_FontHeight(font.font);
    int line_number = 0;
    int lost_lines = 0;

    int used_width = 0;

    int length = (int)text.length();
    // Entire text.
    const char* ctext = text.c_str();

    // Line of text.
    char* line = new char[length+1];

    // Null-terminator separated lines of text.
    // The worst case is a character per line, so we need to do
    // 2 * length (character, null, character, null, ...).
    char* lines = new char[2*length+1];
    // Pointer to within lines.
    char* lines_scan = lines;

    // Text indexing.
    for (int t = 0; t < length; t++) {
        int line_width = 0;
        // Word indexing.
        int w = 0;
        // Stores (from the beginning) a word in ctext (copy).
        line[0] = '\0';
        // Points to the end of the last successfully fitting word in
        // line.
        int ll = 0;

        // Line indexing.
        for (int l = t; l < length; l++) {
            // Find word end.
            for (w = l; w < length && (ctext[w] != ' ' && ctext[w] != '\n'); w++) {
                // As we are dealing with UTF-8, we must make sure to
                // copy an entire character if it is more than one byte.
                // The bit formats of UTF-8 characters are:
                // 0xxxxxxx
                // 110xxxxx 10xxxxxx
                // 1110xxxx 10xxxxxx 10xxxxxx
                // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
                // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
                // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
                //
                // ... Well, actually it's not THAT simple, because
                // there are these magical characters which modify other
                // characters... But it's not worth the effort.
                if (ctext[l] & 0x80) {
                    // The number of bits in the first byte set to 1
                    // before the first zero indicate the total number
                    // of bytes to use for the UTF-8 character.
                    for (int bits = ctext[w] << 1; w < length && (bits & 0x80); w++, bits <<= 1);
                }
            }
            // Copy word into line.
            for (; l < w; l++) {
                line[l - t] = ctext[l];
            }
            line[l - t] = '\0';
            // Test line length.
            TTF_SizeUTF8(font.font, line, &line_width, NULL);
            // Part of SDL_ttf bug workaround.
            line_width+=border;
            if (line_width <= available_width) {
                if (line_width > used_width) {
                    used_width = line_width;
                }
                // Mark current position as valid.
                ll = l - t;
                // If this is the end of a line, or whole text, stop.
                if (ctext[w] == '\n' || ctext[w] == '\0') {
                    t = l;
                    // Note the string is already null terminated.
                    break;
                }
                else {
                    // Replace null terminator with word separator.
                    line[ll] = ctext[w];
                }
            }
            else {
                if (ll > 0) {
                    // There are some fittable words.
                    // As the line overflows with the current l, set the
                    // text index to the last fit.
                    t += ll;
                }
                else {
                    // There are no separators to break on.
                    // We're going to have to cut a word in half.

                    // Swapped-out character
                    char c;
                    int left = 0;
                    int right = l - t;
                    // Search index within line.
                    int ls;
                    ll = 0;
                    for (ls = (right + left) / 2; ls != ll; ls = (right + left) / 2) {
                        ll = ls;
                        c = line[ls];
                        line[ls] = 0;
                        TTF_SizeUTF8(font.font, line, &line_width, NULL);
                        // Part of SDL_ttf bug workaround.
                        line_width+=border;
                        if (line_width <= available_width) {
                            if (line_width > used_width) {
                                used_width = line_width;
                            }
                            left = ls;
                        }
                        else {
                            right = ls;
                        }
                        line[ls] = c;
                    }
                    // Don't skip the non-separating character.
                    t += ll - 1;
                }
                // Null terminate for rendering.
                line[ll] = '\0';
                break;
            }
        }

        // Copy the line into lines (using lines_scan).
        int i;
        for (i = 0; line[i] != '\0'; ++i) {
            lines_scan[i] = line[i];
        }
        lines_scan[i] = '\0';
        lines_scan = &lines_scan[i+1];

        ++line_number;
        if (line[0] == '\0') {
            // Check that we aren't going to chase our tailes trying to fit an unfittable character.
            if (ctext[w] != '\n') {
                LOG(WARNING) << "Cannot render text: character too large.";
                delete[] line;
                delete[] lines;
                throw Text::RenderException("A character is too large");
            }
            else {
                // It's a blank line.
                continue;
            }
        }
    }
    int line_count = line_number;

    int used_height = line_count * line_height;

    used_width += border;

    image = Image(used_width, (used_height < height) ? used_height : height, true);
    uint8_t clear_colour[4] = {rgba[0], rgba[1], rgba[2], 0x00};
    uint8_t clear_mask[4] = {0xff, 0xff, 0xff, 0xff};
    image.clear(clear_colour, clear_mask);
    // image.clear(0xffffff00, 0xffffffff);

    // Render all lines of text.
    SDL_Color blank;
    blank.r = blank.g = blank.b = blank.a = 0;
    SDL_Color colour;
    colour.r = rgba[0];
    colour.g = rgba[1];
    colour.b = rgba[2];
    colour.a = rgba[3];
    lines_scan = lines;
    for (int line_number = 0; line_number < line_count; ++line_number) {
        // Render line
        VLOG(2) << "Rendering line of text: \"" << lines_scan << "\".";
        if (lines_scan[0] == '\0') {
            // Skip it - it's a new line.
            lines_scan = &lines_scan[1];
            continue;
        }

        SDL_Surface* rendered_line;
        {
            // It took a whole day to discover that there was a bug in
            // SDL_ttf. Starting with certain characters on certain
            // fonts seems to break it. :(
            // As a hack, prepend and (for balance) append a space.
            std::stringstream safe;
            safe << " " << lines_scan << " ";
            std::string safe_str(safe.str());
            if (smooth) {
                rendered_line = TTF_RenderUTF8_Shaded(font.font, safe_str.c_str(), colour, blank);
            }
            else {
                rendered_line = TTF_RenderUTF8_Solid(font.font, safe_str.c_str(), colour);
            }
        }

        if (rendered_line == nullptr) {
            LOG(WARNING) << "Cannot render line of text: \"" << lines_scan << "\".";
            delete[] line;
            delete[] lines;
            throw Text::RenderException("Cannot render line of text");
        }

#ifdef TEXT_SAFE_SURFACE
        // This surface has a known format.
        SDL_Surface* compatible = SDL_CreateRGBSurface(0, // Unsed
                                                       rendered_line->w,
                                                       rendered_line->h,
                                                       32,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0xff
                                                       );
        SDL_FillRect(compatible, NULL, 0);
        SDL_SetSurfaceBlendMode(rendered_line, SDL_BLENDMODE_NONE);
        SDL_BlitSurface(rendered_line, NULL, compatible, NULL);
        SDL_LockSurface(compatible);
        // pitch is in bytes, not pixels. RGBA = 4 bytes.
        int jump = compatible->pitch / 4;
#else
        SDL_LockSurface(rendered_line);
        int jump = rendered_line->pitch;
#endif
        // "What is this pointless copy?" you might ask.
        //   Well, it is a suggestion to the c++ compiler that smooth
        //   will not change throughout this function, so it can
        //   optimise the if containing _smooth out of the for loop
        //   entirely, rather than checking it every single iteration.
        int _smooth = smooth;
        int x_offset;
        int y_offset;
        switch (alignment_h) {
        default:
        case Alignment::LEFT:
            x_offset = 0;
            break;
        case Alignment::CENTRE:
            x_offset = (used_width - rendered_line->w) / 2;
            break;
        case Alignment::RIGHT:
            x_offset = used_width - rendered_line->w;
            break;
        }
        switch (alignment_v) {
        default:
        case Alignment::TOP:
            y_offset = line_number * line_height;
            break;
        case Alignment::CENTRE:
            y_offset = line_number * line_height - (used_height - image.height) / 2;
            break;
        case Alignment::BOTTOM:
            y_offset = line_number * line_height - (used_height - image.height);
            break;
        }
        // x surface
        int xs;
        // y surface
        int ys;
        for (ys = 0; ys < rendered_line->h; ++ys) {
            int yi = ys + y_offset;
            if (yi >= image.height) {
                lost_lines++;
                break;
            }
            else if (yi < 0) {
                continue;
            }
            int begin_xs((x_offset >= 0) ? 0 : -x_offset);
            int end_xs((rendered_line->w < image.width - x_offset) ? rendered_line->w : image.width - x_offset);
            for (xs = begin_xs; xs < end_xs; ++xs) {
#ifdef TEXT_SAFE_SURFACE
                image.flipped_pixels[yi][xs + x_offset].a = (((Uint32*)compatible->pixels)[(ys*jump + xs)]);
#else
                if (_smooth) {
                    image.flipped_pixels[yi][xs + x_offset].a = (((Uint8*)rendered_line->pixels)[(ys*jump + xs)]);
                }
                else {
                    image.flipped_pixels[yi][xs + x_offset].a = (((Uint8*)rendered_line->pixels)[(ys*jump + xs)]) ? 255 : 0;
                }
#endif
            }
        }
#ifdef TEXT_SAFE_SURFACE
        SDL_UnlockSurface(compatible);
        SDL_FreeSurface(compatible);
#else
        SDL_UnlockSurface(rendered_line);
#endif
        SDL_FreeSurface(rendered_line);
        if (ys < line_height) {
            LOG(WARNING) << "Text overflow.";
            break;
        }

        // Set lines_scan to start next line
        while (lines_scan[0] != '\0') {
            lines_scan = &lines_scan[1];
        }
        lines_scan = &lines_scan[1];
    }

    this->used_width  = used_width;
    this->used_height = used_height;
    delete[] line;
    delete[] lines;
    generate_texture();
    dirty_texture = false;
    dirty_vbo = true;
}
示例#21
0
SDL_Surface* SimKit::TTFVFont::render_font(const std::string txt, const SDL_Color textcol, const SDL_Color bg) {
    return TTF_RenderUTF8_Shaded(this->rfont, txt.c_str(), textcol, bg);
};