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;
以上是关于khmer的显示实现_1的主要内容,如果未能解决你的问题,请参考以下文章