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

  在做一个用到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.在这里感谢正点原子,很多驱动程序是他们提供的。

时间: 2024-08-08 13:52:18

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

Winform(C#)Flash控件 属性 方法 事件

我的用户控件->右键 添加/移除项 ->COM组件->ShockwaveFlash Object 打勾 属性: 1.AlignMode (读写) 语法:AlignModeAs Long 说明:对齐方式(与SAlign 属性联动).当控件的长宽比例与影片不一致且 WMode 不为 ExactFit 时,影片(没有被放大的)在控件中显示的位置可用该属性调整.该属性值由标志位组成.如图,将该属性值(二进制)中相 应的位标记为 1 就设置了相应的对齐方向. 属性值与相应的对齐方式(后面括号里是二

MFC里创建FLASH控件,并从内存流中载入SWF

#include <atlbase.h> extern CComModule _Module;      #include <atlcom.h> #include <oleacc.h> #include <comdef.h> #pragma comment(lib,"atl") #pragma comment(lib,"User32.lib") #import "c:\WINDOWS\system32\Mac

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

基于5VFX70T的3U VPX 光纤数据采集存储板 1.板卡概述 本板卡是基于3U VPX架构,符合VITA46标准,实现了多种图形图像接口的采集与转换.图像数据的处理.宽带数据缓存.SATA存储主控和千兆以太网通信.采用一片 Xinlinx Virtex-5系列FPGA XC5VFX70T-2FFG1136作为主控芯片,外接1个光纤接口,2路SRIO x4,2路SATA II,2路CAN总线接口,3组256MB DDR2,1路千兆以太网口(外部PHY模式)等.该板卡板卡设计芯片目前使用商业级

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

Move configuration information out of the application deployment package to a centralized location. This pattern can provide opportunities for easier management and control of configuration data, and for sharing configuration data across applications

云计算设计模式(八)——外部配置存储模式

云计算设计模式(八)--外部配置存储模式 移动配置信息从应用部署包到一个集中位置.这个模式可以提供机会,以便管理和配置数据的控制,以及用于跨应用程序和应用程序实例共享的配置数据. 背景和问题 大多数应用程序运行时环境包括位于应用程序文件夹内的在部署应用程序文件保持配置信息.在某些情况下也能够编辑这些文件来改变该应用程序的行为,它已经被部署之后.然而,在许多情况下,改变配置所需要的应用程序被重新部署,从而导致不可接受的停机时间和额外的管理开销. 本地配置文件还配置限制为单个应用程序,而在某些情况下

数据存储——手机外部文件存储

一.特点 1.把文件存储在手机外部存储空间(SD卡)里 2.存储的是任意类型的文件 3.使用IO输入输出流操作文件 4.文件路径 1-SD卡根目录/Android/data/包名/files/[ 文件类型],应用卸载后,数据同时被删除: 2-SD卡根目录/,应用卸载之后,数据不会被同时删除. 5.需要声明权限 1-android.permission.WRITE_EXTERNAL_STORAGE,写入文件: 2-MOUNT_UNMOUNT_FILESYSTEMS,创建和删除文件. 二.API 1

手机外部文件存储(SD卡存储)

package com.atguigu.l04_datastorage; import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException; import android.app.Activity;

keil将程序装入外部FLASH详解

在实际项目中,经常出现芯片的内部FLASH空间不够的情况,这就需要将程序分一部分装到外部FLASH中. 为了让大家能少走些弯路,在这里把我在这其中遇到的一些问题和经验教训给大家分享一下. 仅供参考,如果有错误的地方欢迎指正,提前表示感谢! 转载请注明出处:blog.csdn.net/waitig1992 硬件环境介绍 芯片是LPC1788,外部FLASH是SST39VF1601(NORFLASH). 这个norflash在我的版本的keil(v4.0)中没有烧写算法,需要自己手动编写烧写算法,具

Longhorn发布:基于微服务的开源分布式块存储

Longhorn项目现已正式发布!这是一个基于云和容器部署的分布式块存储新方式.Longhorn遵循微服务的原则,利用容器将小型独立组件构建为分布式块存储,并使用容器编排来协调这些组件,形成弹性分布式系统. Why Longhorn? 如今,基于云和容器的部署规模日益扩大,分布式块存储系统也正变得越来越复杂,单个存储控制器上的volume数量在不断增加.2000年代初,存储控制器上的volume数量只有几十个,但现代云环境却需要数万到数百万的分布式块存储卷.存储控制器变成了高度复杂的分布式系统.