彩色屏显示点阵字库(2016年9月工作)

//===========================

// 头文件

//==========================

#ifndef __FONT_H__
#define __FONT_H__
#include "wbtypes.h"
#include "GUI.H"

#define BIT7_MASK       0x80
#define BIT6_MASK       0x40
#define BIT5_MASK       0x20
#define BIT4_MASK       0x10
#define BIT3_MASK       0x08
#define BIT2_MASK       0x04
#define BIT1_MASK       0x02
#define BIT0_MASK       0x01

typedef enum                //字库编号定义
{
    USER_LIB_ID_BASE = 0,      
    STD_LIB_ASCII_8_8 = 0X40,//标准字库起始
    STD_LIB_GBK_12_12,
    STD_LIB_ASCII_12_12,
    STD_LIB_GBK_16_16,
    STD_LIB_ASCII_16_16,
    STD_LIB_GB2312_24_24,
    STD_LIB_ASCII_24_24,
    STD_LIB_GB2312_32_32,
    STD_LIB_ASCII_32_32,
    LIB_ID_MAX              //字库总数
} LIB_ID;

#define STD_LIB_START                   (USER_LIB_ID_BASE)     //标准字库id起始
#define STD_LIB_END                     (STD_LIB_ASCII_32_32)  //标准字库id结束

#define USER_DEFINE_LIB_START           1                       //用户自定义字库id起始号
#define USER_DEFINE_LIB_END             (STD_LIB_ASCII_8_8 - 1) //用户自定义字库id结束号


typedef enum                  //编码方式
{
    ENCODE_UNICODE = 0,       //UNICODE 编码
    ENCODE_GB2312,            //GB2312 编码
    ENCODE_GBK,               //GBK 编码
    ENCODE_MAX             
} ENCODE_MODE;

#define OPEN_LIB_MAX        8

typedef struct LIB_FD_S{
   // UINT8 open_cont;
    UINT8 opend_index;
    INT32 opend_id[OPEN_LIB_MAX];//已打开的 lib_id
    INT32 fd[LIB_ID_MAX];       //文件句柄集
}LIB_FD;


typedef struct FONT_ATTR_S
{
    UINT8  lib_id;          //字库ID
    UINT8  lib_type;        //标准字库 或 自定义字库
    UINT8  EncodeMode;      //编码方式
    UINT8  width;           //字体宽度
    UINT8  height;          //字体高度
    UINT8  bg_flag;         //背景色标志
    UINT8  half_width;      //半角标志 
    UINT16 x_pos;           //x轴坐标
    UINT16 y_pos;           //y轴坐标
    UINT16 front_color;    //前景色RGB565
    UINT16 bg_color;       //背景色RGB565
   
}FONT_ATTR;

 
#define ERR_PARAM           0x0020      //参数错误
#define FULL_WIDTH               0      //全角
#define HALF_WIDTH               1      //半角

#define STANDARD_LIB            1
#define USERDEF_LIB             2


void DrawFont(USHORT code,FONT_ATTR *font);
void DrawSting(UINT8 *pBuf,USHORT strlen,FONT_ATTR *str);

void init_lib_fd(void);

INT LIB_GBK_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen);
INT LIB_GB2312_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen);
INT LIB_Unicode_ReadData(USHORT Code, FONT_ATTR *font, UINT8 *pResult, INT32 *piLen);

#endif

 

//======================

// font.c

//======================

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "font.h"
#include "nvtfat.h"
#include "config.h"

const UINT8 bit_mask[8] =
{
    BIT7_MASK,
    BIT6_MASK,
    BIT5_MASK,
    BIT4_MASK,
    BIT3_MASK,
    BIT2_MASK,
    BIT1_MASK,
    BIT0_MASK
};

LIB_FD libfd;  //句柄集

void init_lib_fd(void)
{
    int i =0 ;
 
    libfd.opend_index = 0;
   
    for(i = 0; i< OPEN_LIB_MAX ;i++)
    {
      libfd.opend_id[i]  = -1;
    }

    for(i = 0; i < LIB_ID_MAX ;i ++)
    {
       libfd.fd[i] = -1;
    }
}

/*
*从GBK 字库中读点阵数据
*/
INT LIB_GBK_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen)
{
   
    UINT8 SectionCode;
    UINT8 LocalCode;
    INT32 lib_id;
    INT32 lib_id1;
    INT64 OffsetAddr;
    UINT iFontSize;
    UINT ret;

    char path[64],temp_path[64];
    int fd = -1;
    

    LocalCode = Code & 0xFF;
    SectionCode = Code >> 8;

    if((font->width % 8) != 0)
    {
        iFontSize = ((font->width/8)+1) * font->height;
    }
    else
    {
        iFontSize = (font->width/8) * font->height;
    }
   
    //
    if(SectionCode > 0x81 )
    {

        lib_id = font->lib_id;
        sprintf(temp_path,"d:\\GBK_%d_%d_%d.dzk",font->lib_id,font->width,font->height); 

        if(LocalCode > 0x80)
        {
            OffsetAddr = ((SectionCode - 0x81) * 190 + (LocalCode - 0x41)) * iFontSize;
        }
        else
        {
            OffsetAddr = ((SectionCode - 0x81) * 190 + (LocalCode - 0x40)) * iFontSize;
        }
    }
    else
    {
       lib_id = font->lib_id + 1;
       sprintf(temp_path,"d:\\ASCII_%d_%d_%d.dzk",lib_id,font->width,font->height); 
       OffsetAddr = LocalCode * iFontSize;
    }
   
    fd = libfd.fd[lib_id];
   
    if(fd < 0)
    {
      if(libfd.opend_id[libfd.opend_index] != -1 )
        {
            lib_id1 = libfd.opend_id[libfd.opend_index];
            fsCloseFile(libfd.fd[lib_id1]);//关掉 已打开的 lib
            libfd.opend_id[libfd.opend_index] = -1;
            libfd.fd[lib_id1] = -1;
            PRINT_LOG("close %d lib !!!\n",lib_id1);
        }
   
      fsAsciiToUnicode(temp_path, path, TRUE);
      fd = fsOpenFile(path, 0, O_RDONLY);
      if(fd < 0)
        {
            PRINT_LOG("font file %s open fail\n",temp_path);
            return ERR_NO_FILE;
        }
      PRINT_LOG("font file %s open ok\n",temp_path);
     
      libfd.opend_id[libfd.opend_index] = lib_id;
      libfd.fd[lib_id] = fd;
      libfd.opend_index = (libfd.opend_index + 1) % OPEN_LIB_MAX; 
    }
   
    fsFileSeek(fd, OffsetAddr,SEEK_SET); 
    ret = fsReadFile(fd, pResult, iFontSize,piLen);
    ret = ERR_NULL;
    return ret;
}

/*
*从GB2312 字库中读点阵数据
*/
INT LIB_GB2312_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen)
{
   
    UINT8 SectionCode;
    UINT8 LocalCode; 
    INT64 OffsetAddr;
    UINT iFontSize;
    UINT ret;
    INT32 lib_id;
    INT32 lib_id1;

    char path[64],temp_path[64];
    int fd = -1;

    LocalCode = Code & 0xFF;
    SectionCode = Code >> 8;

    if((font->width % 8) != 0)
    {
        iFontSize = ((font->width/8)+1) * font->height;
    }
    else
    {
        iFontSize = (font->width/8) * font->height;
    }
   
    //
    if(SectionCode > 0xA1 )
    {
    
       lib_id = font->lib_id;    
       sprintf(temp_path,"d:\\GB2312_%d_%d_%d.dzk",lib_id,font->width,font->height);
       OffsetAddr = ((SectionCode - 0xA1) * 94 + (LocalCode - 0xA1)) * iFontSize;
    }
    else
    {
       lib_id = font->lib_id + 1;
       sprintf(temp_path,"d:\\ASCII_%d_%d_%d.dzk",lib_id,font->width,font->height);
       OffsetAddr = LocalCode * iFontSize;
    }

    fd = libfd.fd[lib_id];
   
    if(fd < 0)
    {
        if(libfd.opend_id[libfd.opend_index] != -1 )
        {
            lib_id1 = libfd.opend_id[libfd.opend_index];
            fsCloseFile(libfd.fd[lib_id1]);//关掉 已打开的 lib
           
            libfd.opend_id[libfd.opend_index] = -1;
            libfd.fd[lib_id1] = -1;
           
            PRINT_LOG("close %d lib !!!\n",lib_id1);
        }
       
   
        fsAsciiToUnicode(temp_path, path, TRUE);
        fd = fsOpenFile(path, 0, O_RDONLY);
        if(fd < 0)
        {
            PRINT_LOG("font file %s open fail\n",temp_path); 
            return ERR_NO_FILE;
        }
        PRINT_LOG("font file %s open OK\n",temp_path);
        libfd.opend_id[libfd.opend_index] = lib_id;
        libfd.fd[lib_id] = fd;
        libfd.opend_index = (libfd.opend_index + 1) % OPEN_LIB_MAX;    
    }

     
        fsFileSeek(fd, OffsetAddr,SEEK_SET);
        ret = fsReadFile(fd, pResult, iFontSize,piLen);
        ret = ERR_NULL;

    return ret;
}

/*
* 从Unicode 中读取数据
*/
INT LIB_Unicode_ReadData(USHORT Code, FONT_ATTR *font, UINT8 *pResult, INT32 *piLen)
{

    char path[64],temp_path[64];
    INT32 lib_id;
    int fd = -1;
    UINT iFontSize;
    INT64 OffsetAddr;
    INT ret;
   
    if((font->width % 8) != 0)
    {
        iFontSize = ((font->width/8)+1) * font->height;
    }
    else
    {
        iFontSize = (font->width/8) * font->height;
    }
   
    OffsetAddr = Code * iFontSize;

    fd = libfd.fd[font->lib_id];//lib_fd[font->lib_id];
   
    if(fd < 0)
    {
    // 最大能同时打开  OPEN_LIB_MAX 个字库 超过了 最大打开的 个数 就要关掉 最早打开的字库   
        if(libfd.opend_id[libfd.opend_index] != -1 )
        {
            lib_id = libfd.opend_id[libfd.opend_index];
            fsCloseFile(libfd.fd[lib_id]);//关掉 已打开的 lib
            libfd.opend_id[libfd.opend_index] = -1;
            libfd.fd[lib_id] = -1;
            PRINT_LOG("close %d lib !!!\n",lib_id);
        }

        sprintf(temp_path,"d:\\font%d_%d_%d.dzk",font->lib_id,font->width,font->height);
        fsAsciiToUnicode(temp_path, path, TRUE);
       
        fd = fsOpenFile(path, 0, O_RDONLY);
        if(fd < 0)
        {
            PRINT_LOG("font file %s open fail!!!\n",temp_path);
            return ERR_NO_FILE;
        }
        PRINT_LOG("open %d lib !!!\n",font->lib_id);
       
        libfd.opend_id[libfd.opend_index] = font->lib_id;
        libfd.fd[font->lib_id] = fd;
        libfd.opend_index = (libfd.opend_index + 1) % OPEN_LIB_MAX;

    }
   
    fsFileSeek(fd, OffsetAddr,SEEK_SET);
    ret = fsReadFile(fd, pResult, iFontSize,piLen);
   
    ret = ERR_NULL;
   
    return ret;
}

/*
*从将字库中的取出的点阵数据描点到显示bUF
*/
INT (*pfontlib_read[3])(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen) =
{
    LIB_Unicode_ReadData,
    LIB_GB2312_ReadData,
    LIB_GBK_ReadData
};

UINT8  dot_buf[64*48];
UINT16 dot_clolor[2] = {COLOR_BLACK,COLOR_WHITE};// {背景色,前景色}

void DrawFont(USHORT code,FONT_ATTR *font)
{
    UINT8 active_width;
    UINT8 active_height;
    INT32   rDotLen;
    //UINT32  DotLen = 0;
    UINT32  i = 0,j = 0;
    UINT8   offset;
    UINT8  *pDotBuf = NULL;
    UINT8  *tempBuf = NULL;
    USHORT *targetBuf = NULL;
   
    INT32  ret;

    if((font->x_pos > PANEL_WIDTH)||(font->y_pos > PANEL_HEIGHT))
    {
        return ;
    }

    if((font->width % 8) != 0)//横向取模
    {
        offset = (( font->width / 8) + 1 );
    }
    else
    {
        offset = ( font->width / 8) ;
    }

    active_width  = font->width;
    active_height = font->height;
   
    tempBuf = dot_buf;
   
    if(tempBuf < 0)
    {
        ret = ERR_MALLOC_FAIL;
        PRINT_LOG("errno:%d \n",ret);
        return ;
    }

    if(font->EncodeMode >= ENCODE_MAX)
    {
        PRINT_LOG("please choose an encode mode!!!\n");
        return;
    }
    ret = pfontlib_read[font->EncodeMode](code, font, tempBuf, &rDotLen);
    
    if(ret != ERR_NULL)
    {
        PRINT_LOG("read lib error:%d \n",ret);
        return ;
    }
   
   //获取显示缓存
    targetBuf = (USHORT *)get_ready_buf();
    targetBuf += (font->y_pos * PANEL_WIDTH +font->x_pos);
   
    active_width = font->half_width ? (active_width/2) : active_width;
   
    pDotBuf = tempBuf;
   
    //待显示区域超出 屏部分 丢弃
    if((font->x_pos + active_width) > PANEL_WIDTH )
        active_width = PANEL_WIDTH - font->x_pos;
    if((font->y_pos + active_height) > PANEL_HEIGHT)
        active_height = PANEL_HEIGHT - font->y_pos;

    if(font->bg_flag == 1)
    {
        for (i = 0; i < active_height; i++)
        {
            for (j = 0; j < active_width; j++)
            {
                if(*(pDotBuf+ (j/8)) & bit_mask[j % 8])
                 {
                    *(targetBuf+j)  = font->front_color;
                 }
                 else
                 {
                    *(targetBuf+j)  = font->bg_color;
                 }
            }
            targetBuf += PANEL_WIDTH;
            pDotBuf += offset;
        }
    }
    else
    {
         for (i = 0; i < active_height; i++)
        {
            for (j = 0; j < active_width; j++)
            {
                if(*(pDotBuf+ (j/8)) & bit_mask[j % 8])
                 {
                    *(targetBuf+j)  = font->front_color;
                 }
            }
            targetBuf += PANEL_WIDTH;
            pDotBuf += offset;
        }
    }
    tempBuf = NULL;
}
extern UINT8 frameBuf_lock;
//显示字符串
void DrawSting(UINT8 *pBuf,USHORT strlen,FONT_ATTR *str)
{
 
    UINT32 i = 0;
    UINT16 code;
    FONT_ATTR font_attr;

    if((pBuf == NULL)||(strlen <=0 ))
    {
        sysprintf("DrawSting  len error!!!\n");
        frameBuf_lock = 0;
        return ;
    }
   
    memcpy(&font_attr,str,sizeof(FONT_ATTR));
   
    for( i = 0 ; i< strlen ; i++)
    {
        code = *pBuf++; 
       if((font_attr.EncodeMode == ENCODE_GB2312)||(font_attr.EncodeMode == ENCODE_GBK))
        {
            if( code > 0X80)//区分 汉字 和  ASCII
            {
                if(i < (strlen -1))
                {
                  code <<= 8;
                  code  += *pBuf++;
                  i++;
                }
                else
                {
                    break;
                }
             font_attr.half_width = FULL_WIDTH;//全角显示
             DrawFont(code,(FONT_ATTR * )&font_attr);       
             font_attr.x_pos += font_attr.width ;
            }
            else
            {
             font_attr.half_width = HALF_WIDTH;//半角显示
             DrawFont(code,(FONT_ATTR * )&font_attr);       
             font_attr.x_pos += ((font_attr.width )/2);
            }
        }
        else
        {
            code <<= 8;
            code  += *pBuf++;
            i++;
            font_attr.half_width = FULL_WIDTH;
            DrawFont(code,(FONT_ATTR * )&font_attr);
            font_attr.x_pos += (font_attr.width );
        }
    }
 frameBuf_lock = 0;
   
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值