在做一个用到ucGUI的项目的时候要用到不定的汉字和英文字符,但是ucGUI本身又不支持读取芯片外部flash的字库来显示,于是查了下资料,如下:

  http://www.cnblogs.com/hiker-blogs/archive/2013/01/04/2843538.html

  站在巨人的肩膀上,我找到了将汉字库写进flash后,通过ucGUI的控件显示出来的方法,但是至此,并不能在一个字符串里添加汉字和英文,用于同时显示,因为flash里面没有英文字符的模。

  为了让一个控件同时显示汉字和英文,我们还是将目标瞄准ucGUI_Core文件夹中的GUICharP.c文件:

将函数void GUIPROP_DispChar(U16P c)修改成:

void GUIPROP_DispChar(U16P c) {
  int BytesPerLine;
  U8 BytesPerFont;  //一个字的字节数
  U32 base,oft;     //字库的起始地址和偏移量
       
  GUI_DRAWMODE DrawMode = GUI_Context.TextMode;
  const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);
  if (pProp) {
    GUI_DRAWMODE OldDrawMode;
    const GUI_CHARINFO GUI_UNI_PTR * pCharInfo;
        //支持2种字体,flash空间有限,放不下第三种字体
    if((GUI_Context.pAFont == &GUI_FontHZ16)||(GUI_Context.pAFont == &GUI_FontHZ24)/*||(GUI_Context.pAFont == &GUI_FontHZ32)*/)
    {
        pCharInfo = pProp->paCharInfo;

base = (U32)pProp->paCharInfo->pData;
        BytesPerFont = GUI_Context.pAFont->YSize * pProp->paCharInfo->BytesPerLine; //每个字模的数据字节数
        if (BytesPerFont > BYTES_PER_FONT)//BYTES_PER_FONT是一个汉字所占最大字节数,我这里最大显示点阵24x24的汉字,所以BYTES_PER_FONT大小是3x24
        {
            BytesPerFont = BYTES_PER_FONT;
        }
        if (c < 0x80) //英文字符显示部分
        {
            const GUI_FONT *EnglishFont;//定义一个字库指针,方便以后操作
            if(GUI_Context.pAFont == &GUI_FontHZ16)//根据所用字库来给EnglishFont赋值,因为flash里面没有英文字符模,于是用ucGUI自带的
                EnglishFont=&GUI_Font16_ASCII;
            else
                EnglishFont=&GUI_Font24_ASCII;
            //BytesPerLine = GUI_Font24_ASCII.p.pProp->paCharInfo[c-0x20].BytesPerLine*GUI_Font24_ASCII.YSize;
            //在这里,BytesPerLine就是所要显示的字符的模位数,就是GUI_CHARINFO结构体的BytesPerLine
            BytesPerLine = EnglishFont->p.pProp->paCharInfo[c-0x20].BytesPerLine;
            OldDrawMode  = LCD_SetDrawMode(DrawMode);//写入新的模式,并保存旧的模式    
            //注:pCharInfo->  =  EnglishFont.p.pProp->paCharInfo[c-0x20].
            //    GUI_Context.pAFont->  =    当前字体,比如   EnglishFont.
            LCD_DrawBitmap( GUI_Context.DispPosX,
                            GUI_Context.DispPosY,
                            EnglishFont->p.pProp->paCharInfo[c-0x20].XSize,//GUI_CHARINFO的XSize,EnglishFont->p.pProp->paCharInfo[c-0x20]即相当于字库文件F16_ASCII.c中的GUI_CharInfo_Font16ASCII[c-0x20]
                            EnglishFont->YSize,//字库的参数
                            EnglishFont->XMag,
                            EnglishFont->YMag,
                            1,     /* Bits per Pixel */
                            BytesPerLine,
                            EnglishFont->p.pProp->paCharInfo[c-0x20].pData,
                            &LCD_BKCOLORINDEX
                          );
            /* Fill empty pixel lines */
            if (EnglishFont->YDist > EnglishFont->YSize) {  //用于字符对齐,删掉这里的if到return就可以指到效果了
              int YMag = EnglishFont->YMag;
              int YDist = EnglishFont->YDist * YMag;
              int YSize = EnglishFont->YSize * YMag;
              if (DrawMode != LCD_DRAWMODE_TRANS) {
                LCD_COLOR OldColor = GUI_GetColor();
                GUI_SetColor(GUI_GetBkColor());
                LCD_FillRect(GUI_Context.DispPosX,
                             GUI_Context.DispPosY + YSize,
                             GUI_Context.DispPosX + pCharInfo->XSize,
                             GUI_Context.DispPosY + YDist);
                GUI_SetColor(OldColor);
              }
            }
            LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */
            GUI_Context.DispPosX += EnglishFont->p.pProp->paCharInfo[c-0x20].XDist * EnglishFont->XMag;
            return;
        }
        else //中文字符地址偏移算法
        {
            oft = base + (((c>>8) - 0xa1) * 94 + ((c&0xff) - 0xa1)) * BytesPerFont;
            ucGUI_ReadFlashBit(oft, GUI_FontDataBuf, BytesPerFont);//取出字模数据

BytesPerLine = pCharInfo->BytesPerLine;
            OldDrawMode  = LCD_SetDrawMode(DrawMode);

LCD_DrawBitmap( GUI_Context.DispPosX,
                            GUI_Context.DispPosY,
                            pCharInfo->XSize,
                            GUI_Context.pAFont->YSize,
                            GUI_Context.pAFont->XMag,
                            GUI_Context.pAFont->YMag,
                            1,     /* Bits per Pixel */
                            BytesPerLine,
                            GUI_FontDataBuf,
                            &LCD_BKCOLORINDEX
                            );

}

}
        //--
    else
    {
        pCharInfo = pProp->paCharInfo+(c-pProp->First);
        BytesPerLine = pCharInfo->BytesPerLine;
        OldDrawMode  = LCD_SetDrawMode(DrawMode);       
        LCD_DrawBitmap( GUI_Context.DispPosX,
                        GUI_Context.DispPosY,
                        pCharInfo->XSize,
                        GUI_Context.pAFont->YSize,
                        GUI_Context.pAFont->XMag,
                        GUI_Context.pAFont->YMag,
                        1,     /* Bits per Pixel */
                        BytesPerLine,
                        pCharInfo->pData,
                        &LCD_BKCOLORINDEX
                        );
    }

/* Fill empty pixel lines */
    if (GUI_Context.pAFont->YDist > GUI_Context.pAFont->YSize) {
      int YMag = GUI_Context.pAFont->YMag;
      int YDist = GUI_Context.pAFont->YDist * YMag;
      int YSize = GUI_Context.pAFont->YSize * YMag;
      if (DrawMode != LCD_DRAWMODE_TRANS) {
        LCD_COLOR OldColor = GUI_GetColor();
        GUI_SetColor(GUI_GetBkColor());
        LCD_FillRect(GUI_Context.DispPosX,
                     GUI_Context.DispPosY + YSize,
                     GUI_Context.DispPosX + pCharInfo->XSize,
                     GUI_Context.DispPosY + YDist);
        GUI_SetColor(OldColor);
      }
    }
    LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */
    GUI_Context.DispPosX += pCharInfo->XDist * GUI_Context.pAFont->XMag;
  }
}

void GUIPROP_DispChar(U16P c)函数只是用来显示数据的,为了让数据显示在控件中间,还要修改int GUIPROP_GetCharDistX(U16P c)为:

int GUIPROP_GetCharDistX(U16P c) {
 if(c<0x80)//是英文
 {
    const GUI_FONT_PROP GUI_UNI_PTR * pProp;
    if(GUI_Context.pAFont == &GUI_FontHZ16)//在GUI_FontHZ16中找到字符间距,用于控件字符水平对齐,防止英文字符宽度被认为跟汉字一样
    {
        pProp = GUIPROP_FindChar(GUI_Font16_ASCII.p.pProp, c);//在GUI_Font16_ASCII字库里面找字符c
        return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Font16_ASCII.XMag : 0;//返回字符c的横坐标大小
    }
    else
    {
        pProp = GUIPROP_FindChar(GUI_Font24_ASCII.p.pProp, c);
        return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Font24_ASCII.XMag : 0;
    }
   
  }
  else
  {
    const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);
    return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Context.pAFont->XMag : 0;
  }
 
}

当这两个函数修改完毕,并且做好上面大牛的链接内容后,字体数据就放在外部flash中,显示器可以在控件上同时显示汉字和英文了。

http://pan.baidu.com/s/1pLFA739

这是我的工程源码,里面有将字体文件复制进SD卡的函数。我用的开发板是stm32f407,环境是keil5,在stm32f407板子上集成2M的flash,板子上面的SDIO接口连接了一个1G的SD卡,sd卡有font目录,里面放16HZK.bin和24HZK_B.bin文件,液晶驱动是ili9341.在这里感谢正点原子,很多驱动程序是他们提供的。

基于stm32f4的ucGUI通过外部flash存储汉字库显示任意英文字符和汉字组合(控件可用)的更多相关文章

  1. ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件

    源:ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件 如何将ucgui的汉字库存放到外部的flash memory(ucgui)(汉字库)(外部flash) ucgui的字库

  2. Flash播放控件属性详解

    Flash 播放控件属性详解 一.属性篇 1.AlignMode(读写)  语法:AlignMode As Long  说明:对齐方式(与SAlign 属性联动).当控件的长宽比例与影片不一致且WMo ...

  3. 玩转X-CTR100 l STM32F4 l W25Q64 SPI串行FLASH存储

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]      本文介绍X-CTR100控制器 板载FLA ...

  4. 智能设备逆向工程之外部Flash读取与分析篇

    智能设备逆向工程之外部Flash读取与分析篇 唐朝实验室 · 2015/10/19 11:19 author: rayxcp 0x00 前言 目前智能家居设备的种类很多,本文内容以某智能豆浆机为例完成 ...

  5. flash存储原理

    norflash 带有 SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内容每一字节:nandflash器件使用复杂的IO口串行的存取数据,读写操作采用512字节的块(也就是读/写某个字节,必 ...

  6. 218- VPX主板 基于5VFX70T的3U VPX 光纤数据采集存储板

    基于5VFX70T的3U VPX 光纤数据采集存储板 1.板卡概述 本板卡是基于3U VPX架构,符合VITA46标准,实现了多种图形图像接口的采集与转换.图像数据的处理.宽带数据缓存.SATA存储主 ...

  7. External Configuration Store Pattern 外部配置存储模式

    Move configuration information out of the application deployment package to a centralized location. ...

  8. STM32学习笔记(八) SPI总线(操作外部flash)

    1. SPI总线简介 SPI全称串行外设接口,是一种高速,全双工,同步的外设总线:它工作在主从方式,常规需要至少4根线才能够正常工作.SPI作为基本的外设接口,在FLASH,EPPROM和一些数字通讯 ...

  9. RTThread DFS文件系统使用: 基于使用SFUD驱动的SPI FLASH之上的ELM FATFS文件系统

    参考博文: 博文很长,但是实际要操作的步骤没几下. http://m.elecfans.com/article/730878.html  为了防止几年后文章链接找不到,我把文章复制过来了 /***** ...

随机推荐

  1. shr 右移测试

    fdword :DWORD; procedure TForm10.btn1Click(Sender: TObject); var temp:DWORD; begin fdword :=; //7866 ...

  2. CentOS 搭建 nginx + tomcat

    安装nginx yum install nginx 修改 nginx.conf, (/etc/nginx/nginx.conf), 网上有人做人所有配置项目的详解. #nu For more info ...

  3. HDU4787 GRE Words Revenge(AC自动机 分块 合并)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...

  4. EditText限制小数点前后位数

    在EditText输入数字的时候,通常我们需要限制小数点前后位数.比如金额输入一般我们需要限制小数点后面最多2位.我们可以通过 TextWatcher 实现. public class MyWatch ...

  5. bootstrap之强调文本的类(带颜色)

    bootstrap之强调文本的类(带颜色) <small>本行内容是在标签内</small><br> <strong>本行内容是在标签内</str ...

  6. Apache InterfaceAudience

    InterfaceAudience 类包含三个注解类型,用来被说明被他们注解的类型的潜在的使用范围(audience).@InterfaceAudience.Public: 对所有工程和应用可用@In ...

  7. JVM垃圾收集器

    JVM中垃圾的回收由垃圾收集器进行,随着JDK的不断升级,垃圾收集器也开发出了各种版本,垃圾收集器不断优化的动力,就是为了实现更短的停顿. 下面是7种不同的分代收集器,如果两个收集器之间有连线,则表示 ...

  8. LabVIEW 吸星大法 - 看见的好东西都是我的(下篇)

    前言 写了多年的LabVIEW程序,你是否面临这样的问题 总是在做一些重复的工作,感觉很没有意思: 总在不停的写代码,做类似的控件,实现相同的功能,丝毫没有成就感: 总在天加班,没有时间去提高自己; ...

  9. web端限时活动逻辑处理总结

    由于要在web端做一个限时活动的功能,功能大致为:一个小时内可以报名参加活动,然后给予报名者奖品,先到先得.用到一些处理逻辑做下总结,以前没有做过类似的东西,都是自己先体验其他网站的报名方式,然后再摸 ...

  10. java基本数据类型

    基本数据类型概念 java是一种强类型语言,意味着必须为每一个变量声明一种数据类型. java拥有8中基本数据类型,主要包含如下:4中整形类型(long.int.short.byte)表示整形数值:两 ...