关于ucgui的字库

合集下载

基于 UCGUI 库的外扩中文字库研究与实现

基于 UCGUI 库的外扩中文字库研究与实现

基于 UCGUI 库的外扩中文字库研究与实现李建红;刘丹;徐展【期刊名称】《计算机工程》【年(卷),期】2014(40)2【摘要】UCGUI 是实时嵌入式系统中广泛使用的图形用户界面,但 UCGUI 不支持中文字符编解码。

为此,提出一种支持中文字符编解码的方法。

在分析 UCGUI 字符编解码框架基础上,修改内核代码,添加 GB2312汉字编解码驱动,实现中文字符显示编解码服务。

针对 UCGUI 中文显示时中文字库占用空间大与 MCU 存储空间有限的矛盾,提出一种字体驱动与字模数据分离的中文字体设计方法,包括为外扩字体设计专用驱动、字模数据存储接口及存储方法。

在 UCGUI 仿真平台环境下的测试结果表明,该字库在 UCGUI 系列环境下,具有较好的可用性和通用性,可弥补 UCGUI 界面库在低成本嵌入式系统中难以实现中文显示的缺陷。

%UCGUI is a graphical user interface library which is widely used in real-time embedded system. As it does not support Chinese character set, a method to support Chinese character by adding GB2312 Chinese character codingis proposed. This paper designs and implements a font drive program by which font data is separated from UCGUI library code, including drive for extended font, font data access interface & method. Font drive is tested on the UCGUI simulators and is completely compatible with the UCGUI library. This makes up for technical blank of Chinese display in low-cost embedded system with UCGUI library.【总页数】5页(P271-274,279)【作者】李建红;刘丹;徐展【作者单位】电子科技大学电子科学技术研究院,成都 611731;电子科技大学电子科学技术研究院,成都 611731;电子科技大学电子科学技术研究院,成都611731【正文语种】中文【中图分类】TP391.41【相关文献】1.基于蒙古文编码国家标准的OpenType字库研究与实现 [J], 斯日古楞;呼斯勒2.基于STM32平台实现UCGUI外挂中文字库 [J], 马志刚3.基于网络处理器外扩TCAM的研究与实现 [J], 李诗革;李文耀;王欢4.中文字库芯片GT30L32S4W在emWin图形库中的应用 [J], 赵云5.ARM-Linux外扩AD驱动程序的研究与实现 [J], 曹毅;何慎学;陈会鸽因版权原因,仅展示原文概要,查看原文内容请购买。

如何将ucgui的汉字库存放到外部的flash memory

如何将ucgui的汉字库存放到外部的flash memory

(原创)如何将ucgui的汉字库存放到外部的flash memory(ucgui)(汉字库)(外部flash)摘要:在ARM7系统中,都不会有足够大的程序存储器来存放大容量的汉字库,因此当系统中要用到汉字库时,需要将其存储在外部的FLASH Memory,而ucgui的字符显示函数是直接从程序存储器取数据的,因此需要在原始代码里增加一个接口,来指向外部的FLASH Memory。

简介:ucgui中,字符显示的底层函数是GUICharP.c 中的void GUIPROP_DispChar(U16P c) 函数,我们将这个函数修改如下:/*********************************************************************** GUIPROP_DispChar** Purpose:* This is the routine that displays a character. It is used by all* other routines which display characters as a subroutine.*/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;//支持3种字体==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){BytesPerFont = BYTES_PER_FONT;if (c < 0x80) //英文字符地址偏移算法{oft = base + (c - 0x20) * BytesPerFont; //计算出字码在flash中的偏移地址}else//中文字符地址偏移算法{oft = base + (((c>>8) - 0xa1) * 94 + ((c&0xff) - 0xa1)) * BytesPerFont;}LCD_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; }}然后再加入FLASH操作的底层驱动(这里用的是SPI FLASH)/********************************************************************* ** Static code*********************************************************************** *///字模数据的暂存数组,以单个字模的最大字节数为设定值#define BYTES_PER_FONT 4*32 //最大支持32*32的汉字static U8 GUI_FontDataBuf[BYTES_PER_FONT];/********************************************************************* ** 读FLASH中的字库*/#include "spi_flash.h"#include "ssp.h"void LCD_ReadFlashBit(U32 addr,U8* buf,U8 Bytes){U8 i;SPI_FLASH_StartReadSequence(addr); //设置起始地址for(i=0;i<Bytes;i++){buf[i] = SPI_FLASH_SendByte(0xa5);}SPI_FLASH_CS_HIGH();}我们知道,ucgui访问字库的时候,是根据字库文件的索引表来查找汉字数据地址的,因此汉字库文件中的索引也要修改,以汉字库32为例/*******************************************************File Name : hzk32.CCompiler :Author : Liu_xfVersion : V1.0Date : 2011-3-28 11:25:54Description :ucgui的中文字库,与uc工具生成的字库文件不同的是,可以将大容量的汉字数组存入到外部的FALSH里当然这个也是由uc工具生成的文件修改而来的。

基于STM32平台实现UCGUI外挂中文字库

基于STM32平台实现UCGUI外挂中文字库

U CG UI是 一 种轻 量级 的嵌 入 式 图形 支 持 系
间 不足 而 无法 实 现程 序 的烧 写 . 所 以对 于大 量 文字
统 ,它 的设 计架 构 是模 块化 的, 由不 同 的模 块 中
的 上 运
的 随 机 显 示 ,更 好 的方 案 是 将 字 库 与 程 序 代 码 分 开 .但 是 U C GU I 本 身 并没 有 提供 从 外 部存 储 器读
行, 因为 它是 1 0 0 %的标准 C代 码编 写 的 . Uc Gu I 提 供一 个 可扩 展 的 2 D图形 库及 占用 极 少 R AM 的
窗 口管理 体系 ,非常适 合 如 S T M3 2 这样 的轻 量
级 嵌入 式 平 台 的 图形 界面 显示 I l J ,大 量 应用 于 各
作 者简 介 :马 志 刚 ( 1 9 7 9) ,云南 水 富人 ,讲师 ,硕 士,研 究方 向 :计算 机控 制 ,嵌入 式 系统 软硬 件
F O NT T YP E P R OP S J I S 的定 义 ,将字 符 显示 驱动
P Bl 2 P B1 3
PB 1 4 PB 1 5
绝 大部 分应 用场 合 都是 无法 事 先预 知有 哪些 汉字
需 要 显示 ,而 如果 把 所 有 常用 汉 字 按 照 uC G UI
S T M3 2处 理器 上外 接 F l a s h存储 芯片 来扩 大存储 空
间 .例 如 可 采 用 S P I接 口 的 Na n d F l a s h 芯 片 M2 5 P X1 6来 扩展 存储 空 间 ,该芯 片具有 1 6 Mb i t 容 量 ,具备 4 K 字 节子 区擦 除功 能 ,最 高支 持 7 5 Mh z

ucGUI移植详细设计及总结

ucGUI移植详细设计及总结

ucGUI移植详细设计及总结序本文档阐述了将ucGUI移植到IM12上的过程。

ucGUI版本为3.9,移植到IM12上,触摸屏及按键能够正常使用。

在ucGUI源码包的基础上,添加了一些接口函数以适应IM12,在使用时应该根据情况使用这些接口,这些新增加的函数的接口将在后面章节中详细讲述。

此外,适应IM12的ucGUI在Wind River Workbench 3.0环境下被编译成两个静态库文件libNoWindow.a和libWindow.a,编译程序时应该连接这两个库。

文档篇章安排如下:第一章,ucGUI源码包简介。

主要介绍了所使用的ucGUI图形库中各文件夹的内容及功能,并对IM12中与ucGUI移植相关的部分,包括触摸屏、LCD、按键板等进行了简单的介绍。

第二章,图形库移植。

阐述如何对ucGUI进行配置、编译,以在IM12的LCD上显示图形,此部分还未实现触摸屏及按键功能,只是纯粹的显示而已第三章,触摸屏移植。

第四章,按键移植。

第五章,带触摸屏及按键功能的ucGUI应用程序模板。

第一章ucGUI源码包简介ucGUI要移植到im12上,实际上就是根据im12的情况修改ucGUI中的一些配置项,或增加、删减一些程序以适应im12,同时要保持ucGUI的特性。

要做好移植工作,需对ucGUI 及IM12相关部分有足够的了解。

1.1ucGUI简介移植所采用的ucGUI版本为3.9,主要包含的文件夹如图1所示图1 ucGUI源码结构图各文件夹的主要内容如下:Config ----------- 配置文件GUI ----------- 源代码GUI_X ---------- 操作系统接口函数定义文件GUI 源代码文件:1)AntiAlias: 抗锯齿显示效果支持。

2)ConvertColor: 彩色显示的色彩转换支持。

3)ConvertMono: (b/w)和灰度显示的色彩转换支持。

4)Core: 核心文件,提供了GUI基本的功能。

uCGUI 汉字显示技巧及总结

uCGUI 汉字显示技巧及总结

UCGUI的基础应用汉字显示在uC/GUI中显示汉字,必要的一个步骤就是汉字取模。

通常有两种方法:一、单个字模法:使用字模取模软件,进行单个字的取模。

此方法可应用于显示汉字字数较少的情况下。

其优点是:占用存储空间小,无冗余。

但当显示汉字字数较多时,该方法则非常繁琐。

二、字模库法:该方式需要移植整个汉字字库,若项目要求需显示多种汉字字体,则需移植多种字体的字库。

其优点是:操作方便。

若嵌入式系统的FLASH存储容量够大时,该方式可行。

根据作者多年的项目实践,找到一个兼具上述两种方式优点的显示方案:利用UCGUIFontTool软件,提取windows自带的字模库。

该方法的使用步骤:1、将项目中所要显示的汉字根据字体进行分类并汇总。

2、使用UCGUIFontTool软件分别提取上述字模。

3、将所产生的.C文件添加到工程中。

4、更改gui.h中的配置,添加该汉字的宏定义,如图5、显示汉字前更改需显示的字体,如图6、利用函数进行显示。

该方法移植方便,易实现同时显示多种字体,无字模冗余,占用存储空间最小。

图片显示uC/GUI提供了位图的解决方案,在GUI显示图片时,需先将其他格式的图片转换为bmp格式。

可利用windows系统自带的画图软件打开一个图片,再另存为bmp格式,继而转换为.c 格式文件加入到工程中。

其操作步骤如下:1、将其他格式的图片另存为bmp格式。

2、打开UCGUI源码自带的工具uC-GUI-BitmapConvert,选择相应参数,并转换为.c文件。

3、将该.c文件加入到工程中。

4、添加外部变量,并调用相应函数进行显示。

如图5、也可UCGUI提供的缩放函数可对图片进行缩放显示。

如图这里说一个技巧:如果无需在显示过程中对图片进行缩放,那么建议在第二步的时候就完成图片的缩放操作,以减少CPU的工作量。

控件显示UCGUI提供了很多控件,这里不再赘述,每个控件的操作方式类同。

这里以按钮控件作为举例。

第18章emWin(UCGUI)汉字显示方式一(FontCvt的使用)

第18章emWin(UCGUI)汉字显示方式一(FontCvt的使用)

第18章汉字显示方式一(FontCvt的使用)本期教程主要跟大家介绍官方的小工具Font Converter的使用方法,使用官方的字体转换工具,字体的显示效果要比网上那些针对UCGUI设计的字体生成工具好非常多。

4位抗锯齿的显示效果更是非常棒。

在开头先跟大家强调两点,一个是这个字体小工具必须的使用STemWin软件包里面的,SEGGER官网下载的和MDK安装目录里面带的都是评估版,另一点是在教程中我会要求大家将要显示汉字的C文件转换为UTF-8编码,我仅仅是指的将这个显示汉字的C文件转换为UTF-8编码,这点要切记。

18. 1 使用FontCvt生成字库C文件的方法18. 2 在开发板上面实现中文显示18. 3 总结18.1使用FontCvt生成字库C文件的方法我们先讲如何用这个软件生成部分的汉字数据,这里就以“安富莱电子”五个字进行说明。

18.1.1第一步:打开选择Standard,16bit unicode18.1.2第二步:打开选择字体和字体大小18.1.3第三步:选择禁止所有的字符18.1.4第四步:用unicode软件转换函数用中文转unicode的小软件得到“安福莱电子”这5个字的unicode编码我这里在百度上面找了一个网页应用。

18.1.5第五步:在FontCvt上使能这个五个字的编码在Font Converter软件上面使能这个五个字的unicode编码,以“安”字为例它的unicode编码是5b89,这里有两种办法找这个字。

方法一:直接的在软件里面查找,根据左边的unicode编码。

方法二:通过限制范围查找。

18.1.6第六步:然后点击保存为C文件要将前面的五个字全部找到并使能以后再做保存。

18.2在开发板上面实现中文显示下面我们用18.1小节讲的汉字生成方式生成7中类型的字体。

前三种是Standard的宋体,大小是16,36和72.第四种是144*144点阵的,有没有这么大的字体,需要手动往大小选项里面填写144,并选择右侧的Pixels。

GUI汉字显示原理

GUI汉字显示原理

GUI汉字显示原理1、在UCGUI中有两种类型字体, 一种是等宽字体(Monospaced Font),即字体当中所有字都是同一宽度,它在UCGUI中的相应结构体是GUI_FONT_MONO, 一种是均衡字体(Proportional font), 这种字体中的字都有自己独立的宽度, 字体内的每个字都可以有不同宽度, 它在UCGUI中的相应结构体是GUI_FONT_PROP, 对于等宽字体, 一般都是将所有字的点阵存放在一个数组中, 因为每个字都宽度相同. 对于均衡字体, 则要单独用数组来定义每个字符的点阵, 然后将每一个字符的宽高及点阵存为一个数组即字符信息(ucgui中对应结体为GUI_CHARINFO), 所有字符信息再存到一个数组当即称为字符集, 它包含每个字的字符信息(点阵高宽及一行占几个字节), 所谓一行占几个字节, 是指这个字体的点阵每一行有多少个字节, 它与宽度高度单位不同, 宽度高度的单位是象素数.2.另外特别指出的是, 在等宽字体中不仅所有字符宽度相同,高宽也是相等的; 对于均衡字体, 不仅可以宽度不同, 高度也可以不同, 每一行有多少个字节自然也不同, 在均衡字体中每一个字符都单独定义之后才组成字体的字符集.3.字符集的问题, 在UCGUI中每种字体含的字符集不同, 这个可以参看UCGUI手册中的"Standard Font"一章,这一章中对于字符集有如下描述:ASCII: Only ASCII characters 0x20-0x7E (0x7F).[仅包含0x20-0x7E这个范围内的ansii字符]1: ASCII characters and European extensions 0xA0 - 0xFF.[除0x20-0x7E这个范围内的ansii字符, 还有0xA0 - 0xFF这个范围内的欧洲字符集, 这里要指出美国英语只用到0x20-0x7E, 它只考虑了自己的须求, 没有考虑其它国家的须求, 在欧洲是有拉丁字符的, 所以欧洲国家扩展了剩余的0xA0 - 0xFF这个范围内的来表示欧洲的字符集, 其实我们国家的汉字也是在这个范围内扩展的, 不过我们用的是二个字节来表示一个汉字, 是因为汉字太多, 这区区94个值无法满足汉字的须求, 94*94就差不多了. 汉字用到的第一个值为0xb0a1(啊), 最后一个为0xf7fe(齄), 在机内码1当中只用到a1+15~a0+86这个范围的, 关于机内码是这个意思: 对于"啊"字模,机内码:(0xb0,0xa1), 0xb0为"啊"字的机内码1,0xa1为机内码2. 对于机内码2合使用是0xa1~0xff这个范围内的所有值, 关于机内码及汉字显示的原理及汉字库的构成, 本论坛中有专门的一篇文章介绍--"ucgui中处理汉字显示的说明", 请查看此贴, 这里不多说了, 所以范围是这样确定的.]HK: Hiragana and Katakana[日文平假名与片假名].1HK: ASCII, European extensions, Hiragana and Katakana[ansii,欧洲字符集,日文平假与片假].D: Digit fonts[数字及运算符号集].以上的ASCII/1/HK/1Hk/D都是字符集的简单代号.3. 回过头来再看你的GUI_Font__21_Prop2,GUI_Font__21_Prop1. 那么很容易理解,GUI_Font__21_Prop2是欧洲字符集, 范围当然是0xa0-0xff. GUI_Font__21_Prop1中存的是ASCII字符集. 至于GUI_Font__21_CharInfo中则存的是全部的字符集的点阵信息, 包含所有字符信息. 最后, 将字体中包含的所有字符集用链表连接起来. 再将这个链表头指针存到字体结构(GUI_FONT)中的存放均衡字体的指针(const GUI_FONT_PROP* pProp)当中, 这样在处理字符的显示, 可以在这链表中查找所要显示的字符是在哪一个字符集中, 从而找到它的字符信息(即点阵数据及宽高).typedef struct {GUI_DISPCHAR* pfDispChar;GUI_GETCHARDISTX* pfGetCharDistX;GUI_GETFONTINFO* pfGetFontInfo;GUI_ISINFONT* pfIsInFont;tGUI_ENC_APIList* pafEncode;U8 YSize;U8 YDist;U8 XMag;U8 YMag;union {//此联合处存放均衡或是待宽字符集信息...void *pFontData;const GUI_FONT_MONO* pMono;const GUI_FONT_PROP* pProp;} p;U8 Baseline;} GUI_FONT;在GUI_Font__21_Prop1中的(void GUI_FLASH *)&GUI_Font__21_Prop2/* pointer to next GUI_FONT_PROP */在GUI_Font__21_Prop2中的(void GUI_FLASH *)&GUI_Font__21_Prop3/* pointer to next GUI_FONT_PROP */在GUI_FONT_MONO当中的成员next就是指向一下字符集的...这个链表是人工写成的.....链表最后一个成员的next指向空....这个链表的构造, 其实还是为了使用, 所以要理解它, 就要理解是如何用的.均衡字体的显示, 是在GUIPROPAA_DispChar这个函数中处理的, 要理解链表的构造就要理解这个函数,下面做简要的分析....void GUIPROPAA_DispChar(U16P c) {int BytesPerLine;GUI_DRAWMODE DrawMode = GUI_Context.TextMode;const GUI_FONT_PROP* pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);if (pProp) {GUI_DRAWMODE OldDrawMode;const GUI_CHARINFO* pCharInfo = pProp->paCharInfo+(c-pProp->First);BytesPerLine = pCharInfo->BytesPerLine;OldDrawMode = LCD_SetDrawMode(DrawMode);Draw ( GUI_Context.DispPosX, GUI_Context.DispPosY,(pCharInfo->XSize+1)/2,GUI_Context.pAFont->YSize,BytesPerLine,(U8 const*) pCharInfo->pData);LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */ GUI_Context.DispPosX += (pCharInfo->XDist+1)/2;}}而理解GUIPROPAA_DispChar的重点, 就是要理解它当中调用的用来寻找要显示的字符的字符信息的函数GUIPROP_FindChar, GUIPROP_FindChar主要是寻找字符所在的字符集(其实这个字符集在汉字应用当中,有些不同.在hzk12.c中, 作者是将汉字接区来分集的, 下面我们以hzk12.c 中的构造来讲解字符集链表:hzk12.c 中共分成(0xa1a1~0xa1fe),(0xa2a1~0xa2fe)...(0xf7a1~0xf7fe)共分成86个字集, 另外加上(0x0020, 0x007f)这个ANSCII字符集, hzk12.c中的链表中就其有87个字符集, 这里的字符集的意义就不再是一个标准的字符集了, 而只能称之为字符的集合而已, 没有严格意义上的字符集的意思).hzk12.c中, 字符集链表构成为: 字符集链表第一个元素为ascii字符集,第二个为机内码处于(0xa1a1~0xa1fe)间的汉字集, 最后一个为(0xf7a1,0xf7fe)....了解了汉字库的这个字符集链表的构成, 那么现在来看一下如何寻找一个要显示的字符处于哪个字符集当中, 找了那个字符集才能找到这个字符的字符信息....static const GUI_FONT_PROP* GUIPROP_FindChar(const GUI_FONT_PROP* pProp, U16P c) {for (pProp = GUI_Context.pAFont->p.pProp; pProp; pProp=(const GUI_FONT_PROP*) pProp->pNext) {if ((c>=pProp->First) && (c<=pProp->Last))break;}return pProp;}GUIPROP_FindChar 其实就是查找字符的机内码是位于哪个字符集之间, 比如寻找"啊"字, 机内码为0xb0a1,那么由上查找, 就可以知道它是位于链表中第16(0xb0-0xa1=16)个字符集(机内码处于0xb0a1~0xb0fe)当中, 那么就返回这个字符集的指针. 找到了要显示的字符所处的字符集, 再根据:const GUI_CHARINFO* pCharInfo = pProp->paCharInfo+(c-pProp->First);c-pProp->First即为该字符在此字符集中的偏移, pProp->paCharInfo为该字符集中第一个字符地址...这样就找到了要显示的字符的字符信息了(宽高及点阵数等), 理解了这个过程, 那么反过来理解这个字符集为何要如此构造, 就比较容易了...比如说: 为什么要将汉字分成86个字符集合? 这是由于汉字的机内码并没有用到所有的0xffff--xa1a1=0x5e5e中连续的值, 而是间断的, 0xa1a1~0xa1fe用到了, 0xa200~0xa2a1这段当中的值不能用(因为机内码2小于0xa1了), 只能用0xa2a1~0xa2fe, 所以这个特性决定了汉字的机内码分布是显区段的, 不能用一个单一的GUI_FONT_PROP 结点来表示出所有的字符集, 因为汉字是区间分布的, 不是连续的.比如说, 如下所示:GUI_FLASH const GUI_FONT_PROP GUI_FontHZ12_Propa1= {0xa1a1,0xfefe,&GUI_FontHZ12_CharInfo[ 96],(void *)&GUI_FontHZ12_Propa2};用以下一个结点来表示所有汉字, 如同ACSII, 那么我们分析一下它为什么不可以:首先对于区间(0xa1a1~0xa1fe)这第一个区间, 在以上的结构下, 这个区间内的字符还是能够正确找到所要显示的字符信息. 但对于(0xa2a1~0xa2fe)这个区间的, pProp->paCharInfo+(c-pProp->First)显然无法找到字符信息. 这是GUI_FontHZ12_CharInfo 这个所有字符信息集数组的结构决定的, 因为汉字未用的区间的在它上面没有体现, 它上面存放的是将分隔开的汉字区间连在一起的, 这样你就无法根据pProp->paCharInfo+(c-pProp->First)来找到字符的位置了....[ucgui原创]在UCGUI中增加汉字显示的说明.在UCGUI中增加汉字显示的说明.作者: ucguiemail:*************home:版本: v1.0.0.1UCGUI中本身只支持E,没有提供中文的字库的.C源码文件, 但是我们可以通过下面的方式来实现汉字的显示...我们知道, 在DOS下经常利用点阵来显示汉字. 带汉字显示的程序,很多都会自己带上汉字库, 这个字库里放的就是每个汉字的点阵.一. 汉字的显示原理之一 -----------------点阵汉字.简单的理解, 所谓一个字的点阵. 其实就是指这个汉字用多少个象素点来描述. 每个象素点显示为什么颜色, 通常情况下, HZK16采用的是16*16点阵, 即256个象素点描述一个汉字.这些点的颜色分为两种, 一种是前景色, 一种是显示为背景色.那么,关于那些点显示为前景色, 那些点显示为背景色, 是如何得知的呢??可以这样来考虑, 你在纸上比较正正方方的写一个规则的楷字, 然后在这个字的从上到下,左到右, 分别画十七条直线, 那么这个字就被放置于一个16*16的方格之内, 这样我们就可以很明显的看出, 16*16的方格内的具体哪些点有笔划经过, 有笔划经过与没笔化经过的即就是应该被分别填充上前景色与背景色的点.现在,找到了一个汉字的点阵, 那么还须要用数据来记录点阵的信息, 通常情况下, 我们会用32个字节来表示16*16点阵的汉字, 即每一行用二个字节来记录十六个象素点的色色彩情况, 0表示背景色, 1表示前景色. 16行其须要32个字节.点阵汉字的原理同时也决定了它的缺点, 他不具务放大特性, 因为它的显示是基于被定死的点阵, 放大后, 会产生明显的锯齿,非常的难看, 当然, 可以进行一些光滑处理, 但基本上没有多在的改观.但点阵汉字简易, 对于复杂汉字, 它比矢量显示汉字法更快带.矢量显示是基于记录汉字的笔化的. 对于简单的汉字它比较占优势, 容易放大处理. 但对于复杂的汉字, 表示起来, 则笔化太多..复杂.二. 关于字库的建立及其原理.现在讲完了汉字点阵. 也说了一个汉字点阵的存放方式, 但具体的点阵如何存放, 读者也应该了解.通常情况下, 一般的DOS下的程序都会提供一个汉字库, 这样在脱离汉字平台(如UCDO)的支持下也可以进行汉字显示, 但是这样会存一个问题, 就是如果每个DOS下的程序员都这么做的话, 就会造成一定的磁盘空间浪费. 所以有的DOS下的程序,针对自己所需要的汉字, 就会定制自己的小型字库, 那么字库的制作到底应该如何进行呢? 下面我们将就这个问题进行一些基本的讨论.众所周知,一个ASCII字符占一个字节,它的数值从0到255, 那么汉字字符将如何与ASCII字符区别开来呢?实际上,仔细观察ASCII字符表,从第161(即0xa1)个字符开始,后面的字符并不经常为E文所使用。

ucGUI加载“完整”外部字库的方法

ucGUI加载“完整”外部字库的方法

ucGUI加载“完整”外部字库的方法ucGUI加载“完整”外部字库的方法(1)——从外扩NOR Flash中加载CPU:LPC2478NOR Flash:MX29LV640EBtypedef __packed struct {U8 XSize;U8 XDist;U8 BytesPerLine;const unsigned char GUI_UNI_PTR * pData;} GUI_CHARINFO;在我的平台下,外部NOR Flash的起始地址是0x80000000,其容量是8MB。

我使用ucGUI提供的字库工具生成的4位抗锯齿字库大小为1.8M字节(此为经过计算后纯字库数据的大小)。

考虑到字库内容的连续性,在NOR Flash中为字库存储分配一个固定的区域,在我的工程中将其配置为0x80600000,从该地址开始还有2M的存储空间。

程序中做如下定义(代码中的一些数字的意义后文解释):#define GUI_FONT_HWZS_NORFLASH_BASE (0x80600000) #define GUI_FONT_HWZS_PROP_SIZE (1008)#define GUI_FONT_HWZS_CHARINFO_SIZE (48167)#define GUI_FONT_HWZS_DATA_SIZE (1806048)GUI_FONT_PROP *GUI_Font_hwzs_22AA4_Prop = (GUI_FONT_PROP *)(GUI_FONT_HWZS_NORFLASH_BASE);GUI_CHARINFO *GUI_Font_hwzs_22AA4_CharInfo = (GUI_CHARINFO *)(GUI_FONT_HWZS_NORFLASH_BASE + GUI_FONT_HWZS_PROP_SIZE);char *GUI_Font_hwzs_22AA4_CharData =(char *)(GUI_FONT_HWZS_NORFLASH_BASE +GUI_FONT_HWZS_PROP_SIZE + GUI_FONT_HWZS_CHARINFO_SIZE);GUI_FLASH const GUI_FONT GUI_Font_hwzs_22AA4 ={GUIPROP_AA4_DispChar ,GUIPROP_AA4_GetCharDistX ,GUIPROP_AA4_GetFontInfo ,GUIPROP_AA4_IsInFont ,&GUI_ENC_APIList_SJIS ,24 /* height of font */ ,24 /* space of font y */ ,1 /* magnification x */ ,1 /* magnification y */ ,(void GUI_FLASH *)((GUI_FONT_PROP *)(GUI_FONT_HWZS_NORFLASH_BASE)) };借助Visual Studio 2008进行了字库二进制文件的生成。

第21章emWin(UCGUI)SIF系统独立字体(官方推荐)

第21章emWin(UCGUI)SIF系统独立字体(官方推荐)

第21章SIF系统独立字体(官方推荐)SIF字体和上章教程中讲的XBF字体基本是相同的,不同的是XBF是存储到外部存储器中,而SIF需要将其加载到内部存储器中,比如RAM里面,这样处理器就可以直接读取相应的地址就能获得数据。

这种方式显示字体的速度要比XBF方式快。

21. 1 SIF格式字体生成方法21. 2 移植到开发板显示21. 3 总结21.1SIF格式字体生成方法这里我们使用FontCvt生成一种宋体,字体选择16号并选standard模式。

21.1.1第一步:选择standard21.1.2第二步:选择字体和字体大小21.1.3第三步:另存为SIF格式文件21.2移植到开发板上显示移植到开发上的程序主要分为两部分,一个是从SD卡中读取字体加载到外部SRAM里面,另一个建立一个对话框显示字体。

21.2.1创建SIF字体/*********************************************************************************************************** 函 数 名: MainTask* 功能说明: GUI主函数* 形 参:无* 返 回 值: 无**********************************************************************************************************/void MainTask(void){OS_ERR err;char *_acBuffer;_acBuffer = (char *)EXT_SRAM_ADDR; (1)GUI_Init();/* 打开文件 */OSSchedLock(&err);(2)result = f_open(&file, "son.sif", FA_OPEN_EXISTING | FA_READ | FA_OPEN_ALWAYS);result = f_read(&file, _acBuffer, file.fsize, &bw);(3)OSSchedUnlock(&err);GUI_SIF_CreateFont(_acBuffer, &SIF_Font, GUI_SIF_TYPE_PROP);(4)WM_SetDesktopColor(GUI_WHITE);WM_SetCreateFlags(WM_CF_MEMDEV);PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);while(1){GUI_Delay(100);}}1.指针变量指向外部SRAM首地址。

ucgui汉字显示函数追踪

ucgui汉字显示函数追踪

GUI_SetFont(& GUI_FontHZ24x24);设置字体为GUI_FontHZ24x24,原型:const GUI_FONT GUI_UNI_PTR* GUI_SetFont(const GUI_FONT GUI_UNI_PTR * pNewFont) { const GUI_FONT GUI_UNI_PTR* pOldFont = GUI_Context.pAFont;GUI_LOCK();if (pNewFont)GUI_Context.pAFont = pNewFont;GUI_UNLOCK();return pOldFont;}GUI_FontHZ24x24字库:GUI_CONST_STORAGE GUI_FONT GUI_FontHZ24x24 = {GUI_FONTTYPE_PROP_SJIS,24,24,1,1,&GUI_FontHZ_24x24_Prop1};#define GUI_FONTTYPE_PROP_SJIS \GUIPROP_DispChar, \GUIPROP_GetCharDistX, \GUIPROP_GetFontInfo, \GUIPROP_IsInFont, \&GUI_ENC_APIList_SJISGUI_FONT_PROP GUI_FontHZ_24x24_Prop1 = {0xB2E2, /*start :²â*/0xB2E2, /*end :²â, len=1*/&GUI_FontHZ_24x24_CharInfo[ 0 ],&GUI_FontHZ_24x24_Prop2};GUI_CHARINFO GUI_FontHZ_24x24_CharInfo[4] = {{ 24, 24, 3, (unsigned char *)&acFontHZ_B2E2 }, /*0:测/{ 24, 24, 3, (unsigned char *)&acFontHZ_B6C8 }, /*1:度*/{ 24, 24, 3, (unsigned char *)&acFontHZ_BBB7 }, /*2:环*/{ 24, 24, 3, (unsigned char *)&acFontHZ_BCE0 } /*3:监*/}//“测”字unsigned char acFontHZ_B2E2[72] = {________,________,________,_XX___X_,_____X__,_____XX_,__XX__XX,XXXXXXX_,_____X__,___XX_XX,_____X__,_____X__,___X__XX,_____X__,_X___X__,______XX,_____X__,_XX__X__,______XX,__XX_X__,_X___X__,XX___XXX,__X__X__,_X___X__,_XX__XXX,__X__X__,_X___X__,_XX_X_XX,__X__X__,_X___X__,____X_XX,__X__X__,_X___X__,____X_XX,__X__X__,_X___X__,____X_XX,__X__X__,_X___X__,___X__XX,__X__X__,_X___X__,___X__XX,__X__X__,_X___X__,___X__XX,_XX__XX_,_X___X__,XXXX__XX,_XX__X__,_X___X__,_XX___X_,_X______,_X___X__,__X_____,_X_X____,_____X__,__X_____,XX__X___,_____X__,_XX_____,X____X__,_____X__,_XX____X,_____XX_,_____X__,_XX___X_,_____XX_,__XXXX__,____XX__,________,___XXX__,};/* char: 度 code:0xB6C8 */ unsigned char acFontHZ_B6C8[72] = { ________,___X____,________,________,___XX___,________,________,____XX__,_____X__,__XXXXXX,XXXXXXXX,XXXXXXX_,__XX____,X_______,________,__XX____,_XX_____,XX______,__XX____,_X______,XX______,__XX____,_X______,XX__XX__,__XXXXXX,XXXXXXXX,XXXXXXX_,__XX____,_X______,XX______,__XX____,_X______,XX______,__XX____,_X______,XX______,__XX____,_XXXXXXX,XX______,__X_____,________,________,__X_____,________,_XX_____,__X____X,XXXXXXXX,XXX_____,__X_____,_X______,XX______,__X_____,__X____X,X_______,_X______,___X__XX,________,_X______,____XXX_,________,_X______,____XXX_,________,X_______,__XXX_XX,X_______,X_______,XXX_____,XXXXXXX_,_____XXX,________,__XXXX__, };/* char环∙ code:0xBBB7 */ unsigned char acFontHZ_BBB7[72] = { ________,________,________,________,________,_____X__,______XX,XXXXXXXX,XXXXXXX_,XXXXXX__,_______X,X_______,____X___,_______X,________,____X___,______XX,________,____X___,______XX,________,____X___,______X_,________,____X__X,_____XXX,________,XXXXXXXX,X____XXX,________,____X___,____XXXX,_X______,____X___,____X_XX,__X_____,____X___,___XX_XX,___X____,____X___,__XX__XX,____XX__,____X___,__X___XX,____XX__,____X_XX,XX____XX,_____XX_,____XX__,X_____XX,_____XX_,_XXX___X,______XX,________,XXX_____,______XX,________,X_______,______XX,________,________,______XX,________,________,______XX,________,________,______XX,________,________,______XX,________, };/* char: 监 code:0xBCE0 */ unsigned char acFontHZ_BCE0[72] = { _______X,________,________,_______X,X_____XX,________,__XX___X,X____XX_,________,__XX___X,X____XX_,________,__XX___X,X____X__,____XX__,__XX___X,X____XXX,XXXX____,__XX___X,X___XX__,________,__XX___X,X___X___,X_______,__XX___X,X__XX___,_X______,__XX___X,X__X____,_XX_____,__XX___X,X_X_____,__XX____,__XX___X,X_X_____,__XX____,_______X,X_______,________,_______X,X_______,________,__X_____,________,__XX____,__XXXXXX,XXXXXXXX,XXXX____,__XX____,X____X__,__XX____,___X____,X____X__,__XX____,___X____,X____X__,__XX____,___X____,X____X__,__XX____,___X____,X____X__,__XX____,___X____,X____X__,__XX____,XXXXXXXX,XXXXXXXX,XXXXXXX_,________,________,________,};GUI_Context结构体typedef struct {/* Variables in LCD module */LCD_COLORINDEX_UNION LCD;LCD_RECT ClipRect;U8 DrawMode;U8 SelLayer;U8 TextStyle;/* Variables in GL module */GUI_RECT* pClipRect_HL; /* High level clip rectangle ... Speed optimization so drawing routines can optimize */ U8 PenSize;U8 PenShape;U8 LineStyle;U8 FillStyle;/* Variables in GUICHAR module */const GUI_FONT GUI_UNI_PTR * pAFont;//字体const GUI_UC_ENC_APILIST * pUC_API; /* Unicode encoding API */I16P LBorder;I16P DispPosX, DispPosY;//X,Y坐标I16P DrawPosX, DrawPosY;I16P TextMode, TextAlign;GUI_COLOR Color, BkColor; /* Required only when changing devices and for speed opt (caching) *//* Variables in WM module */#if GUI_WINSUPPORTconst GUI_RECT* WM__pUserClipRect;GUI_HWIN hAWin;int xOff, yOff;#endif/* Variables in MEMDEV module (with memory devices only) */#if GUI_SUPPORT_DEVICESconst tLCDDEV_APIList* pDeviceAPI; /* function pointers only */GUI_HMEM hDevData;GUI_RECT ClipRectPrev;#endif/* Variables in Anitaliasing module */#if GUI_SUPPORT_AAconst tLCD_HL_APIList* pLCD_HL; /* Required to reroute drawing (HLine & Pixel) to the AA module */U8 AA_Factor;U8 AA_HiResEnable;#endif} GUI_CONTEXT;GUI_FONT 结构体原型:struct GUI_FONT {GUI_DISPCHAR* pfDispChar; //字符显示函数GUI_GETCHARDISTX* pfGetCharDistX;GUI_GETFONTINFO* pfGetFontInfo;GUI_ISINFONT* pfIsInFont;const tGUI_ENC_APIList* pafEncode;U8 YSize;U8 YDist;U8 XMag;U8 YMag;union {const void GUI_UNI_PTR * pFontData;const GUI_FONT_MONO GUI_UNI_PTR * pMono;const GUI_FONT_PROP GUI_UNI_PTR * pProp;} p;U8 Baseline;U8 LHeight; /* height of a small lower case character (a,x) */U8 CHeight; /* height of a small upper case character (A,X) */};GUI_GotoXY设置坐标char GUI_GotoXY(int x, int y) {char r;GUI_LOCK();r = _GotoX(x);r |= _GotoY(y);GUI_UNLOCK();return r;}static char _GotoX(int x) {GUI_Context.DispPosX = x;return 0;}static char _GotoY(int y) {GUI_Context.DispPosY = y;return 0;}GUI_DispString()//显示字符串,原型:void GUI_DispString(const char GUI_UNI_PTR *s) {int xAdjust, yAdjust, xOrg;int FontSizeY;if (!s)return;GUI_LOCK();FontSizeY = GUI_GetFontDistY(); //Font的y大小,默认8xOrg = GUI_Context.DispPosX;/* Adjust vertical position */yAdjust = GUI_GetYAdjust(); //垂直对齐方式GUI_Context.DispPosY ‐= yAdjust;for (; *s; s++) {GUI_RECT r;int LineNumChars = GUI__GetLineNumChars(s, 0x7fff); //获取一行\0或\n 8bits字节数int xLineSize = GUI__GetLineDistX(s, LineNumChars); //这些数据所占用x轴上横向点阵数/* Check if x‐position needs to be changed due to h‐alignment */switch (GUI_Context.TextAlign & GUI_TA_HORIZONTAL) { //水平对齐方式case GUI_TA_CENTER: xAdjust = xLineSize / 2; break;case GUI_TA_RIGHT: xAdjust = xLineSize; break;default: xAdjust = 0;}r.x0 = GUI_Context.DispPosX ‐= xAdjust;r.x1 = r.x0 + xLineSize ‐ 1;r.y0 = GUI_Context.DispPosY;r.y1 = r.y0 + FontSizeY ‐ 1; //该行字体显示矩形区域rGUI__DispLine(s, LineNumChars, &r); //显示该行数据GUI_Context.DispPosY = r.y0;s += GUI_UC__NumChars2NumBytes(s, LineNumChars); //s指向下一行待显示的数据区if ((*s == '\n') || (*s == '\r')) {switch (GUI_Context.TextAlign & GUI_TA_HORIZONTAL) {case GUI_TA_CENTER:case GUI_TA_RIGHT:GUI_Context.DispPosX = xOrg; //居中和右对齐,传递函数原始位置xOrgbreak;default:GUI_Context.DispPosX = GUI_Context.LBorder;break;}if (*s == '\n')GUI_Context.DispPosY += FontSizeY; //回车,转入下一行} else {GUI_Context.DispPosX = r.x0 + xLineSize; //接着上一行的结束位置,继续显示}if (*s == 0) //待显示数据已经显示完毕break;}GUI_Context.DispPosY += yAdjust; //将垂直对齐方式还原成未调用GUI_DispString之前值GUI_Context.TextAlign &= ~GUI_TA_HORIZONTAL; //清除文本水平对齐方式GUI_UNLOCK();}‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐2.GUI__DispLine()函数gui/core/GUICharLine.cvoid GUI__DispLine(const char GUI_UNI_PTR *s, int MaxNumChars, const GUI_RECT* pr) {GUI_RECT r;{r = *pr;#if GUI_WINSUPPORTWM_ADDORG(r.x0, r.y0);WM_ADDORG(r.x1, r.y1); //将矩形(r.x0,r.y0)平移到(GUI_Context.xOff,GUI_Context.yOff)坐标处WM_ITERATE_START(&r) { //计算剪切域,另用《浅析μC/GUI‐v3.90a之WM_ITERATE_START剪切域计算宏》专门讨论 #endifGUI_Context.DispPosX = r.x0;GUI_Context.DispPosY = r.y0;/* Do the actual drawing via routine call. */_DispLine(s, MaxNumChars, &r);#if GUI_WINSUPPORT} WM_ITERATE_END();WM_SUBORG(GUI_Context.DispPosX, GUI_Context.DispPosY);#endif}}static void _DispLine(const U16 GUI_UNI_PTR *s, int Len, const GUI_RECT* pr) {GUI_RECT r;r = *pr;#if GUI_WINSUPPORTWM_ADDORG(r.x0,r.y0);WM_ADDORG(r.x1,r.y1);WM_ITERATE_START(&r) {#endifGUI_Context.DispPosX = r.x0;GUI_Context.DispPosY = r.y0;_DispLine_UC(s, Len, &r); /* Do the actual drawing via routine call. */#if GUI_WINSUPPORT} WM_ITERATE_END();WM_SUBORG(GUI_Context.DispPosX, GUI_Context.DispPosY);#endif}static void _DispLine_UC(const U16 GUI_UNI_PTR *s, int Len, const GUI_RECT *pRect) {if (GUI_Context.pClipRect_HL) {if (GUI_RectsIntersect(GUI_Context.pClipRect_HL, pRect) == 0)return;}{U16 c0;while (‐‐Len >=0) {c0=*s++;GL_DispChar(c0);}}}void GL_DispChar(U16 c) {/* check for control characters */if (c == '\n') {GUI_DispNextLine();} else {if (c != '\r') {GUI_LOCK();GUI_Context.pAFont‐>pfDispChar(c);//即调用void GUIPROP_DispChar(U16P c);if (GUI_pfDispCharStyle) {GUI_pfDispCharStyle(c);}GUI_UNLOCK();}}void GUIPROP_DispChar(U16P c) {int BytesPerLine;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 = 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 LCD_DrawBitmap(int x0, int y0, int xsize, int ysize, int xMul, int yMul,int BitsPerPixel, int BytesPerLine,const U8 GUI_UNI_PTR * pPixel, const LCD_PIXELINDEX* pTrans){U8 Data = 0;int x1, y1;/* Handle rotation if necessary */#if GUI_SUPPORT_ROTATIONif (GUI_pLCD_APIList) {GUI_pLCD_APIList‐>pfDrawBitmap(x0, y0, xsize, ysize, xMul, yMul, BitsPerPixel, BytesPerLine, pPixel, pTrans);return;}#endif/* Handle the optional Y‐magnification */y1 = y0 + ysize ‐ 1;x1 = x0 + xsize ‐ 1;/* Handle BITMAP without magnification */if ((xMul | yMul) == 1) {int Diff;/* Clip y0 (top) */Diff = GUI_Context.ClipRect.y0 ‐ y0;if (Diff > 0) {ysize ‐= Diff;if (ysize <= 0) {return;}y0 = GUI_Context.ClipRect.y0;#if GUI_SUPPORT_LARGE_BITMAPS /* Required only for 16 bit CPUs if some bitmaps are >64kByte */ pPixel += (U32) Diff * (U32) BytesPerLine;#elsepPixel += (unsigned)Diff * (unsigned)BytesPerLine;#endif}/* Clip y1 (bottom) */Diff = y1 ‐ GUI_Context.ClipRect.y1;if (Diff > 0) {ysize ‐= Diff;if (ysize <= 0) {return;}}/* Clip right side */Diff = x1 ‐ GUI_Context.ClipRect.x1;if (Diff > 0) {xsize ‐= Diff;}/* Clip left side ... (The difficult side ...) */Diff = 0;if (x0 < GUI_Context.ClipRect.x0) {Diff = GUI_Context.ClipRect.x0 ‐ x0;xsize ‐= Diff;switch (BitsPerPixel) {case 1:pPixel+= (Diff>>3); x0 += (Diff>>3)<<3; Diff &=7;break;case 2:pPixel+= (Diff>>2); x0 += (Diff>>2)<<2; Diff &=3;break;case 4:pPixel+= (Diff>>1); x0 += (Diff>>1)<<1; Diff &=1;break;case 8:pPixel+= Diff; x0 += Diff; Diff=0;break;case 16:pPixel+= (Diff<<1); x0 += Diff; Diff=0;break;}}if (xsize <=0) {return;}LCDDEV_L0_DrawBitmap (x0,y0, xsize, ysize, BitsPerPixel, BytesPerLine, pPixel, Diff, pTrans);} else {/**** Handle BITMAP with magnification ***/int x,y;int yi;int Shift = 8‐BitsPerPixel;for (y=y0, yi=0; yi<ysize; yi++, y+= yMul, pPixel+=BytesPerLine) {int yMax = y+yMul‐1;/* Draw if within clip area (Optimization ... "if" is not required !) */if ((yMax >= GUI_Context.ClipRect.y0) && (y <= GUI_Context.ClipRect.y1)) {int BitsLeft =0;int xi;const U8 GUI_UNI_PTR * pDataLine = pPixel;for (x=x0, xi=0; xi<xsize; xi++, x+=xMul) {U8 Index;if (!BitsLeft) {Data = *pDataLine++;BitsLeft =8;}Index = Data>>Shift;Data <<= BitsPerPixel;BitsLeft ‐= BitsPerPixel;if (Index || ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) ==0)) {LCD_PIXELINDEX OldColor = LCD_COLORINDEX;if (pTrans) {LCD_COLORINDEX = *(pTrans+Index);} else {LCD_COLORINDEX = Index;}LCD_FillRect(x,y, x+xMul‐1, yMax);LCD_COLORINDEX = OldColor;}}}}}}#define LCDDEV_L0_DrawBitmap GUI_Context.pDeviceAPI‐>pfDrawBitmapstatic void _InitContext(GUI_CONTEXT* pContext) {/* memset(..,0,..) is not required, as this function is called only at startup of the GUI when data is 0 */ #if GUI_SUPPORT_DEVICESpContext‐>pDeviceAPI = LCD_aAPI[0]; /* &LCD_L0_APIList; */#endifpContext‐>pClipRect_HL = &GUI_Context.ClipRect;LCD_L0_GetRect(&pContext‐>ClipRect);#if GUI_SUPPORT_AApContext‐>pLCD_HL = &_HL_APIList;#endifpContext‐>pAFont = GUI_DEFAULT_FONT;pContext‐>pClipRect_HL = &GUI_Context.ClipRect;pContext‐>PenSize = 1;/* Variables in WM module */#if GUI_WINSUPPORTpContext‐>hAWin = WM_GetDesktopWindow();#endif/* Variables in GUI_AA module */#if GUI_SUPPORT_AApContext‐>AA_Factor = 3;#endifpContext‐>Color = GUI_INVALID_COLOR;pContext‐>BkColor = GUI_INVALID_COLOR;LCD_SetBkColor(GUI_DEFAULT_BKCOLOR);LCD_SetColor(GUI_DEFAULT_COLOR);pContext‐>pUC_API = &GUI__API_TableNone;}const tLCDDEV_APIList* /*const*/ LCD_aAPI[] = {&LCD_L0_APIList#if GUI_NUM_LAYERS > 1,&LCD_L0_1_APIList#endif#if GUI_NUM_LAYERS > 2,&LCD_L0_2_APIList#endif#if GUI_NUM_LAYERS > 3,&LCD_L0_3_APIList#endif#if GUI_NUM_LAYERS > 4,&LCD_L0_4_APIList#endif};const tLCDDEV_APIList LCD_L0_APIList = {#if LCD_YMAG==1#if LCD_DELTA_MODELCD_L0_Color2Index,LCD_L0_Index2Color,LCD_L0_GetIndexMask,LCD_L0_DELTA_DrawBitmap,LCD_L0_DELTA_DrawHLine,LCD_L0_DELTA_DrawVLine,LCD_L0_DELTA_FillRect,LCD_L0_DELTA_GetPixelIndex,LCD_L0_GetRect, /* Original routine is o.k. here, since we use the logicalcoordinates for clipping, which are not magnified */ LCD_L0_DELTA_SetPixelIndex,LCD_L0_DELTA_XorPixel,LCD_L0_SetLUTEntry,#elseLCD_L0_Color2Index,LCD_L0_Index2Color,LCD_L0_GetIndexMask,(tLCDDEV_DrawBitmap*)LCD_L0_DrawBitmap,LCD_L0_DrawHLine,LCD_L0_DrawVLine,LCD_L0_FillRect,LCD_L0_GetPixelIndex,LCD_L0_GetRect,LCD_L0_SetPixelIndex,LCD_L0_XorPixel,LCD_L0_SetLUTEntry,#endif#elseLCD_L0_Color2Index,LCD_L0_Index2Color,LCD_L0_GetIndexMask,LCD_L0_MAG_DrawBitmap,LCD_L0_MAG_DrawHLine,LCD_L0_MAG_DrawVLine,LCD_L0_MAG_FillRect,LCD_L0_MAG_GetPixelIndex,LCD_L0_GetRect, /* Original routine is o.k. here, since we use the logicalcoordinates for clipping, which are not magnified */ LCD_L0_MAG_SetPixelIndex,LCD_L0_MAG_XorPixel,LCD_L0_SetLUTEntry,#endif#if GUI_SUPPORT_MEMDEVNULL, /* pfFillPolygon */NULL, /* pfFillPolygonAA */#if LCD_BITSPERPIXEL <= 8&GUI_MEMDEV__APIList8#else&GUI_MEMDEV__APIList16#endif#endif};void LCD_L0_DrawBitmap(int x0, int y0,int xsize, int ysize,int BitsPerPixel,int BytesPerLine,const U8 GUI_UNI_PTR * pData, int Diff,const LCD_PIXELINDEX* pTrans){int i;/* Use _DrawBitLineXBPP */for (i=0; i<ysize; i++) {switch (BitsPerPixel) {case 1:_DrawBitLine1BPP(x0, i + y0, pData, Diff, xsize, pTrans);break;#if (LCD_MAX_LOG_COLORS > 2)case 2:_DrawBitLine2BPP(x0, i + y0, pData, Diff, xsize, pTrans);break;#endif#if (LCD_MAX_LOG_COLORS > 4)case 4:_DrawBitLine4BPP(x0, i + y0, pData, Diff, xsize, pTrans);break;#endif#if (LCD_MAX_LOG_COLORS > 16)case 8:_DrawBitLine8BPP(x0, i + y0, pData, xsize, pTrans);break;#endif#if (LCD_BITSPERPIXEL > 8)case 16:DrawBitLine16BPP(x0, i + y0, (const U16 *)pData, xsize, pTrans);break;#endif}pData += BytesPerLine;}}static void _DrawBitLine1BPP(int x, int y, U8 const GUI_UNI_PTR *p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) { LCD_PIXELINDEX Index0 = *(pTrans+0);LCD_PIXELINDEX Index1 = *(pTrans+1);x += Diff;switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) {case 0:do {LCD_L0_SetPixelIndex(x++, y, (*p & (0x80 >> Diff)) ? Index1 : Index0);if (++Diff == 8) {Diff = 0;p++;}} while (‐‐xsize);break;case LCD_DRAWMODE_TRANS:do {if (*p & (0x80 >> Diff))LCD_L0_SetPixelIndex(x, y, Index1);x++;if (++Diff == 8) {Diff = 0;p++;}} while (‐‐xsize);break;case LCD_DRAWMODE_XOR:;do {if (*p & (0x80 >> Diff)) {int Pixel = LCD_L0_GetPixelIndex(x, y);LCD_L0_SetPixelIndex(x, y, LCD_NUM_COLORS ‐ 1 ‐ Pixel);}x++;if (++Diff == 8) {Diff = 0;p++;}} while (‐‐xsize);break;}}void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {ili9320_SetPixelIndex(x,y,PixelIndex);//TFTLCD写一个像素点。

UCGUI 简介

UCGUI 简介

UCGUI 简介译者:UCGUI邮箱:UCGUI@主页:版本:v1.0.0.01.0......UCGUI整体简介................UCGUI简介................本文档的目的...... .........前提学习要求.1.1.....要求...............目标硬件系统................开发环境(编译器).1.2.....UCGUI特性....... ........示例.1.3.....评估板.1.4.....如何使用本手册................印刷上的字体说明.1.5.....屏幕及坐标系统.1.6.....LCD控制器的连接类型.1.7.....数据类型.UCGUIUCGUI是一种嵌入式应用中的图形支持系统.它设计用于为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器的图形用户接口,它适用单任务或是多任务系统环境, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示.它的设计架构是模块化的, 由不同的模块中的不同层组成, 由一个LCD驱动层来包含所有对LCD的具体图形操作, UCGUI可以在任何的CPU上运行, 因为它是100%的标准C 代码编写的.UCGUI能够适应大多数的使用黑白或彩色LCD的应用, 它提供非常好的允许处理灰度的颜色管理.还提供一个可扩展的2D图形库及占用极少RAM的窗口管理体系.本文档的目的本文档描述如何在嵌入式应用中安装,配制,使用UCGUI的图形用户接口, 并讲解UCGUI的内部设计架构.前提本文档假定你已经备坚实的C语言程序设计方面的知识, 如果你觉得自己这方面还不够, 那么我们推荐Kernighan 和 Richie的"C语言程序设计"给你, 它描述了最新的C标准, 即ANSI C标准, 本文档不须要具备汇编语言方面的知识.第一章1.1 要求对于开发UCGUI图形应用不须什么目标系统, 大部分的图形应用开发都可以在模拟器下进行; 但是最终的目的是通常还是在目标系统上运行程序.目标系统(硬件)你的目标系统必须具备如下几点:[1].CPU(8/16/32/64位)[2].必要的RAM和ROM存储[3].LCD显示器(任何类型及分辩率的)对于内存的需求取决于你选用的UCGUI的功能模块以及你所使用的目标系统上的编译器的效率. 内存的占用量无法估计准确的值, 下面就一些的数值适用于多数的目标系统.小型系统(不含窗口管理功能)[1].RAM:100字节[2].堆栈:500字节[3].ROM:10~25K(取决于选用的UCGUI功能模块)大型系统(包含窗口管理及各种窗体控件功能)[1].RAM: 2-6 kb (决于选用的应用中建立窗口的数量)[2].堆栈: 1200 bytes[3].ROM: 30-60 kb (决于选用的UCGUI功能模块)还要注意ROM的需求量随着你在应用程序中使用的字体数目而增长,以上的所有值都是粗糙的估计, 并不准确.开发环境(编译器)目标系统中采用的什么样的CPU并不重要, 但必须要有与所用CPU相对应的C编译器,如果你所使用的编译器有什么局限性, 请联系我们, 我们会告知你这些局限性会不会在你编译程序时产生问题, 大多数的16/32/64位的CPU或DSP上的编译器都可以正常使用, 大部分8位的编译也都可以正常编译.并不须要C++编译器, 不过它也可以正常使用, 如果有须求的话, 应用程序也可以在C++环境下正常编译使用.1.2 UCGUI的特性UCGUI的设计目标是为使用LCD作为图形显示装置的应用提供高效的/与LCD控制器独立及处理器独立的图形用户接口. 它适合于单任务环境及多任务环境, 如私用的操作系统或是商业的RTOS(实时操作系统). UCGUI以C源码形式提供, 并适用于任意LCD 控制器和CPU下任何尺寸的真实显示或虚拟显示.它包含以下特性:一般特性[1] 适用任何8/16/32位CPU, 只要有相对应的标准C编译器.[2] 任何的控制器的LCD显示器(单色,灰度,颜色), 只要有适合的LCD驱动可用.[3] 在小模式显示时无须LCD控制器.[4] 所有接口支持使用宏进行配制.[5] 显示尺寸可定制.[6] 字符和位图可在LCD显示器上的任意起点显示,并不仅局限于偶数对齐的地址起点.[7] 程序在大小和速度上都进行了优化.[8] 编译时允许进行不同的优化.[9] 对于缓慢一些的LCD控制器, LCD显存可以映射到内存当中, 从而减少访问次数到最小并达到更高的显示速度.[10]清晰的设计架构.[11]支持虚拟显示, 虚拟显示可以比实际尺寸大(即放大).图形库[1] 支持不同颜色深度的位图.[2] 提供可用的位图转换工具.[3] 图形运算时绝对不含浮点运算.[4] 快速画点/线(不含浮点运算).[5] 高速画圆及多边形.[6] 多种画图模式.字体集[1] 为基础应用提供多种不同字体:4*6, 6*8, 6*9,8*8, 8*9, 8*16, 8*17, 8*18, 24*32, 以及8, 10, 13, 16等几种高度(象素单位)的均衡字体(proportional fonts). 更详细的信息, 请参考第25章:"标准字体".[2] 可以方便的加入及链接进自定义字体.[3] 只有应用程序中用到的字体被实际链接进最后的执行映象文件中, 因此保证占用最小数量的ROM.[4] 提供可用的字体转换工具.任何宿主系统(如微软windows系统)上的可用字体均可以经转换后使用.字符串/数值输出[1] 支持数值的任何字体下的十进制/二进制/十六制显示.[2] 支持数值的任何字体下的十进制/二进制/十六制编辑输入.窗体管理器[1] 齐全的窗口管理, 包括剪切, 在窗体客户区外[2] 窗体可以移动及改变大小.[3] 支持窗口回调函数(可选功能).[4] 窗体占用最低RAM(每个窗体占用20个字节).可选的类似PC机的窗体控件[1] 可用的窗体控件(窗体对象, 也称作控件), 操作简便而且容易使用.触摸屏及鼠标支持[1]对于窗体控件如按钮, UCGUI提供触摸屏及鼠标支持.PC下的工具[1] 模拟器及查看器.[2] 位图转器工具.[3] 字体转换工具.示范样例为了给你一个更好的关于UCGUI可以完成什么的概念. 我们编写了不同的可用范例程序, 执行映象文件在Sample\exe下, 源码码在Sample目录下. Sample\GUIDemo下包含了展示更多UCGUI特性的范围范例程序.1.3 评估板一个完整的评估板包括有LCD显示器的演示板/C编译器/完整的工程示例, 评估板的目的主要是测试和演示UCGUI, 并可以熟悉UCGUI的开发.评估板[1] 三菱M30803 CPU/SED 13705 LCD 控制器(包含图表及文档说明).[2] LCD(320*240 分辨率)单色, 1/4 VGA彩色显示或者TFT.更详细的说明, 请查看网站.1.4 如何使用此文档本文档介绍了如何安装、配制、使用UCGUI, 并描述了UCGUI的内部设计架构以及所有提供的功能(即应用程序开发手册, 简称API接口).在实际使用UCGUI之前, 你应该阅读或者至少概览一遍整个手册以对UCGUI有一个整体的认识, 建议按照以下的步骤进行UCGUI的学习:[1] 获取UCGUI源码到硬盘中.[2] 通读本文档第二章:"UCGUI开篇".[3] 使用UCGUI模拟器以慢慢熟悉用它可以做什么(参考第三章:"UCGUI模拟器").[4] 使用文档其它部分提供的知识扩展你的程序.文档排版中使用符号标志的约定[参看具体的E文档]风格作用[1] 正文.[2][3] API参数.[4] 程序示例源码.[5] 已经加入存在的应用中的源码.1.5 屏幕及坐标体系屏幕由许多可以单独控制的点组成, 这些点称为象素, 大部分UCGUI提供的文本显示及画图函数均可以在任意指定的点进行画写.水平刻度为X轴, 垂直刻度为Y轴. 由X轴及Y轴坐标组成(x,y)二维坐标来描述屏幕中一点, 在需要X,Y坐标的作为参数的函数中X坐标在Y坐标之前传递. 屏幕(或者窗口)左上角点的坐标为(0,0). X轴右方向为正, Y轴下方向为正. 上图描述了UCGUI中的会标体系及X轴Y轴. 所有传入API参数中的坐标值的单位均为象素.1.6 LCD显示器到微控制器连接方式UCGUI提供所有LCD的访问支持, 实际上对几乎所有LCD控制器的都能提供独立透明的访问支持. 了解详细情况, 请参考第20章:"初级UCGUI配制". 如果你的LCD控制器不被支持的话请与我们联系, 我们目前正在为市场上所有的的LCD控制器编写驱动, 也许我们已经可以提供你打算使用的LCD控制器的驱动. 通常的为你应用写访问LCD的驱动是非常简单的工作. 如果在你目标硬件中需要的话, MIcrium公司可提供专业化的用户支持服务.LCD显示器控制器是以何种方式连接到系统中以及它是如何被程序访问的都不重要, 通常可以有几种连接方法, 在驱动程序中提供实现大部分的相同访问接口. 驱动程序通常情况下无须做什么大的修改, 可以在LCDConf.h文件中进行适合你的硬件的配制修改. 有关如何配制的情况可参考在第22章:"LCD 驱动程序"中的解释说明. 最通常的LCD 访问方法如下所描述, 如果你只想知道如何使用UCGUI, 以下小节可跳过.[1] LCD控制器总线型连接LCD控制器直接连接到系统总线上, 即意味着可以象RAM一样访问它, 这是一种非常高效的访问方法, 是强烈推荐使用的方法. LCD显存地址定义在LCDSEG当中, 为了能访问LCD显存, 必须知道LCD显存在物理空间中的映射区域, 这种连接方式的不同LCD控制器的驱动通用的.[2] LCD控制器端口型连接对于速度缓慢一些的控制器使用在快速的处理器上, 使用端口连接方式是唯一的解决方案. 这种连接方法的缺点是访问LCD的速度比总线型连接慢, 不过加上访问缓存后可以最大化的提高LCD的访问速度, 从而使LCD画面更新不会明显的下降. 编写驱动时所要做的就是写出设置及读写与LCD控制器连接的硬件端口的宏. 这种连接方式对于不同的LCD控制器需要不同的驱动程序.[3] 无须控制器的连接LCD显示器也可以不用LCD控制器而直接连接到系统上, LCD显示数据可以直接通过一个4位或是8位的移位寄存器来传送, 这种方式的硬件解决方案的优点是成本低, 但是缺点是占用大部分的处理器时间, 其占用率在不同的CPU上从20%到差不多100%不等; 对于速度慢的处理器, 这是根本不能接受的. 这种连接方式根本不须要指定的驱动程序, 因为UCGUI只是简单的将要显示的数据传送到LCD显存当中, 其余就是编写周期性的将LCD显存中的数据传送到LCD中显示的硬件图形显示相关部分.样例中提供了用C及优化过的M16C及M16C/80汇编语言编写的传送显存中数据到LCD中显示的代码.1.7 数据类型因为C并没有提供在不同的平台中固定长度的数据类型, 所以UCGUI定义了大部分自己的数据类型如下表所示:数据类型定义注解位有符号整数char 8-bitI8 signed无符号整数char 16-bitU8 unsignedI16 signed short 16-bit 有符号整数U16 unsigned short 16-bit 无符号整数I32 signed long 32-bit 有符号整数U32 unsigned long 32-bit 无符号整数I16P signed short 16-bit 有符号整数U16P unsigned short 16-bit 无符号整数对于多数16/32位的定义都可以非常方便的设置, 如果你在自己的应用程序部分定义改变或是重新定义自己的数据类型,推荐放在LCDConf.h配置文件内.。

ucGUI添加自定义汉字字库

ucGUI添加自定义汉字字库

在uCGUI中添加自定义字体的方法
uCGUI 自带的字体文件中只包含英文及标点,想要显示中文字体最简单的方法便是自己动手添加。

先来看一下ucGUI 中自带字体文件的取模方式,如图1所示
其中用X 表示的部分是需要在屏幕上显示的一个像素点,下划线的部分则不显示,uCGUI 中自带的字体都是基于这个方法来显示的。

其实图1 中,每一个逗号前都是1 个字节的数据,所以我们可以将图1 的取模方式改为如图2 所示的情况,这样也是正确的,当然也可以改成全16 进制的表示方式,但显示效果没有图1 来的直观。

下面进入具体实现步骤。

步骤1:下载字体生成软件
步骤2:首先需要一个字体生成软件,该软件要能制作出如图1 所示的字体取模效果,我使用的是ucGUI 字体生成器V3.0,界面如图3 所示。

图三
步骤3:开始制作自己想要的字体文件
如图四所示
图四
步骤四:在GUI/Font文件夹中创建一个.c文件,这里定义为Font.c(文件名可以随意更改,只要不和库文件名冲突就可以)如图5所示
图5
步骤五:把Font.c添加到keil工程目录下,如图六所示
图六
步骤六:修改程序
将Font.c文件中里面的数组加上const修饰,如图七所示
图七
步骤七:在KEIL工程中找到GUI.H
在GUI.h中添加一段代码,声明数组,该数组名就是Font .c文件中的最末尾数组的数组名,如图八所示
图八
步骤八:调用GUI_SetFont(&GUI_FontHZ16)函数,如图九所示
图九
步骤九:编译,如果没有出现错误,就可以下载到开发板,显示效果如图十所示
图十。

UCGUI显示中文

UCGUI显示中文

UCGUI显示中文
最近用stm32搞个mp3,用的是ucgui,无奈不支持中文,找了半天资料发现一个可以直接的代码,发来给大家参考下
字库代码是《嵌入式系统设计与开发实例详解:基于ARM的应用》这本书里面的,方法是和ucgui显示字符一样的原理,所以可以直接调用GUI_DispStringAt();这类函数直接显示中文,非常方便,不过只有一种字体大小。

我已经做成单独的文件夹User_Font,只要调用里面的头文件“FHZK12GUI.H”就可以了,用的时候先要设置字体
GUI_SetFont(&GUI_FontHZ12);
GUI_DispStringAt("显示汉字1234",0,188);
这样就可以了
然后在上传该书的光盘源码吧,里面有书籍的图片吧,可以将就着看看
ucgui可以使用的汉字字库ourdev_639049NHGDRT.rar(文件大小:184K)(原文件名:User_Font.rar)
嵌入式系统设计与开发实例详解这本书的光盘源码和图片ourdev_639050PGR14R.rar(文件大小:147.41M)(原文件名:嵌入式系统设计与开发实例详解―基于ARM的应用.rar)。

uCGUI添加汉字库方法

uCGUI添加汉字库方法

一找到UCGUIGenApp.exe程序,并打开,界面如下
二选择要转换的字体,这里选择“华文中宋,加粗,22号字体”
三因为全部导出的话文件会很大,因此根据项目需要,只导出特定的汉字做字库。

选择“指定范围导出GBK码”,输入要导出的汉字,并点“确定”。

四点击“确定”后,会自动生成字库的C文件,位置和uCGUIGenAPP.exe相同。

五将文件“Text_37.c”拷贝到/GUI/Font里,并在Keil工程中添加这个文件。

六打开Test_37.c文件,可见字库名已经被定义为“GUI_FontHZ_Test_37”
七修改GUI.h文件。

找到GUI.h中的“Standard Fonts”块,并在下方添加字库名“extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ_Test_37;”。

注意“;”号必须加入。

八设置好后就可以正常使用了,比如在按键上加汉字。

5UCGUI学习资料-第17章Shift-JIS支持

5UCGUI学习资料-第17章Shift-JIS支持

第17章 Shift-JIS支持最通用的日文编码方法是Shift-JIS。

Shift-JIS编码使8位字符得到丰富的使用,第一个字节的值用来区别单字节和多字节字符。

你不需要调用特殊函数来显示一个Shift-JIS字符串。

最主要的必要条件是要有一种包含有用于显示的Shift-JIS字符的字体。

第1页µC/GUI中文手册17.1 创建Shift-JIS字体字体转换器能够从任何的Windows字体产生一种Shift-JIS字体用于µC/GUI。

当使用一种Shift-JIS字体时,用于显示显示Shift-JIS字符的函数会自动地与库链接。

关于如何创建Shift-JIS字体的详细信息,请联系Micrium公司(info@)。

一份单独的字体转换器的技术资料描述了所有你需要在你的µC/GUI工程中实现Shift-JIS的有效方法。

17.2 例子下面的例子定义了一种包括6个字符的小字体:“A”,“B”,“C”和Shift-JIS字符0x8350(片假名字母KE),0x8351(片假名字母GE)和0x8352(片假名字母KO)。

然后在显示屏上绘出一个复合字符串。

该例子的源代码是Sample\Misc\ShiftJIS.c。

/*-------------------------------------------------------------------------- 文件: ShiftJIS.c目的: 展示µC/GUI的ShiftJIS性能--------------------------------------------------------------------------*/#include “GUI.H”/*************************************************************************** * ShiftJIS字体的定义 * ***************************************************************************//* 拉丁文大写字母 A */static const unsigned char acFontSJIS13_0041[13] = { /* 编码0041 */________,________,___X____,___X____,__X_X___,__X_X___,__X_X___,_XXXXX__,_X___X__,_X___X__,XXX_XXX_,________,________};第2页µC/GUI中文手册/* 拉丁文大写字母 B */static const unsigned char acFontSJIS13_0042[13] = { /* 编码0042 */________,________,XXXXX___,_X___X__,_X___X__,_X___X__,_XXXX___,_X___X__,_X___X__,_X___X__,XXXXX___,________,________};/* 拉丁文大写字母 C */static const unsigned char acFontSJIS13_0043[13] = {/* 编码0043 */________,________,__XX_X__,_X__XX__,X____X__,X_______,X_______,X_______,X_______,_X___X__,__XXX___,________,________};/* 片假名字母KE */static const unsigned char acFontSJIS13_8350[26] = { /* 编码8350 */__XX____,________,___X____,________,___X____,________,___XXXXX,XXXX____,__X____X,________,_X_____X,________,X______X,________,______X_,________,第3页µC/GUI中文手册______X_,________,_____X__,________,____X___,________,__XX____,________,________,________};/* 片假名字母GE */static const unsigned char acFontSJIS13_8351[26] = { /* 编码8351 */__XX____,X_X_____,___X____,_X_X____,___X____,________,__XXXXXX,XXX_____,__X____X,________,_X_____X,________,X______X,________,______X_,________,______X_,________,_____X__,________,____X___,________,__XX____,________,________,________};/* 片假名字母KO */static const unsigned char acFontSJIS13_8352[26] = { /* 编码8352 */________,________,________,________,__XXXXXX,XX______,________,_X______,________,_X______,________,_X______,________,_X______,________,_X______,________,_X______,_XXXXXXX,XXXX____,________,________,________,________,________,________};static const GUI_CHARINFO GUI_FontSJIS13_CharInfo[6] = {{7, 7, 1, (void *)&acFontSJIS13_0041} /* 编码0041 */,{ 7, 7, 1, (void *)&acFontSJIS13_0042} /* 编码0042 */,{ 7, 7, 1, (void *)&acFontSJIS13_0043} /* 编码0043 */第4页µC/GUI中文手册,{ 14, 14, 2, (void *)&acFontSJIS13_8350} /* 编码8350 */,{ 14, 14, 2, (void *)&acFontSJIS13_8351} /* 编码8351 */,{ 14, 14, 2, (void *)&acFontSJIS13_8352} /* 编码8352 */ };static const GUI_FONT_PROP GUI_FontSJIS13_Prop2 = {0x8350 /* 第一个字符 */,0x8352 /* 最后一个字符 */,&GUI_FontSJIS13_CharInfo[3] /* 第一个字符的地址 */,(void*)0 /* 指向下一个GUI_FONT_PROP的指针 */ };static const GUI_FONT_PROP GUI_FontSJIS13_Prop1 = {0x0041 /* 第一个字符 */,0x0043 /* 最后一个字符 */,&GUI_FontSJIS13_CharInfo[ 0] /* 第一个字符的地址 */,(void *)&GUI_FontSJIS13_Prop2 /* 指向下一个GUI_FONT_PROP的指针 */ };static const GUI_FONT GUI_FontSJIS13 = {GUI_FONTTYPE_PROP_SJIS /* 字体类型 */,13 /* 字体高度 */,13 /* 字体Y轴方向的间隔 */,1 /* X轴方向放大系数 */,1 /* Y轴方向放大系数 */,(void *)&GUI_FontSJIS13_Prop1};/*************************************************************************** * 包含ASCII字符和ShiftJIS字符的字符串的定义 * ***************************************************************************/static const char aSJIS[] = {"ABC\x83\x50\x83\x51\x83\x52\x0"};/*************************************************************************** * 展示ShiftJIS字符的输出 * ***************************************************************************/void DemoShiftJIS(void)第5页µC/GUI中文手册{GUI_SetFont(&GUI_Font13HB_1);GUI_DispStringHCenterAt("μC/GUI-sample: ShiftJIS characters", 160, 0);/* 设置ShiftJIS字体 */GUI_SetFont(&GUI_FontSJIS13);/* 显示字符串 */GUI_DispStringHCenterAt(aSJIS, 160, 40);}/*************************************************************************** * 主函数 * ***************************************************************************/void main(void){GUI_Init();DemoShiftJIS();while(1)GUI_Delay(100);}范例程序运行结果的屏幕截图第6页µC/GUI中文手册。

UCGUI移植

UCGUI移植

文件chinese:汉字字库Font:字库Core:核心文件,提供了GUI基本的功能AntiAlias:9个C文件ConvertColor:彩色显示的色彩转换支持ConvertMono:(b/w)和灰度显示的色彩转换支持。

MenDev:Memory device 支持。

这个东西可用在很多情况下,但最主要的功能是防止在项目重叠时,防止屏幕的闪烁。

Touch:触摸屏Widget:窗体控件库Wm:窗口库LCDDriver:1个C文件gui:config:LCDConf.hLCD_XSIZE (320)LCD长LCD_YSIZE (240)LCD宽LCD_BUSWIDTH (16)总线宽度LCD_FIXEDPALETTE (565) TFT格式LCD_SWAP_RB 1 是否红蓝交换LCD_BITSPERPIXEL 16 (Bpp)位深:每个像素占用位数GUIConfig.hGUI_OS 多任务支持GUI_SUPORT_MENDEV menory devices 支持GUI_SUPORT_TOUCH 触摸屏支持GUI_SUPORT_UNICODE UNICODE支持GUI_MAXTASK 任务数GUI_ALLOC_SIZE 320*240 动态内存GUI_DEFAULT_FONT 默认字体修改LCDDriver 中c文件,实现LCD_L0_Init()初始化、LCD_L0_Set_PixelIndex()画点、LCD_L0_Get_PixelIndex()读取点值、LCD_On()、LCD_Off()GUI_TOUCH_DriverAnalog.cGUITouchConf.hGUI_TOUCH_SWAP_XY ()XY交换GUI_TOUCH_MIRROR_X X取反GUI_TOUCH_MIRROR_Y Y取反GUI_TOUCH_AD_LEFT最左侧AD转换值GUI_TOUCH_AD_RIGHT最右侧AD转换值GUI_TOUCH_AD_TOP 顶部AD转换值GUI_TOUCH_AD_BOTTOM 底部AD转换值改GUI_X_TOUCH.c,实现GUI_TOUCH_X_MeasureX()读取X方向AD转换值、GUI_TOUCH_X_MeasureY()读取Y方向AD转换值查询方式:专门开一个任务不停调用GUI_TOUCH_Exec()(此函数有去除抖动功能)中断方式:读取X、Y的AD转换值,看AD转换值是否合法(X在最左、最右之间,Y在最上、最下之间),不合法,GUI_TOUCH_StoreState(-1,-1)。

在ucgui例程中添加自定义汉字库的步骤指南

在ucgui例程中添加自定义汉字库的步骤指南

奋斗版 STM32 开发板文档———在 uCGUI 例程中添加自定义汉字库的步骤指南在 uCGUI 例程中添加自定义汉字库的步骤指南在奋斗STM32开发板光盘里的资料目录下有一个《ucgui中文字体生成》目录,这个目录 下就是制作ucgui自定义字库的软件。

运行UCGUIGenApp.exe执行文件, 显示如下根据需要选择字体 ,例如如下选择好字体后, 并在输入你定义的文件名, 比如 ,显示如下,如果要生成一个小的自定义字库,可以点击淘宝店铺:1奋斗版 STM32 开发板文档———在 uCGUI 例程中添加自定义汉字库的步骤指南在对话框输入你需要在ucgui中可能出现的的中文或者西文字符。

不要有重复的字符。

比如按确定后,就可以生成一个自己定义的小汉字库simsun16.c。

然后用MDK打开ucgui例程工程, 在工程里添加font组项。

并添加simsun16.c进 去。

工程里添加示意如下打开simsun16.c,发现这个小汉字库名被定义为GUI_FontHZ_SimSun_21然后在 gui.h里添加红色部分文字。

/* Digits */ extern GUI_CONST_STORAGE GUI_FONT GUI_FontD24x32; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD32; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD36x48; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD48; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD48x64; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD64; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD60x80; extern GUI_CONST_STORAGE GUI_FONT GUI_FontD80;淘宝店铺:2奋斗版 STM32 开发板文档———在 uCGUI 例程中添加自定义汉字库的步骤指南/* Comic fonts */ extern GUI_CONST_STORAGE GUI_FONT GUI_FontComic18B_ASCII, GUI_FontComic18B_1; extern GUI_CONST_STORAGE GUI_FONT GUI_FontComic24B_ASCII, GUI_FontComic24B_1;/*自定义小字库*/ extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ_SimSun_21;然后就可以用ucgui各种部件的定义字体的函数来定义相应字体。

ucgui怎样实现字库与程序空间分离

ucgui怎样实现字库与程序空间分离

ucgui怎样实现字库与程序空间分离ucgui怎样实现字库与程序空间分离⽇志原⽂:/people/!MjFza3lAc29odS5jb20=/68028621.htmlucgui作为⼀个强⼤的GUI系统,现在嵌⼊式设备的开发上应⽤的越来越多了,现在对于在这套系统上的中⽂⽀持,控件功能扩展等⽅⾯的资料也很多,有兴趣的朋友可以到论坛⾥转悠⼀下,收获⼀定不少的。

在Arm上利⽤这套GUI系统⼯作的时间也短了,现在也给⼤家说说⾃⼰的⼀些应⽤吧。

⼤家都知道,程序与数据分离开对于开发还是维护都很有必要的,反正本⼈就很讨厌为download⼀个程序花上⼏分钟或上10分钟的时间的。

ucgui提供⼀个字库的⽣成叫字体转换器软件,能⽅便的把window上的字库转换为满⾜ucgui要求的c⽂件(当然俺可不保证可随便盗版⽤MS的字体哦),⽣成的c⽂件格式⼤概为下⾯的形式GUI_CONST_STORAGE U8 acFontHZ16x16_0020[] ={________,________,...};......GUI_FLASH const GUI_CHARINFO GUI_FontHZ16x16_CharInfo[] ={{ 9, 9, 2, (void GUI_FLASH *)&acFontHZ16x16_0020 },...};......GUI_FLASH const GUI_FONT_PROP GUI_FontHZ16x16_Prop_a1 ={0xa1a1,0xa1fe,&GUI_FontHZ16x16_CharInfo[96],(void *)&GUI_FontHZ16x16_Prop_a2};GUI_FLASH const GUI_FONT_PROP GUI_FontHZ16x16_Prop_ASC ={0x0020, // first character0x007f, // last character&GUI_FontHZ16x16_CharInfo[0], // address of first character(void *)&GUI_FontHZ16x16_Prop_a1 // pointer to next GUI_FONT_PROP};GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16x16 ={GUI_FONTTYPE_PROP_SJIS, // type of font16, // height of font16, // space of font y1, // magnification x1, // magnification y(void GUI_FLASH *)&GUI_FontHZ16x16_Prop_ASC};如果想⼤改动的去修改Edit或Text控件关于显⽰字模的代码的话,本⼈觉得会有些难度并且没这个必要其实我们在调⽤ucgui显⽰的时候需要指定到底⽤哪个字库显⽰GUI_SetFont(&GUI_FontHZ16x16);在这⾥我们主要修改的就是GUI_FontHZ16x16改为⼀个⾮const类型变量,⽽把GUI_FONT结构(void GUI_FLASH *)指向的所有内容变成⼆进制⽂件都放在固定的数据地址就可以了,接着怎样把固定的那部分内容⽣成⼀个⼆进制⽂件呢?打开你的ADS,把GUI_FLASH const GUI_FONT_PROP GUI_FontHZ16x16_Prop_ASC以上所有的数组变成const类型存放为⼀个.c⽂件const GUI_FONT g_ResourceAddress = {&GUI_FontHZ16x16_Prop_ASC,};GUI_FONT * dbc_WindowsListAddr(void){return (GUI_FONT *)&g_ResourceAddress;}当然你还要设置⼀下Simple image的开始位置偏移地址.最后就是在程序中要把GUI_FontHZ16x16的GUI_FLASH *的指向到固定的flash位置就可以咯...。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于ucgui的字库1、在UCGUI中有两种类型字体, 一种是等宽字体(Monospaced Font),即字体当中所有字都是同一宽度,它在UCGUI中的相应结构体是GUI_FONT_MONO, 一种是均衡字体(Proportional font), 这种字体中的字都有自己独立的宽度, 字体内的每个字都可以有不同宽度, 它在UCGUI中的相应结构体是GUI_FONT_PROP, 对于等宽字体, 一般都是将所有字的点阵存放在一个数组中, 因为每个字都宽度相同. 对于均衡字体, 则要单独用数组来定义每个字符的点阵, 然后将每一个字符的宽高及点阵存为一个数组即字符信息(ucgui中对应结体为GUI_CHARINFO), 所有字符信息再存到一个数组当即称为字符集, 它包含每个字的字符信息(点阵高宽及一行占几个字节), 所谓一行占几个字节, 是指这个字体的点阵每一行有多少个字节, 它与宽度高度单位不同, 宽度高度的单位是象素数.2.另外特别指出的是, 在等宽字体中不仅所有字符宽度相同,高宽也是相等的; 对于均衡字体, 不仅可以宽度不同, 高度也可以不同, 每一行有多少个字节自然也不同, 在均衡字体中每一个字符都单独定义之后才组成字体的字符集.3.字符集的问题, 在UCGUI中每种字体含的字符集不同, 这个可以参看UCGUI手册中的"Standard Font"一章,这一章中对于字符集有如下描述:ASCII: Only ASCII characters 0x20-0x7E (0x7F).[仅包含0x20-0x7E这个范围内的ansii字符]1: ASCII characters and European extensions 0xA0 - 0xFF.[除0x20-0x7E这个范围内的ansii字符, 还有0xA0 - 0xFF这个范围内的欧洲字符集, 这里要指出美国英语只用到0x20-0x7E, 它只考虑了自己的须求, 没有考虑其它国家的须求, 在欧洲是有拉丁字符的, 所以欧洲国家扩展了剩余的0xA0 - 0xFF这个范围内的来表示欧洲的字符集, 其实我们国家的汉字也是在这个范围内扩展的, 不过我们用的是二个字节来表示一个汉字, 是因为汉字太多, 这区区94个值无法满足汉字的须求, 94*94就差不多了. 汉字用到的第一个值为0xb0a1(啊), 最后一个为0xf7fe(齄), 在机内码1当中只用到a1+15~a0+86这个范围的, 关于机内码是这个意思: 对于"啊"字模,机内码:(0xb0,0xa1), 0xb0为"啊"字的机内码1,0xa1为机内码2. 对于机内码2合使用是0xa1~0xff这个范围内的所有值, 关于机内码及汉字显示的原理及汉字库的构成, 本论坛中有专门的一篇文章介绍--"ucgui中处理汉字显示的说明",请查看此贴, 这里不多说了, 所以范围是这样确定的.]HK: Hiragana and Katakana[日文平假名与片假名].1HK: ASCII, European extensions, Hiragana and Katakana[ansii,欧洲字符集,日文平假与片假].D: Digit fonts[数字及运算符号集].以上的ASCII/1/HK/1Hk/D都是字符集的简单代号.3. 回过头来再看你的GUI_Font__21_Prop2,GUI_Font__21_Prop1. 那么很容易理解,GUI_Font__21_Prop2是欧洲字符集, 范围当然是0xa0-0xff. GUI_Font__21_Prop1中存的是ASCII字符集. 至于GUI_Font__21_CharInfo中则存的是全部的字符集的点阵信息, 包含所有字符信息. 最后, 将字体中包含的所有字符集用链表连接起来. 再将这个链表头指针存到字体结构(GUI_FONT)中的存放均衡字体的指针(constGUI_FONT_PROP* pProp)当中, 这样在处理字符的显示, 可以在这链表中查找所要显示的字符是在哪一个字符集中, 从而找到它的字符信息(即点阵数据及宽高).typedef struct {GUI_DISPCHAR* pfDispChar;GUI_GETCHARDISTX* pfGetCharDistX;GUI_GETFONTINFO* pfGetFontInfo;GUI_ISINFONT* pfIsInFont;tGUI_ENC_APIList* pafEncode;U8 YSize;U8 YDist;U8 XMag;U8 YMag;union {//此联合处存放均衡或是待宽字符集信息...void *pFontData;const GUI_FONT_MONO* pMono;const GUI_FONT_PROP* pProp;} p;U8 Baseline;} GUI_FONT;在GUI_Font__21_Prop1中的(void GUI_FLASH *)&amp;GUI_Font__21_Prop2/* pointer to nextGUI_FONT_PROP */在GUI_Font__21_Prop2中的(void GUI_FLASH*)&amp;GUI_Font__21_Prop3/* pointer to nextGUI_FONT_PROP */在GUI_FONT_MONO当中的成员next就是指向一下字符集的...这个链表是人工写成的.....链表最后一个成员的next指向空....这个链表的构造, 其实还是为了使用, 所以要理解它, 就要理解是如何用的.均衡字体的显示, 是在GUIPROPAA_DispChar这个函数中处理的, 要理解链表的构造就要理解这个函数,下面做简要的分析....void GUIPROPAA_DispChar(U16P c) {int BytesPerLine;GUI_DRAWMODE DrawMode = GUI_Context.TextMode;const GUI_FONT_PROP* pProp =GUIPROP_FindChar(GUI_Context.pAFont-&gt;p.pProp, c);if (pProp) {GUI_DRAWMODE OldDrawMode;const GUI_CHARINFO* pCharInfo =pProp-&gt;paCharInfo+(c-pProp-&gt;First);BytesPerLine = pCharInfo-&gt;BytesPerLine;OldDrawMode = LCD_SetDrawMode(DrawMode);Draw ( GUI_Context.DispPosX, GUI_Context.DispPosY,(pCharInfo-&gt;XSize+1)/2,GUI_Context.pAFont-&gt;YSize,BytesPerLine,(U8 const*) pCharInfo-&gt;pData);LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */GUI_Context.DispPosX += (pCharInfo-&gt;XDist+1)/2; }}而理解GUIPROPAA_DispChar的重点, 就是要理解它当中调用的用来寻找要显示的字符的字符信息的函数GUIPROP_FindChar, GUIPROP_FindChar主要是寻找字符所在的字符集(其实这个字符集在汉字应用当中,有些不同.在hzk12.c中, 作者是将汉字接区来分集的, 下面我们以hzk12.c中的构造来讲解字符集链表:hzk12.c 中共分成(0xa1a1~0xa1fe),(0xa2a1~0xa2fe)...(0xf7a1~0xf7fe)共分成86个字集, 另外加上(0x0020, 0x007f)这个ANSCII字符集, hzk12.c中的链表中就其有87个字符集, 这里的字符集的意义就不再是一个标准的字符集了, 而只能称之为字符的集合而已, 没有严格意义上的字符集的意思).hzk12.c中, 字符集链表构成为: 字符集链表第一个元素为ascii字符集,第二个为机内码处于(0xa1a1~0xa1fe)间的汉字集, 最后一个为(0xf7a1,0xf7fe)....了解了汉字库的这个字符集链表的构成, 那么现在来看一下如何寻找一个要显示的字符处于哪个字符集当中, 找了那个字符集才能找到这个字符的字符信息....static const GUI_FONT_PROP* GUIPROP_FindChar(constGUI_FONT_PROP* pProp, U16P c) {for (pProp = GUI_Context.pAFont-&gt;p.pProp; pProp; pProp=(const GUI_FONT_PROP*) pProp-&gt;pNext) { if ((c&gt;=pProp-&gt;First) &amp;&amp;(c&lt;=pProp-&gt;Last))break;}return pProp;}GUIPROP_FindChar 其实就是查找字符的机内码是位于哪个字符集之间, 比如寻找"啊"字, 机内码为0xb0a1,那么由上查找, 就可以知道它是位于链表中第16(0xb0-0xa1=16)个字符集(机内码处于0xb0a1~0xb0fe)当中, 那么就返回这个字符集的指针. 找到了要显示的字符所处的字符集, 再根据:const GUI_CHARINFO* pCharInfo =pProp-&gt;paCharInfo+(c-pProp-&gt;First);c-pProp-&gt;First即为该字符在此字符集中的偏移,pProp-&gt;paCharInfo为该字符集中第一个字符地址...这样就找到了要显示的字符的字符信息了(宽高及点阵数等), 理解了这个过程, 那么反过来理解这个字符集为何要如此构造, 就比较容易了...比如说: 为什么要将汉字分成86个字符集合? 这是由于汉字的机内码并没有用到所有的0xffff--xa1a1=0x5e5e中连续的值, 而是间断的, 0xa1a1~0xa1fe用到了, 0xa200~0xa2a1这段当中的值不能用(因为机内码2小于0xa1了), 只能用0xa2a1~0xa2fe, 所以这个特性决定了汉字的机内码分布是显区段的, 不能用一个单一的GUI_FONT_PROP结点来表示出所有的字符集, 因为汉字是区间分布的, 不是连续的.比如说, 如下所示:GUI_FLASH const GUI_FONT_PROPGUI_FontHZ12_Propa1= {0xa1a1,0xfefe,&amp;GUI_FontHZ12_CharInfo[ 96],(void *)&amp;GUI_FontHZ12_Propa2};用以下一个结点来表示所有汉字, 如同ACSII, 那么我们分析一下它为什么不可以:首先对于区间(0xa1a1~0xa1fe)这第一个区间, 在以上的结构下, 这个区间内的字符还是能够正确找到所要显示的字符信息. 但对于(0xa2a1~0xa2fe)这个区间的,pProp-&gt;paCharInfo+(c-pProp-&gt;First)显然无法找到字符信息. 这是GUI_FontHZ12_CharInfo这个所有字符信息集数组的结构决定的, 因为汉字未用的区间的在它上面没有体现, 它上面存放的是将分隔开的汉字区间连在一起的, 这样你就无法根据pProp-&gt;paCharInfo+(c-pProp-&gt;First)来找到字符的位置了....[ucgui原创]在UCGUI中增加汉字显示的说明.在UCGUI中增加汉字显示的说明.作者: ucguiemail: ucgui@home: 版本: v1.0.0.1UCGUI中本身只支持E,没有提供中文的字库的.C源码文件, 但是我们可以通过下面的方式来实现汉字的显示...我们知道, 在DOS下经常利用点阵来显示汉字. 带汉字显示的程序,很多都会自己带上汉字库, 这个字库里放的就是每个汉字的点阵.一. 汉字的显示原理之一-----------------点阵汉字.简单的理解, 所谓一个字的点阵. 其实就是指这个汉字用多少个象素点来描述. 每个象素点显示为什么颜色, 通常情况下, HZK16采用的是16*16点阵, 即256个象素点描述一个汉字.这些点的颜色分为两种, 一种是前景色, 一种是显示为背景色.那么,关于那些点显示为前景色, 那些点显示为背景色, 是如何得知的呢??可以这样来考虑, 你在纸上比较正正方方的写一个规则的楷字, 然后在这个字的从上到下,左到右, 分别画十七条直线,那么这个字就被放置于一个16*16的方格之内, 这样我们就可以很明显的看出, 16*16的方格内的具体哪些点有笔划经过, 有笔划经过与没笔化经过的即就是应该被分别填充上前景色与背景色的点.现在,找到了一个汉字的点阵, 那么还须要用数据来记录点阵的信息, 通常情况下, 我们会用32个字节来表示16*16点阵的汉字, 即每一行用二个字节来记录十六个象素点的色色彩情况, 0表示背景色, 1表示前景色. 16行其须要32个字节. 点阵汉字的原理同时也决定了它的缺点, 他不具务放大特性, 因为它的显示是基于被定死的点阵, 放大后, 会产生明显的锯齿,非常的难看, 当然, 可以进行一些光滑处理, 但基本上没有多在的改观.但点阵汉字简易, 对于复杂汉字, 它比矢量显示汉字法更快带.矢量显示是基于记录汉字的笔化的. 对于简单的汉字它比较占优势, 容易放大处理. 但对于复杂的汉字, 表示起来, 则笔化太多..复杂.二. 关于字库的建立及其原理.现在讲完了汉字点阵. 也说了一个汉字点阵的存放方式, 但具体的点阵如何存放, 读者也应该了解.通常情况下, 一般的DOS下的程序都会提供一个汉字库, 这样在脱离汉字平台(如UCDO)的支持下也可以进行汉字显示, 但是这样会存一个问题, 就是如果每个DOS下的程序员都这么做的话, 就会造成一定的磁盘空间浪费. 所以有的DOS 下的程序,针对自己所需要的汉字, 就会定制自己的小型字库, 那么字库的制作到底应该如何进行呢? 下面我们将就这个问题进行一些基本的讨论.众所周知,一个ASCII字符占一个字节,它的数值从0到255, 那么汉字字符将如何与ASCII 字符区别开来呢?实际上,仔细观察ASCII字符表,从第161(即0xa1)个字符开始,后面的字符并不经常为E文所使用。

相关文档
最新文档