QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: yg_sun

我想问问关于linux显示字体的问题

[复制链接]
发表于 2004-10-14 16:40:06 | 显示全部楼层
所以你上面说得应该也没错。
一般的应用程序参考locale里面的设置来理解编码格式,格式跟实际不一致时就会显示乱码。像mozilla它能够正确理解多种编码格式,所以基本上不会出现乱码。
当然,具体能不能显示出来还得最终靠字体的支持亚。
回复

使用道具 举报

 楼主| 发表于 2004-10-14 17:27:25 | 显示全部楼层
请举例说明一下输入和输出吧,这块讲得比较模糊,格式化输入输出后,系统内只需处理系统内码编码的字符,也举一下例子吧!
还有locale的感觉好像是虽然支持多种语言,但一旦选择一种语言并指定编码后,就完全本地了,向你说的如果locale是en的话,那如果应用程序不能处理编码,他就不能正确现实非en的字符。那你后面说的内码,也应该是把当前语言(比如en)的多种编码转换,就是只能转换某种特定语言的多种编码。
我还想问的是,像gnome这样的,根据locale的不同就能显示多种语言,怎么做到的,倘若我有世界上所有的语言(假设为n)的字体,那是不是在编写gnome的时候,要写出n个版本的gnome。
最后,我想知道在编写应用程序,你所用的字符,比如说应用程序的标题,我用拼音或英文写“你好“/“hello”,那他们用什么编码的,好像用c写程序时没注意过,是编译器负责编码,还是系统来做。
回复

使用道具 举报

发表于 2004-10-14 18:28:22 | 显示全部楼层
1.通过键盘和鼠标的输入因为有操作系统的参与还不能很好理解。但如果我们以文件作为输入的话应该能看得很清楚,因为文件是可以很方便的人为预定为某种编码格式的。通过尝试不同编码格式的文件在不同locale上的显示情况可以很方便的验证我们的理解。具体而言就是那gedit在不同的locale下读不同的编码文件看结果。输出也可以用相似的例子阿。
关于内码实用性的例子也好说,比如我们有一个程序用来去掉字符串中的第一个字符。现在有两个人在不同的locale下使用我的程序:一个人在iso8859-1下输入abc(616263),程序应该返回bc(6263)对吧;另一个人在gb2312下输入一二三(D2BBB6FEC8FD),我们应该给她返回二三(B6FEC8FD)。程序在得到编码后就分别转化为(610062006300)和(004E8C4E094E),现在编码都是两字节代表一个字符了,简单的移掉前两个字节就得到结果了,在将编码转换回去就行了。


2.兄台好像没说到点子上,locale=语系_地区.{编码}才对。
如果locale=en_US.ISO8859-1的话,那的确不能显示非英文字符;
但我的locale=en_US.UTF-8,所以我的系统能够显示那些非英文字符。
你应该能理解这点吧。
一个locale已经指定了编码格式,所以只对应一种与内码的相互转换关系(有一个系统文件专门定义这种转换关系)。我说的转换也只是locale中的编码与系统内码的相互转换,同语系地区的多种locale编码之间的转换系统应该不关心,我猜虽然系统完全有可能做到这一点。
比如说gb2312与utf-8都能编码简体汉字字符,但是系统只根据locale来理解你的输入,gb2312编码的文件在我的locale下才会不能正常现实,因为系统试图使用utf-8/内码的转换关系来转换gb2312到内码,显示的时候他会拿反转换(内码/utf-得到的utf-8做编码格式去请求字形,所以才会出现乱码。

3.没有到n个版本的gnome那么夸张,但是有n个资源字符串的so文件却是肯定的。通过locale来使用合适的so资源文件就可以拉

4.你编写代码中的输入会变成什么编码格式的这个应该由编译器提供的选项来决定。比如就我所知的微软c++编译器,有_UNICODE宏,使用的时候是会将字符串资源编译成unicode。
回复

使用道具 举报

 楼主| 发表于 2004-10-14 20:47:44 | 显示全部楼层
兄台好像没说到点子上,locale=语系_地区.{编码}才对。
如果locale=en_US.ISO8859-1的话,那的确不能显示非英文字符;
但我的locale=en_US.UTF-8,所以我的系统能够显示那些非英文字符

准确地说,是有可能现实中文字符,因为有可能中文不是UTF-8的编码。
是不是那个en_US是说明系统内,比如说gnome应该使用UTF-8中的英文部分,而其他部分只要是UTF-8编码的,并有对应字体的就能正常显示。
至于你说的处理文件的问题,如果我用gedit之类的可以处理部分编码的情况,是不是就不用经过locale的编码/内码转换了。
我用mozilla浏览网页的时候,我用adsl,到网通主页察看使用时间的时候,有部分是乱吗,我想那就应该是网页中的那部分编码,不能被mozilla处理,与locale无关吧。
我记得如果默认语言选择中文,在console中有些地方不能正确显示英文,这是怎么回事。console下的字符显示,是什么过程。
回复

使用道具 举报

发表于 2004-10-15 10:21:33 | 显示全部楼层
我只能说自己的理解未必就是全对了,但我可以尝试用我的理解来解释我们所看到的各种现象:如果能够解释得通,只能印证理解可能没错;但如果解释不通,那就说明我的理解存在偏差,还需要进一步的探讨。
看看论坛里关于中文化和显示的问题,基本上我都还能解释得通,说明我的理解应该比较接近背后的原理了。兄台以为如果呢?我觉得这种学习的过程就是猜测与验证不停交换进行的过程,所以我很高兴去试图解释你说提出的这些疑问,希望能够再发现一些我理解上的漏洞。

关于纯console(启动X之前就存在的那种),它的显示应该与X无关。你说默认语言选择中文,在console中有些地方不能正确显示英文? 我觉得比较奇怪,纯的console使用固定的字体,不存在缺字的情况,中文显示不出来还正常,英文显示不了就太奇怪了。你能不能说说你的i18n文件里的设置。
回复

使用道具 举报

 楼主| 发表于 2004-10-15 11:08:18 | 显示全部楼层
我说的问题比较普遍,就是在i18n中,设置语言为zh时,比如说ls -l时,月份部分显示为乱码,我原来的rh9也是这样,有人说export LANG=C LC_CTYPE=C 能解决,不过我是过了,还是乱码,不信你可以在你的fedora下体会一下,我知道在fedora1下默认语言设为中文,console下会出现乱码。
那我们可以断定,应该与locale有关吧。首先console字体肯定没问题,因为在默认英文下能正常显示,所以应该是编码的问题吧,用英文时默认是utf-8,在中文下是gb18030为什么会出现部分乱码?我想因为console下的字体是那种早期的bitmap的字体,会不会在这种字体的gb18030的编码上存在bug,所以会处乱码?
我想起你问问你,你用过windowmaker吗,我最近在用,不知道怎么汉化,好像与locale无关,而且好像系统自带的应用程序(gnome..)都会依赖于locale。
回复

使用道具 举报

发表于 2004-10-15 11:44:23 | 显示全部楼层
export LANG=C LC_CTYPE=C并不能解决问题.
如果要时间显示不为乱码的话应该是export LC_TIME=C
另外控制台下出现乱码很正常, 应该现在的linux控制台还不支持中文。中文当成了扩展ascii码来显示,也就是那些乱码。在虚拟终端下就不会有这样的问题。为什么可以有n个语言版本的gnome了, 因为现在大部分的支持国际化的软件都使用gettext(libintl)这个库, 在软件初始化时它会根据当前的locale调入当前软件的mo文件,这个文件一般位于/usr/share/locale/LOCALE/LC_MESSAGES/目录中, LOCALE用具体的locale代替如zh_CN。另外程序运行时也可以改变自己的locale, 不过现在还不能做到即时改变程序界面的locale,因为这是在初始化时进行的,要实现这样的功能也有点困难。因此, 程序界面的语言一旦程序运行起来之后就不能改变了, 也就是说一个运行中的中文化的gedit不能通过改变它的locale让它变成英文界面, 只能够退出gedit,设定locale后再重新运行gedit。 gedit能够使用多种编码是因为程序可以自己进行编码转变,有相应库支撑的。
1.1.1. Locale环境
Locale的命名规则:<语言>_<地区名>.<字符编码名称>

对于zh_CN.GB2312而言,zh表示中文,CN表示大陆地区,GB2312表示使用的字符集为GB2312。

Locale使用一组分类,用户可以独立的操纵每一组分类。用户既能用设置环境变量的方法,也能使用setlocale设置它们。这些分类都保存在/usr/share/locale下。它们包含了:

LC_COLLATE
用于比较和排序。
LC_CTYPE
用于字符分类和字符串处理,控制所有字符的处理方式,包括字符编码,字符是单字节还是多字节,如何打印等。
LC_MONETORY
用于格式化货币单位。
LC_NUMERIC
用于格式化非货币的数字显示。
LC_TIME
用于格式化时间和日期。
LC_MESSAGES
用于控制程序输出时所使用的语言,主要是提示信息,错误信息,状态信息, 标题,标签, 按钮和菜单等。
LC_ALL
它不是环境变量,只是一个宏,可使用setlocale设置所有的LC_*环境变量。这个变量设置之后,可以废除LC_*和LANG的设置值,使得这些变量的设置值与LC_ALL的值一致。
LANG
它的值用于指定上面环境变量没有设置的所有变量值。如果指定了上面任何一个变量的值,则会废除对应的LANG值的缺省设置。
回复

使用道具 举报

发表于 2004-10-15 11:46:35 | 显示全部楼层
兄台,我可不如你呀,我学用linux也才不过半个多月,尝试过的东西很少
我是搞软件的,所以才会从感兴趣的国际化本地化以及编码和显示入手,因为windows下这些很容易就被忽略了。
所以实际上很多东西我都还得向你请教阿,不过你好像也没用linux很长时间啊,呵呵。

还是讨论问题吧
console的字体显示是什么概念我也不清楚,不过有几点应该是可以肯定的:
1.console下的显示不存在找字体这样的步骤,显示所用的字体应该是预设好的某种固定点阵字体(你可以预设它的大小,颜色等),但根据编码从字体文件里面找字来画这个步骤肯定还是有的。
2.不管你怎么改你的locale设置,你的文件和目录名字的编码肯定不会随着改变是不是,我坚信文件和目录名应该是以系统内码存放的。
3.为什么en下正常而zh下不正常,我们可以尝试zh的locale下的虚拟终端中的显示,相同locale下,console和vterm的shell输出的字符串编码肯定是一样的。不过两种方式下画字的过程不一样罢了。我猜虚拟终端应该没问题你说对吧。

然后你看两者之间的区别在什么地方呢?所以我觉得你猜测的系统出问题的地方应该没错!细节原因应该还可以探讨..下午继续吧
我想因为console下的字体是那种早期的bitmap的字体,会不会在这种字体的gb18030的编码上存在bug,所以会处乱码?
回复

使用道具 举报

发表于 2004-10-15 12:06:59 | 显示全部楼层
在linux系统中,一般采用utf8作为系统内码,因此它是可以支持任何语言的,这是linux国际化的基础。
1、控制台它不支持中文,当然中文就显示为乱码,这很简单。只要你使用支持中文的locale(不一定是zh_*),系统就能正确的处理中文,虽然它显示出来的是一堆乱码。与字体没有关系。不过打过unicon补丁的内核就能正确的显示中文了。建议看些以前苏哲写的资料。
2、文件和目录名的编码是由你的locale来决定的, 不信你可以试试。
3、这个不知道你在说什么。。
另外说一句,控制台下的字体没有gb18030的(不是指X的终端)。这里并没有什么bug。要控制台下显示中文可以使用zhcon, cce等。
回复

使用道具 举报

发表于 2004-10-15 13:44:00 | 显示全部楼层
多谢兄台出来指点..
系统内码是utf-8我也看到有人说过,不过不太肯定,utf-8作为变长编码,处理字符串岂不是很不方便,多字节到宽字节字符的转换还是必需的吧?

1.这点我很同意,不过那位老兄说他的部分英文也出现乱码,不太好解释。打补丁显示中文的原理我很感兴趣,待会就去找来看看。多谢了

2.文件和目录名的编码是由locale来决定的还是固定格式我想很容易证明,以我为例,en_US.UTF-8的locale下创建一个文件,改名为中文,然后改变locale为
zh_CN.GB18030,看看文件名能否正常显示,如果真的不能正常显示的话就说明我猜错了.vfat文件系统下的文件目录名都是unicode格式的。

3.我的意思很简单,同样的locale下分别用控制台和虚拟终端察看你的文件和目录名的显示,控制台显示不对而虚拟终端显示正常的情况下,因为他们要显示的内容的编码是一样的,只不过字体的支持不一样而已。
回复

使用道具 举报

发表于 2004-10-15 13:52:54 | 显示全部楼层
3、它们的编码肯定是一样的。。。
回复

使用道具 举报

发表于 2004-10-15 14:27:55 | 显示全部楼层
在 XFree86 窗口系统中实现对 GB18030 的支持(一)
http://www-900.ibm.com/developerWorks/cn/linux/i18n/gb18030/xfree86/part1/index.shtml
在 XFree86 窗口系统中实现对 GB18030 的支持(二)
http://www-900.ibm.com/developerWorks/cn/linux/i18n/gb18030/xfree86/part2/index.shtml
GB18030-2000 标准在 Linux 上的实现
http://www-900.ibm.com/developerWorks/cn/linux/i18n/gb18030/index.shtml
只有编码相关文章3篇。
回复

使用道具 举报

 楼主| 发表于 2004-10-15 17:38:22 | 显示全部楼层
文件名到底是系统内码存放的还是根据locale改变,我认为文件在创建后编码就不能改变了,所以在编写linux的时候,应该会用比较流行的编码如utf-8之类的,也就是说毕竟是外国人的杰作,对中文编码的支持会出现问题。在显示的时候,系统会根据locale(比如gb18030)进行内码的转换,可是可能那些字符本身是别的编码(比如utf-,所以会出现乱码。
2.文件和目录名的编码是由locale来决定的还是固定格式我想很容易证明,以我为例,en_US.UTF-8的locale下创建一个文件,改名为中文,然后改变locale为
zh_CN.GB18030,看看文件名能否正常显示,如果真的不能正常显示的话就说明我猜错了.vfat文件系统下的文件目录名都是unicode格式的。

我觉得你这种方法试不出来,因为以内码存放,这个内码也是有某个编码转换的,当输出时以另一种编码输出肯定不能正常显示。从另外一个角度,比如gnome-terminal本身可以处理一部分编码,也就是说他可以不经过内码-编码这些步骤,所以如果文件名以内码存放,那gnome-terminal怎么能处理呢?
回复

使用道具 举报

发表于 2004-10-16 00:45:09 | 显示全部楼层
兄台,我刚试过了,文件和目录名的确是由locale所定义的格式编码的。是我错了,那位老兄说得对!

1. 我在utf-8的locale下创建文件夹,重命名为‘中文’,然后改locale为gb18030,重启后浏览到该路径,location栏里面显示的正是utf-8编码‘%E4%B8%AD%E6%96%87’转化为unicode正是‘中文’二字的编码'4E2D8765'!
2. 我还不死心,说不定utf-8正是系统内码呢?然后将文件夹重新命名为‘中文’,再把locale转回为utf-8,最后看到文件夹名称的编码为‘D6D0CEC4’,正好对应gb码的'中文'两字.

图我懒得贴了,明天再重新总结吧.
回复

使用道具 举报

发表于 2004-10-16 00:49:21 | 显示全部楼层
看看这个你应该有印象吧。上午就有人碰到这样的问题,被我重现了,呵呵。
我在gb18030的locale下浏览我的windows分区。
utf-8就没问题。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-7 15:37 , Processed in 0.040621 second(s), 14 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表