修改SDL_ttf,支持动态设置字体大小

时间:2021-05-11 00:52:07

        最近有个项目使用到SDL_ttf库来渲染字体,但是遇到一点麻烦。大家在使用TTF_OpenFont()打开字体库之后,却无法更改字体大小,我们总不能关闭重新打开吧,因为那也太耗时了。于是乎决定修改源码,成功之后与大家分享。

1.SDL_ttf.h中添加函数extern DECLSPEC void SDLCALL TTF_SetFontSize(TTF_Font *font,int ptsize);

2.修改SDL_ttf.c

    SDL_ttf使用的是freetype来加载字体库,然后再使用freetype获取字体编码绘制字体到SDL_Surface上。最初实验总是不成功,结果大量的实验,原来是没有清除font导致不正确;加上Flush_Cache(font),成功搞定。

void TTF_SetFontSize(TTF_Font *font,int ptsize)
{
	FT_Fixed scale;
	FT_Error error;
	FT_Face face;
	
	face = font->face;
	
	/* Make sure that our font face is scalable (global metrics) */
	if ( FT_IS_SCALABLE(face) ) {

	  	/* Set the character size and use default DPI (72) */
	  	error = FT_Set_Char_Size( font->face, 0, ptsize * 64, 0, 0 );
			if( error ) {
	    	TTF_SetFTError( "Couldn't set font size", error );
	    	TTF_CloseFont( font );
	    	return ;
	  }

	  /* Get the scalable font metrics for this font */
	  scale = face->size->metrics.y_scale;
	  font->ascent  = FT_CEIL(FT_MulFix(face->ascender, scale));
	  font->descent = FT_CEIL(FT_MulFix(face->descender, scale));
	  font->height  = font->ascent - font->descent + /* baseline */ 1;
	  font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
	  font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
	  font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));
	  
	} else {
		/* Non-scalable font case.  ptsize determines which family
		 * or series of fonts to grab from the non-scalable format.
		 * It is not the point size of the font.
		 * */
		if ( ptsize >= font->face->num_fixed_sizes )
			ptsize = font->face->num_fixed_sizes - 1;
		font->font_size_family = ptsize;
		error = FT_Set_Pixel_Sizes( face,
				face->available_sizes[ptsize].height,
				face->available_sizes[ptsize].width );
	  	/* With non-scalale fonts, Freetype2 likes to fill many of the
		 * font metrics with the value of 0.  The size of the
		 * non-scalable fonts must be determined differently
		 * or sometimes cannot be determined.
		 * */
	  	font->ascent = face->available_sizes[ptsize].height;
	  	font->descent = 0;
	  	font->height = face->available_sizes[ptsize].height;
	  	font->lineskip = FT_CEIL(font->ascent);
	  	font->underline_offset = FT_FLOOR(face->underline_position);
	  	font->underline_height = FT_FLOOR(face->underline_thickness);
	}

	if ( font->underline_height < 1 ) {
		font->underline_height = 1;
	}

	font->glyph_italics *= font->height;
	
	Flush_Cache(font); //这个非常重要
}