仪器软件中大字体数值参数显示处理

标题:仪器软件中大字体数值参数显示处理

作者:Favory.peng (2010/5/11)

 

在监护仪或其他医疗仪器中为了让测量的参数显示的更加醒目通常会用到一些很大的数字字体进行显示,这些数字点阵字库通常会占据很大的存储空间,对于嵌入式系统中资源很吃紧的情况下将是一笔不小的开销(这个也许不是什么大问题啦),但另一方面在显示这些大的测量参数时,一点点的画到屏幕参数显示区域效率非常之低;为了解决这一问题,我将告诉大家一个简单的点阵字库压缩存储和快捷显示的方法。

下图数字“8”的点阵为例:

我们可以用存储线条的方式来分解存储这个点阵,一个字节表示一个段线条(长度在128点之内),其中bit7表示该点的内容是黑还是白(0/1)及前景还是背景,后面的7bit6~bit0存储连续相同的点的个数及线段长度;

由于数字的点阵结构比较简单,这种简单的压缩存储的方法将大大减少大字点阵库的存储空间。

另外用这种存储结构的点阵时,在进行点阵显示时也将大大的提高显示效率,我们可以利用画线条的方法进行点阵字库的显示,在大多LCD屏的控制器指令中都会对横向线条(显存连续)的绘制进行优化,至少省去了需要送显示地址的时间消耗。

点阵字库结构定义

Byte1:点阵类型标识(0-横向,1-竖向)

Byte2:字符的个数

Byte3:首字符编码

Byte4:点阵字符高度

Byte5:点阵字符宽度

Byte6~Byte10:保留位

Byte11~Byte50:字符点阵索引表(2个字节表示一个字符点阵起始位置,支持20个字符)

Byte51~Byte N:字符点阵数据段

点阵字符显示函数处理流程

1、根据首字符编码计算字符点阵索引位置

2、读取字符点阵索引信息,读取字符点阵数据

3、判断首位,若是前景以像素数为长度画直线,画满字符宽度长度后Y +1X回首位

注意:在有些显存分区的平台中,需对画线函数进行优化,判断显存分区信息,若在分区交界,分两段直线绘制;

 

后记:虽然这篇技术含量不高,但这个ideal不错,希望对有类似应用的朋友有所帮助....

文件名: LedDisp.h 版本号: v1.0.5 (v20091122.00001) 功能: 显示七段数码管风格的数字、小数点、冒号及部分字母。 (此版本理论上可用于MFC,Win32 SDK或其它环境,在Windows XP sp2下用vc6.0及vs2008编译、运行通过.) 第一作者: Jef 日期: 20091122 电子邮件: dungeonsnd@126.com 地址: 中国/江苏 版权: 1.您可以修改及免费使用本程序,但把本程序或修改后程序用于商业用途前请先通知第一作者并得到作者的许可。 2.修改之后保留此文件开头处的文件说明信息并更改副版本号(如 v20090825.00001 改成 v20091002.00001 ), 并拷贝一份附上您的个人信息发送到上面的作者邮箱,作者负责在全面测试后发布您修改后的新版本。 3.您使用本程序而导致任何伤害以及经济损失,由过错方依法承担所有责任,一概与第一作者及合作单位无关。 4.如果您使用本程序则表示您已经同意此版本协议!否则请勿使用! 其它: v1.0.1 (v20090825.00001) v1.0.2 (v20091026.00001) 1.增加Hide()方法 2.增加IsHide()方法 3.增加Disp(CDC* pdc,CRect DispRect,int iDigitsAmount,CString cs);方法 4.等 v1.0.3 (v20091031.00001) 1.增加多个小数点和冒号显示支持 2.增加GetLedFont()方法 3.修改了显示熄灭数码管的内部实现 4.等 v1.0.4 (v20091105.00001) 1.修改了SetSegmentPosition(int index)函数,增加内部属性 修正因子m_bMakeAmend, 设置修改因子为真时,在特殊情况下(如用户设置段宽度为2个像素或者1个像素), 程序将保证所有段的宽度相等,并且保证段与段不会相连. 2.修改了保存显示区域背景机制! 前一版本在调用数码管显示函数(Disp()等函数)时会自动 保存一幅对应于显示区域RECT的位图,此种机制当用户在OnPaint()函数里调用显示 函数而不调用Hide()时,并且此时的RECT在每次调用显示函数时都改变,则会导致保存 背景位图的向量m_vecBkSave不断扩大,而实际上保存的位图将没有作用且浪费大量内存! 如: void CLEDView::OnPaint() { CPaintDC dc(this); OnShow(); //不断的以不同的RECT区域调用Disp()将导致保存的 //位图(对应于每个区域)数量剧增! } void CLEDView::OnShow() { CClientDC dc(this); CRect rtClient; GetClientRect(&rtClient); double m_x =rtClient.Width()/800.0; double m_y =rtClient.Height()/600.0; CRect rt0; rt0.SetRect(20*m_x,10*m_y,220*m_x,410*m_y); led.Disp((CDC*)&dc,rt0,1,_T("1:")); } 解决方案: 保存位图将不再以RECT来标识,而是以一个用户输入的字符串来标识. 3. 添加MFC之外框架的支持.(未完成,未测试,希望测试的用户给作者联系测试结果.如WIN32 SDK,WTL等环境下.) v1.0.5 (v20091122.00001) 1. 增加UNICODE支持 2.完成MFC外的某些框架的支持 3.修改了和完善了某些代码段。如 删除保存背景的 向量某一元素之前先把其中的位图删除; 内存dc用完之后添加删除操作 DeleteDC ; 构析函数中增加了删除 全部位图资源操作 4. 修改了数个变量名使其更统一,如 SHOWPOS改成了iShowPos; 删除了某些接口,如 DispInt(); 2.说明及注意 (Attention!) a.支持 改变数码管亮时的颜色 灭时颜色 区域背景色,支持居左居中居右显示,支持细调显示的位置(SetFont();)及数码管粗细等细节. 支持距离左或右一定距离显示字符串(m_iDistaceToRight). 支持创建不定数量的自定义字体(LedFontID来表示已创建的不同字体,已经创建过的字体被再次创建时则改写这个字体). 支持默认参数(调用时可以依次不传递有默认值参数). b.显示的字符的宽度与高度不随窗口的大小变化而自动变化,故调用者应自行处理. c.内部不含自动重画功能,故调用者应自己处理窗口重绘时字符的重新显示. d.字符串内可同时含 ":"与"." ,但字符串左起第一个字符不能为":"或"." ,且不能连续两个不点位符号,如小数点或冒号!! e.能显示的字符包括 0-9,a-f,A-F,".",":","-" f.如 bool Disp(HDC hDc,RECT rtDispRect,TCHAR* cs,int iFontWidth,int iFontHeight,TCHAR* strIdentifier=_T("LedValue1")); 用户应自己设置好 rtDispRect与iFontWidth iFontHeight 的大小关系. 如果iFontHeight大于rtDispRect.Height(),则超出DispRect区域显示字符. 但左右可能不会超出显示(用户可设置m_bShowWhenOverstepRect来控制是否显示). 调用者应自己保证使字符串能全部显示在DispRect中,否则超出部分可能不会显示!!! g.当字符的宽度与数码管的每一段的宽度比例严重失调时,显示的字符会严重失真(如数码管每一段宽度为5个像素, 而长度却也为5像素则显示效果将失真)! 一般情况下,iFontHeight=2*m_iFontWidth,m_dSegmentWidth远小于m_iFontWidth h. led.SetColor(RGB(0,200,0)) 等方法会改变类的字体属性,故之后调用显示字体属性都会发生改变. 但创建新的字体时不会改变类的字体属性. i.调用 Disp(...,strIdentifier)等此类数码管显示函数显示数码管后, 显示区域的背景及区域会自动保存. 1.再次调用Disp(...,strIdentifier)时会用新的显示区域的背景替换原背景及区域; 2.调用Hide(...,strIdentifier)方法时程序会自动删除strIdentifier对应原位图及区域,然后隐藏该区域的数码管(用原背景位图贴在此区域); 3.对象析构时会自动删除已经保存的所有的背景位图及区域. 3.使用方法(仅举一种使用方法) (Using e.g.) i. void CLEDView::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here OnShow(); // Do not call CView::OnPaint() for painting messages } void CLEDView::OnShow() { // TODO: Add your command handler code here CClientDC dc(this); CRect rtClient; GetClientRect(&rtClient); CBitmap bmp; bmp.LoadBitmap(IDB_BITMAP1); CDC memdc; memdc.CreateCompatibleDC(&dc); memdc.SelectObject(&bmp); dc.StretchBlt(0,0,rtClient.Width(),rtClient.Height(),&memdc,0,0, 800,600,SRCCOPY); double m_x =rtClient.Width()/800.0; double m_y =rtClient.Height()/600.0; CRect rt0; rt0.SetRect(int(20*m_x),int(10*m_y),int(420*m_x),int(80*m_y)); CString s; s ="123-:1:."; TCHAR str[256]; sprintf(str,"%s",s); led.DispDigits((HDC)dc,rt0,str,7,_T("Led1")); } void CLEDView::OnHide() { // TODO: Add your command handler code here CClientDC dc(this); led.Hide((HDC)dc,"Led1"); } ii. CClientDC dc(this); ...... CRect rt0; rt0.SetRect(int(20*m_x),int(10*m_y),int(420*m_x),int(80*m_y)); CString s; s ="123-:1:."; led.Disp_mfc((CDC*)&dc,rt0,s,27,45,_T("Led1")); */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值