在做一个用到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. solr4.5安装配置 linux+tomcat6.0+mmseg4j-1.9.1分词

    首先先介绍下solr的安装配置 solr下载地址 (我这用的solr-4.5.0) 运行环境 JDK 1.5或更高版本 下载地址(Solr 4以上版本,要求JDK 1.6)  我用的JDK1.6 ) ...

  2. fly bird

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. 【异常】No ManagedConnections available within configured blocking timeout

    Caused by: org.jboss.util.NestedSQLException: No ManagedConnections available within configured bloc ...

  4. windows消息机制详解(转载)

    消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...

  5. bootstrap学习笔记【转】

    bootstrap是由Twitter公司研发的一个基于HTML,CSS,JavaScript的开源框架,最重要的部分是它的响应式布局.(国内文档翻译官网:http://www.bootcss.com/ ...

  6. Docker中images无法使用apt-get update解决方案

    问题描述:使用apt-get update一直fail 原因:DNS设置错误 解决办法: nm-tool #查看DNS后面的数(IPv4),将后面的数copy下来 sudo nano /etc/def ...

  7. c# 局域网文件传输实例

    一个基于c#的点对点局域网文件传输小案例,运行效果截图 //界面窗体 using System;using System.Collections.Generic;using System.Compon ...

  8. STM32之DMA+ADC

    借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...

  9. AmazeUI 框架知识点-元素

    1.按钮  .am-btn 圆角按钮 .am-radius 椭圆形按钮 .am-round 按钮激活状态 .am-active 禁用状态 .am-disabled 2.按钮尺寸.am-btn-xl . ...

  10. 把C#程序(含多个Dll)合并成一个Exe的超简单方法

    开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具.那该怎么办呢? 下文介绍一种超 ...