khmer的显示实现_1

Posted alen_xie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了khmer的显示实现_1相关的知识,希望对你有一定的参考价值。

由于工作的需要,分配添加支持khmer,痛苦的煎熬了一个月,终于把它给整出来了,方便以后大家开发中提供一点点的帮助。

本次的开发主要采用开源的代码来实现的。采用了两种:harfbuzz跟freetype。

首先:介绍一下harfbuzz的基础知识:

Harfbuzz 是一个开源的text opentype layout 引擎,它被应用于很多的开源项目中,如Pango,Filefox,Webkit,android等。

可以参考:http://my.oschina.net/wolfcs/blog/107635 ,文档的介绍,我们就不必详细的介绍了。

本次中主要是通过harfbuzz 获取到glyph id,获取到这个值。因时间比较紧张,暂时采用demo上的某些例子参考,并进行相应的修改。然后获取到glyph id后,再通过freetype获取到所需要字符的信息,其实获取的这个字符image的信息,然后调用显示的函数进行显示出来。

代码如下:

int GetKhmerStringInfo(int iLan, unsigned char *pucBuf, int iBufWidth, int iBufHeight, int iX, int iY, \\
		char *pcShowString, unsigned int uiFrontColor, int iXTimes, int iYTimes)

	int iPenPos = 0;
	int iFontMaxHeight = 0;
	int iDrawHeight = 0;
	unsigned int uiCount = 0;
	unsigned int iLoop = 0;
	const int FONT_MAX_SIZE = MaxFontSize();
	int bError = 0;
	hb_buffer_t *buffer;
	hb_glyph_info_t *infos;
	hb_glyph_position_t *positions;
	hb_glyph_info_t *info;
	hb_glyph_position_t *pos;
	GS_TT_BITMAP stBitmap;

	if (strlen(pcShowString) <= 0)
	
		return -1;
	
	iX = GetXPos(iX);
	iY = GetYPos(iY);
	iBufWidth = GetXPos(iBufWidth);
	iBufHeight = GetYPos(iBufHeight);
	iPenPos = iX;

	GetttfFileData();
	buffer = hb_buffer_create();
	hb_buffer_add_utf8(buffer, (const char *)pcShowString, -1, 0, -1);
	hb_buffer_guess_segment_properties(buffer);
	hb_shape(font, buffer, NULL, 0);
	uiCount = hb_buffer_get_length(buffer);
	infos = hb_buffer_get_glyph_infos(buffer, NULL);
	positions = hb_buffer_get_glyph_positions(buffer, NULL);
	stBitmap.pucBuffer = GSOS_Malloc(FONT_MAX_SIZE);
	if (NULL == stBitmap.pucBuffer)
	
		return 0;
	
	for (iLoop = 0; iLoop < uiCount; iLoop++)
	
		info = &infos[iLoop];
		pos = &positions[iLoop];
		bError = FT_Load_Glyph(stFTFace, info->codepoint, FT_LOAD_DEFAULT);
		if (stFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
		
			bError = FT_Render_Glyph(stFTFace->glyph, FT_RENDER_MODE_NORMAL);
		
		memset (stBitmap.pucBuffer, 0, FONT_MAX_SIZE);
		RenderGlyphInternal(&(stFTFace->glyph->outline), &stBitmap);
		if (iPenPos == iX && stBitmap.iLeft < 0)
		
			stBitmap.iLeft = 0;
		
#if HD_OSD || OSD_NAME == SUPER
		iDrawHeight = GetYPos(28 - iFontMaxHeight)/2;
#endif
		DrawFontBitmap(pucBuf, iBufWidth, iBufHeight, iPenPos + stBitmap.iLeft, \\
				iY+4 - stBitmap.iTop + iDrawHeight, &stBitmap, uiFrontColor);
		iPenPos += (stFTFace->glyph->metrics.horiAdvance >> 6)*iXTimes;
	
	hb_buffer_destroy(buffer);
	GSOS_Free(stBitmap.pucBuffer);
	return GetHD2SDXPos(iPenPos - iX);


因为freetype需要每次传入一个字符进入索引到对应的图形,获取到字符的等信息,因每次都需要malloc or read or create,使用一个全局的变量控制。

int GetttfFileData(void)

	if (iOpenFileOnlyOnce > 0)
	
		iOpenFileOnlyOnce--;
		FILE *fpttf;
		hb_blob_t *blob = NULL;
		hb_destroy_func_t destroy;
		unsigned int upem = 0;
		void *user_data = NULL;
		char *font_data = NULL;
		hb_memory_mode_t mm = HB_MEMORY_MODE_WRITABLE;

		fpttf = fopen(TTF_SAVE_FALSH_PATCH, "rb");
		if (NULL == fpttf)
		
			printf("open ttf file faild!, [%s, %d]\\r\\n", __FUNCTION__, __LINE__);
			return 0;
		
		fseek(fpttf, 0, SEEK_END);
		uifpLen = ftell(fpttf);
		fseek(fpttf, 0, SEEK_SET);
		if (NULL != font_data)
		
			GSOS_Free(font_data);
			font_data = NULL;
		
		font_data = GSOS_Malloc(uifpLen);
		uifpLen = fread(font_data, 1, uifpLen, fpttf);
		fclose(fpttf);
		user_data = (void *)font_data;
		blob = hb_blob_create((const char *)font_data, uifpLen, mm, user_data, destroy);
		face = hb_face_create(blob, 0);
		hb_blob_destroy(blob);
		blob = NULL;
		upem = hb_face_get_upem(face);
		font = hb_font_create(face);
		hb_font_set_scale(font, upem, upem);
		hb_ft_font_set_funcs(font);
		GetFreetypeFace(TTF_SAVE_FALSH_PATCH, KHMER_FONT_SIZE, &stFTFace);
	
	return uifpLen;


当切换到其他的语言时,就可以free掉了。

void FreeHarfbuzzMem(void)

	if (NULL != font)
	
		hb_font_destroy(font);
		font = NULL;
	
	if (face)
	
		hb_face_destroy(face);
		face = NULL;
	
	iOpenFileOnlyOnce = 1;

以下就是初始化freetype

static int GetFreetypeFace(char *ttf, int font_size, FT_Face *face)

	FT_Library library;

	if (font_size < 1 || font_size > 72)
	
		return -1;
	
	if (FT_Init_FreeType(&library) != 0)
	
		return -2;
	
	if (FT_New_Face(library, ttf, 0, face) != 0)
	
		return -3;
	
	FT_Set_Char_Size(*face, 0, font_size * 64, 96, 96);
	return 0;



至于一些定义,我就不提供了,可以参考其他,至于修改的lib后期再共享一下。


以上是关于khmer的显示实现_1的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的实现_遍历_重构_树形显示

1_Matlab实现图像显示及其代数操作

python-实现3级菜单(作业课)

iqkeyboardmanager 支持webview吗

Verilog实现二位十进制数字的显示

权限模块_使用权限_实现主页面的效果_显示左侧菜单&只显示有权限的菜单项