首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>linux 内核>文章内容
Linux操作系统核心的汉字显示机制
来源:http://www.unix5.com 作者:linuxfans 发布时间:2008-04-28  

 

sw->con putcs(vc_cons[currcons].d, 

(u16 *)draw_from, (u16 *)draw_to_ 

(u16 *)draw_rwom, Y, draw_x);

之所以要调用底层驱动程序,是因为存在不同的显示设备,其对应VGA显存的存取方式也不一样。 上面的Sw->con_putcs()就会调用fbcon.c中的fbcon_putcs()函数(con_putcs是一个函数的指针,在 Framebuffer模式)下指向fbcon_putcs()函数,也就是说,在do_con_write()函数中是直接调用了 fbcon_putcs()函数来进行字符的绘制,比如说在256色模式下,真正负责输出的函数是:

 

void fbcon_cfb8_putcs(struct vc_d 

ta *conp,struct display *p, const
 unsignde short *s, int count, int YY, int xx )

显示中文

比如说我们试输出一句中文:putcs(你好 ”)(“你好”的内码为0xc4.0xe3.0ba.0xc3)。这时候会怎么样呢?有一点可以肯定,“你好”肯定不会出现在屏幕上,原因是:

1、核心中没有汉字字库,中文显示就是无米之炊了。

2、在负责字符显示的void fbcon_cfb8_putcs()函数中,原有操作如下:

对于每个要显示的字符,依次从虚拟终端缓冲区中以WORD为单位读取(低位字节是ASCII码,高8位是字符的属性)。由于汉字是双字节编码方式,所以这种操作是不可能显示出汉字的,只能显示xxxx_putcs()输出的是一个一个的VGA字符。

因此,要解决的问题:确保在调用do_con_write()时进行uni_pc转换不会改变原有编码,一个很直接的实现方式就是加载一个我们自己定制的 Unicode映射表,loadunimap dirdct.uni,或者进接把direct.uni设置为核心的缺省映射表。

针对以上问题,我们要做的第一个尝试方案如下:

首先需要在核心中加载汉字字库,然后修改fbcon_cfb8_putcs()函数,在fbcon_cfb8_putcs()中一次读两个WORD,检查这两个WORD的低位字节是否能拼成一个汉字,如果发现能拼成一个汉字,就算出这个汉字在汉字字库的的偏移,然后把它当成个16×16的VGA字符来显示。

试验的结果表明:

1、能够输出汉字,但仍有许多不理想的地方,比如说,输出以半个汉字开始的一串汉字,则这半个汉字后面的汉字都会是乱码,这是“半个汉字”的问题。

2、光标移动会破坏汉字的显示,表现为,光标移动过的汉字会变成乱码,这是因为光标的更新是通过xxxx_putc()函数来完成的。

xxxx_putc()函数与xxxx_putcs()函数实现的功能够类似,但是xxxx_()函数只刷新一个字符而不是一个字符串,因而xxxx_putc()的输入参数是一个整数,而不是一个字符串的地址,xxxx_putc()函数的声明如下:

 

void fbcon_cfb8_putc(struct vc_data 
*conp, struct display *p, int c, int YY, int xx)

下一个尝试方案就是同时修改xxxx_putc()函数和xxxx_putc()函数为了解决半个汉字的问题,每一次输出之前,都从屏幕当前行的起始位置开始打措,以确定要输出的字符是否落在半个汉字的位置上,如果是在半个汉字的位置上,如果是在半个汉字的位置,则进行相应的调整,即从向前移动一个字节的位置开始输出。vhYLinux联盟

这个方案有一个困难,即xxxx_putc()函数不用缓冲区的地址,而是用一个整数作为参数,所以xxx_putc()无法直接利用相邻的字符来判别该字符是否是汉字。

解决方案是,利用xxxx_putc()的光标们置参数(yy,xx),可以逆推出该字符在缓冲区中的位置,但仍一些小麻烦,在Linux的虚拟终端下,用户可能会上卷该屏幕(Shift+Pageup),导致光标的y座标和相应字符在缓冲区的行数不一致,相应的解决方案是,在逆推的过程中,考虑在屏的参量。

这样一来,我们就又进了一步,得到了一个相对更好的版本。但仍有问题没有解决,敲入turbonetcfg,会发现菜单的边框字符也被当成汉字显示,这是因为,这种边框字符是扩展字符,也使用了字符的低8位,因而被当成汉字显示,这是因为,这种边框字符是扩展字符,也使用了字符的低8位,因而被当作汉字来赤示。例如,单线“—”的制表符内码为0xC4,当连成一条长线时就是由一连串0xC4组成的,而0Xc4c4正是汉字“哪”,于是水平的制表符被一连串的“哪”字替代了,因为制表符的种类比较多,而且垂直制表符与其后面字符的组合形式又多种多样,因而很难判断出相应位置的字符是不是制表符,从理论上说,无论采取什么样的排除算法,都必然存在误判的情况,因为总存在二义性,没有充足的条件来推断出当前字符究竟是制表符还是汉字。

共4页: 上一页 [1] 2 [3] [4] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
·Linux内核对I/O端口的管理实现(
·深入分析 Linux操作系统的内核链
·Linux内核可装载模块对设备驱动
·概述Linux系统的驱动框架及驱动
·详解Linux 2.6内核新文件系统变
·Linux系统可卸载内核模块完全指
·FreeBSD手册讲解(一)--配置FreeB
·编译Linux操作系统的内核讲解
  相关文章
·Linux操作系统“警惕”内核汉化
·如何利用异常表处理Linux内核态
·简析Linux与FreeBSD的syscall
·Linux下的中文显示和支持常见问
·如何在Linux内核中的实现SYN Coo
·Linux内核源代码学习概述
·Linux系统内核漏洞分析
·深入学习LINUX内核之七(图文讲解
·深入学习LINUX内核之六(图文讲解
·深入学习LINUX内核之五(图文讲解
·深入学习LINUX内核之四(图文讲解
·深入学习LINUX内核之三(图文讲解

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!