找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2057|回复: 0
收起左侧

Directfb中文显示

[复制链接]
ID:107189 发表于 2016-3-6 15:13 | 显示全部楼层 |阅读模式
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例子是在官网例子上做的修改。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表