Directfb 的DrawString其實支持中文顯示,不過只支持utf-8編碼,所以主要的問題就是讓
把我們常用的gb2312編碼轉換成utf-8編碼。其實是有現成的函數可以轉換的,只是庫比
較大,所以還是自己實現吧。
首先得把gb2312轉換成Unicode,然后再把Unicode轉換成utf-8。gb2312轉換成Unicode
比較容易,windows下有個函數MultiByteToWideChar可以實現,我們可以利用這個函數
生成一個數組,以后用的時候直接查表就可以了。下邊是生成表的代碼。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main()
{
wchar_t wstr[8] = {0};
FILE *fp;
unsigned char rowCode,colCode;
char szStr[64] = {0};
char szBuff[2] = {0};
unsigned char row;
unsigned char col;
fp = fopen("GB2Uni_LUT.h", "w+, ccs=UNICODE");
if(fp)
{
strcpy( szStr, "unsigned short Unicode[87][94]={\n");
fwrite(szStr,1,strlen(szStr),fp);
for(row = 0; row < 87; row++)
{
for(col = 0; col < 94; col++)
{
rowCode = row + 0xA1;
colCode = col + 0xA1;
szBuff[0] = rowCode;
szBuff[1] = colCode;
if( MultiByteToWideChar(CP_THREAD_ACP,MB_ERR_INVALID_CHARS,szBuff,2,wstr,8))
{
sprintf(szStr,"0x%04X,",wstr[0]);
fwrite(szStr,1,strlen(szStr),fp);
}
else
{
fwrite( "0x0000,", 1, 13, fp );
}
}
fwrite( "\n", 1, 1, fp );
}
strcpy( szStr, "};\n");
fwrite( szStr, 1, strlen( szStr ), fp );
fclose(fp);
}
return 0;
}
然后就可以考慮Unicode轉換成utf-8了,理解起來比較麻煩,代碼實現比較簡單,
原理參照另一篇日志Unicode,UTF8等編碼規范[轉]。
下面是gb2312轉utf-8的代碼實現。
int GB2UTF_8(char *p_desStr, char *p_srcStr)
{
int x ,y;
short s_Temp = 0;
char chighChar = 0;
char clowChar = 0;
assert(p_srcStr);
assert(p_desStr);
while ('\0' != *p_srcStr)
{
if(((unsigned char)*(p_srcStr))>=0xA0)
{
//gb2312轉unicode
chighChar = *p_srcStr-0xA1;//大端序
clowChar = *(p_srcStr+1)-0xA1;//
x = (int)chighChar;
y = (int)clowChar;
s_Temp = Unicode[x][y];//取unicode編碼
//unicode轉utf-8
chighChar = (0xff00&s_Temp)>>8;
clowChar = (0x00ff&s_Temp);
char cTemp[3];
cTemp[0] = 0xE0 | ((0xF0 & chighChar)>>4);
cTemp[1] = 0x80 | (((0x0F & chighChar)<<2) | ((0xC0 & clowChar)>>6));
cTemp[2] = 0x80 | (0x3F & clowChar);
memcpy(p_desStr,cTemp,sizeof(cTemp));
p_desStr += 3;
p_srcStr += 2;
}
else
{
memcpy(p_desStr, p_srcStr, 1);
p_srcStr += 1;
p_desStr += 1;
}
}
return 0;
}
其中Unicode這個數組就是利用最上面的程序生成的。
下面是directfb顯示的例子。是在Linux下運行的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <directfb.h>
#include <assert.h>
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static IDirectFBFont *pFont = NULL;
static int screen_width = 0;
static int screen_height = 0;
#define DFBCHECK(x...) \
{ \
DFBResult err = x; \
\
if (err != DFB_OK) \
{ \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
}
int main (int argc, char **argv)
{
DFBSurfaceDescription dsc;
DFBFontDescription font_dsc;
char *TmpString = NULL;
DFBCHECK (DirectFBInit (&argc, &argv));
DFBCHECK (DirectFBCreate (&dfb));
DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
dsc.flags = DSDESC_CAPS;
dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));
DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width, screen_height));
DFBCHECK (primary->SetColor (primary, 0x80, 0x80, 0xff, 0xff));
//DFBCHECK (primary->FillRectangle (primary,
// 0, screen_height / 2,
// screen_width - 1, screen_height / 6));
font_dsc.flags = DFDESC_ATTRIBUTES|DFDESC_HEIGHT|DFDESC_WIDTH;
font_dsc.width = 32;
font_dsc.height = 32;
DFBCHECK (dfb->CreateFont (dfb, \
"/work/font.TTF", \
&font_dsc, \
&pFont));
primary->SetColor (primary, 0x80, 0x80, 0xff, 0xff);
primary->SetFont (primary, pFont);
char SrcString[] = "協助李嚴鎮守白帝,《三國志》稱“征南\n(趙云)厚重";
TmpString = (char *)calloc(1, strlen(SrcString)*2);
GB2UTF_8(TmpString, SrcString);
DFBCHECK(primary->DrawString (primary,
TmpString, -1,
100, screen_height / 2, DSTF_LEFT));
free(TmpString);
DFBCHECK (primary->Flip (primary, NULL, 0));
//pFont->Release (pFont);
sleep (3);
primary->Release( primary );
dfb->Release( dfb );
return 23;
}
生成表和轉的代碼是在網上找來的,做了一點修改,directfb例子是在官網例子上做的修改。
|