QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2334|回复: 29

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

[复制链接]
发表于 2004-10-9 00:39:26 | 显示全部楼层 |阅读模式
xserver,xclient,字符编码,字体,字体引擎等等,他们是怎么相互协调才把字显示出来的。
最好描述一下整个过程。
是,xclient把一些需要显示的字的编码发给xserver,xserver通过字体引擎找到相应字体(字体引擎怎么知道用那个字体,是不是有什么配置文件),在显示吗。
字体引擎都有什么,我用的是fedora2,用的什么字体引擎呀!
平常说的编码如gbk,utf8等,设置不好就会显示乱码,是不是字体引擎不支持,跟字体有关吗?
还有gb2312,gb1080什么的,使编码方式吗?
我在这个部分比较迷惑,还请多多指教!
发表于 2004-10-12 10:45:16 | 显示全部楼层
正好我也用FedoraCore2,正在摸索中,一起探讨吧。


xserver和xclient之间的协作方式我不太清楚,好像是分了好几种。
我现在的理解程度只能到:
1.locale是支持国际化和本地化的基础,linux系统中能够支持本地化的应用都会根据locale设置对自己的输入和输出字符的编码格式进行调整。当然locale的设置也分了好几种,其中比较重要的是LC_CTYPE,LC_MESSAGE等,它们是可以分开设置成不同的格式的。
2.字体是支持屏幕显示的最重要的依赖,因为输入输出的字符最终要以某种字体的形式显示到屏幕上。
一种字体应该是与编码格式无关的,像中文就有很多种编码格式GB2312,GBK,GB18030,还有UTF-8,但字体应该只需一份就够了。也就是说一旦你拥有了某种字体,就应该拥有它所支持的多种编码格式,该字体所支持的格式应该是说明在字体文件内部的。
3.字体集的概念好像是几种字体的集合,用多语言的混合显示,比如说中英文。这个概念我不太理解,一个应用的输入输出应该是一种编码格式的吧,比如说GB2312,应该同时编码了中英文,是怎么能够做到让其中的中文部分显示一种字体,然英文部分现实另一种字体呢?请大家给我讲讲吧。
4.上面所说的应用程序如果是基于X的应该就算Xclient,Xclient根据locale送出字符的编码,并同时指明一种字体/字体集(我觉得用何种字体显示应该是应用自己的事情,系统(应该就是xServer,X之外的应用应该没有字体的概念吧)只需要提供它所支持的全部字体供应用从中选择就行了,所以我们可以看到一般应用程序都给用户提供选择显示的字体这样的功能)。然后XServer根据编码和所选用的字体去字体路径中寻找合适的**(该怎么称呼?)并显示到屏幕上,所以字体引擎应该在这一步发挥作用。
回复

使用道具 举报

发表于 2004-10-12 11:21:22 | 显示全部楼层
我是一名软件工程师,所以以软件工程师的角度来抽象和理解linux关于本地化支持的原理。当然还有很多问题,请大家指正。因为初学linux,所以很多地方具体涉及到什么配置或文件我都不清楚。

我现在的系统情况是这样的:默认英文(en_US.UTF-,没有装中文的支持包。安装成功后Gnome不能显示中文的目录和文件,然后我加了simsun和tahoma等几种字体,只用了下面的几条命令:
#1.拷贝字体到linux
mkdir /usr/share/fonts/addin
cp /mnt/wind/addin /usr/share/fonts/addin
#2.创建fonts.scale和fonts.dir,并拷贝encodings.dir
cd /usr/share/fonts/addin
mkfontscale
mkfontdir
cp /usr/X11R6/lib/X11/fonts/encodings/encodings.dir ./
#3.添加字体路径
chkfontpath --add /usr/share/fonts/addin
基本上就是论坛里面大家说的,但少了很多步。重启后进Gnome设置 首选项-性能-字体 除了最后一项虚拟终端没动,其它都改为tahoma。
然后Gnome就能够浏览中文了。启动mozilla进linuxfans居然也能正常看到中文。

我想不通,我用的locale是英文en_US.UTF-8,为什么有了中文字体就能浏览中文了?
linuxfans网页的encoding是GB2312,为什么我还能正常看到。请问这个正常吗?

zh_CN.UTF-8和en_US.UTF-8的locale是不是在处理编码方面是一样的,不同的是时区,日期表示等?如果能使用UTF-8处理中文,为什么我们还需要zh_CN.GB18030这样的locale呢?
回复

使用道具 举报

发表于 2004-10-12 18:48:52 | 显示全部楼层
zh_CN.UTF-8和en_US.UTF-8的locale是不是在处理编码方面是一样的,不同的是时区,日期表示等?如果能使用UTF-8处理中文,为什么我们还需要zh_CN.GB18030这样的locale呢?

可以这样认为,zh_CN表示使用中文的界面(语言环境),utf8就是编码方式了
在字体文件中,每个字形(也就是我们所说的“方块字”)在文件中的偏移量是有规定的,
比如偏移量0A代表字形“大”,0B代表“小”,当然这个是在字体文件中的定义,不管用什么样的locale,都要根据这个偏移量从字体文件中读取字形。
再来看一般的文件,比如文本文件。文本文件里并没有保存字形,而是保存字的代号。比如“大小”在文本文件里实际上就是“C1D1”这样的代号。
但是最终要把这样的代号所表示字形显示出来,这样就用到了locale。
locale实际上就是的字体中的偏移量(字形)和文件中的代号的对应关系。
比如代号“C1”对应着字体偏移量0A的字形,“D1”对应着0B,那么当打开包含“C1D1”的文件的时候,就可以看到“大小”这两个字。
如果“C1”对应着0B,“D1”对应着0A,那么看到的将是”小大“这两个字。如果对应是其他的对应关系,那么看到的就可能是乱码。一种locale就是一种这样的对应关系。
回复

使用道具 举报

发表于 2004-10-12 23:27:16 | 显示全部楼层
恩,从编码到字形之间的转换过程非常有趣。

关于字体文件,我们以simsun为例子来讨论吧,应该是同时至少包含了英文字符和汉字字符吧,并且每个字符的字形在文件中应该是只有一份吧。根据simsun.ttf文件生成的fonts.dir有如下的内容:
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-ascii-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb18030.2000-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb2312.1980-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gbk-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso10646-1
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso8859-15
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso8859-1
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-koi8-r
是不是很能够说明一个字体文件能够应用到很多中编码格式下呢?

你说通过在文件中的某种偏移量来取到对应的字形我非常赞同,但是从编码到字形的转换关系真的就是在locale中么, 那么各种字体文件中字形的偏移量都必须是一致的吧?因为对于某种特定的编码格式,不管使用什么字体,字形所代表的字符的编码应该是一样的啊。

已知:
1.从编码到字形的转换关系在locale中
2.通过偏移量从字体文件中读到编码所对应的字形
推论:
不同的字体文件中字形的偏移量必须一致

请指教!
回复

使用道具 举报

发表于 2004-10-12 23:30:34 | 显示全部楼层
剩下的明天再想吧,晚了
回复

使用道具 举报

发表于 2004-10-13 09:59:40 | 显示全部楼层
我观察过几种中文字体的结构,发现他们里面的的字形的顺序是相同的,字体文件的技术协议上应该对此有所说明。
locale的算法定义是在基础运行库中完成的,用来设置的变量都只是“标志”。
我只看过一点代码,具体的过程我也不清楚。
回复

使用道具 举报

发表于 2004-10-13 10:19:05 | 显示全部楼层
看看这一段内容(比较老了,时间是2001年9月):
原文出处:http://www-900.ibm.com/developerWorks/cn/linux/sdk/install/part2/index.shtml
1.1. 国际化的基本概念
国际化(Internationalization,简写为I18N)是指软件在设计结构和机制上支持多语言的扩展特性,其功能和代码设计不针对某一特定语言和地域。Locale是ANSI C语言中最基本的支持国际化的标志,对中文Linux来说,支持中文Locale是最基本的要求。

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值的缺省设置。



还可以包括其他的环境变量LC_ADDRESS,LC_IDENTIFICATION,LC_PAPER,LC_NAME,LC_TELEPHONE,LC_MEASUREMENT。

标准Locale:

"C"
这是标准的C Locale。它所指定的属性和行为由ISO C标准所指定。它是程序启动时缺省使用Locale。

"POSIX"
这是标准的POSIX Locale。它是标准的C Locale的别名。

""
空名字是让程序选择当前环境设置值。

设置一个中文环境需要正确的设置上述Locale变量,举例来说,在使用zh_CN.GB2312环境时,使用locale命令,所见到的系统环境为:

   LANG="zh_CN.GB2312"
    LC_CTYPE="zh_CN.GB2312"
    LC_NUMERIC="zh_CN.GB2312"
    LC_TIME="zh_CN.GB2312"
    LC_COLLATE="zh_CN.GB2312"
    LC_MONETARY="zh_CN.GB2312"
    LC_MESSAGES="zh_CN.GB2312"
    LC_PAPER="zh_CN.GB2312"
    LC_NAME="zh_CN.GB2312"
    LC_ADDRESS="zh_CN.GB2312"
    LC_TELEPHONE="zh_CN.GB2312"
    LC_MEASUREMENT="zh_CN.GB2312"
    LC_IDENTIFICATION="zh_CN.GB2312"
    LC_ALL=






1.1.2. 创建Locale环境

为了建立locale环境,我们必须具备下面的描述文件:
locale-data
这个文件定义了Locale环境(LC_*)的所有细节,包括字符的分类与转换,字符排序,区域显示时间,货币显示格式等等。通常是保存在系统的/usr/share/i18n/locales目录下。

charmap
这个文件定义了Locale中所有字符与内码的对应关系。通常是保存在系统的/usr/share/i18n/charmaps目录下。

这两个文件都是纯文本文件,可以使用文本编辑器直接察看和修改。通过这两个文件就可以生成对应的locale环境。缺省条件下,生成的locale环境是以二进制的形式保存在/usr/share/locale目录下。把这两个文本文件生成locale环境的工作是由localedef程序实现的。举例来说,生成zh_CN.GB2312的locale环境:

mkdir /home/usr/share/locale/zh_CN.gb2312
localedef -I zh_CN -f GB2312 zh_CN.GB2312 --prefix=/home
cd /home/usr/share/locale/
mv zh_CN.gb2312 zh_CN.GB2312





这几条命令在/home目录下,生成Locale环境zh_CN.GB2312。因为按照POSIX标准,一个Locale的编码名称是大小写无关的。虽然我们指定的是大写的GB2312,但是glibc为了统一起见,它会生成一个小写的编码名称。但是由于很多程序依赖于zh_CN.GB2312,因此对这个文件进行了改名。

除了Locale环境之外,您还需要gconv文件。这一组文件是用来定义glibc的gconv系统在遇到GB2312编码的字符时,应使用哪一个模块来处理。gconv-modules文件描述了字符编码和处理模块文件对应关系。例如,在/usr/lib/gconv/gonv-modules文件中,需要包含下列行:
alias GB2312// EUC-CN//

1.1.3. X Window系统的多语言环境
X Window系统的多语言环境是在系统底层libc的Locale架构的基础上建立起来的。X函数库需要利用libc提供的函数来进行字符之间的转换。因此,为了使X Window应用程序的Locale正确工作,您必须首先设置一个正确的libc Locale环境,同时正确设置LC_CTYPE这个类别。

指定了编码方式并且将字符的辨识和转换用libc的函数处理之后,X Window系统的多语言处理的主要问题就变为图形显示和输入了。在X系统下,多语言环境必须能做到多语言字符图形化输出和字符输入。字符的图形化输出还要处理字型,这又与字型的设定方式有关。

与libc一样,在X Window系统下也有关于Locale的设置部分,称为X-Locale。XFree86系统都把它保留在/usr/X11R6/lib/X11/locale目录下。在这个目录下的每个Locale都有一个目录,存放各自的X-locale,一般这个文件的名字是XLC_LOCALE。这个文件里面包含了跟该区域编码相关的设定,而文件中以#字号开头的是注释。以安装程序上简体中文XLC_LOCALE的内容为例:

XLC_FONTSET
#   fs0 class (7 bit ASCII)
fs0 {
    charset {
        name    ISO8859-1:GL
    }
    font    {
        primary     ISO8859-1:GL
        vertical_rotate all
    }
}
#   fs1 class
fs1 {
    charset {
        name    GB2312.1980-0:GL
    }
    font    {
        primary GB2312.1980-0:GL
    }
}
END XLC_FONTSET



以上内容定义的是显示Locale时使用的字符集。在多语言环境中,为了同时显示中英文,系统往往需要多种字体。例如,上例中表示:在显示简体中文时要使用两种不同编码的字体,其中一个是使用了GB2312编码的中文字体,其字体名称以GB2312.1980-0结束,另一个是ISO8859-1编码的英文字体,其字体名称以ISO8859-1结束。


XLC_LOCALE的下一部分定义了Locale中的字体在X系统中的处理方式:

XLC_XLOCALE
   
encoding_name       zh.euc
mb_cur_max      2
state_depend_encoding   False
wc_encoding_mask    \x30000000
wc_shift_bits       7
   
cs0 {
        side        GL:Default
        length      1
        wc_encoding \x00000000
        ct_encoding ISO8859-1:GL
}
   
cs1 {
        side        GR:Default
        length      2
        wc_encoding \x30000000
        ct_encoding GB2312.1980-0:GL; GB2312.1980-0:GR
}
   
END XLC_XLOCALE







cs0定义的部分为iso8859-1编码的英文字符,每个字符占用一个字节。cs1定义的部分为GB2312编码的中文字符,每个字符占用两个字节,这两个字节都必须用GB2312.1980-0的字体来表示。注意,对于上面的X设置,GB2312.1980-1类型的字体是无法正常显示的,除非用户修改X Locale。

除此之外,/usr/X11R6/lib/X11/locale还使用locale.dir和locale.alias文件定义可用X-Locale的名称和位置。其中,locale.dir定义了每个X-Locale文件的位置以及实际的Locale名称。locale.alias文件则定义了每个Locale可能的别名。

X Window 的字体存放在/usr/X11R6/lib/X11/fonts目录下,一般使用PCF的字体。在将新的字体文件拷贝到此目录之后,运行

mkfontdir

由这条命令更新改目录下的fonts.dir的内容。例如,

fzs14.pcf.Z fzs14

helvR12_iso01.pcf.gz -adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1

上面两行的信息是从字体文件中抽取出来的,比如,helvR12_iso01.pcf.gz文件中就包含iso8859-1编码的文件。但是,字体文件fzs14.pcf.Z就不包含类似的字体说明信息,因此我们还需要使用fonts.alias文件建立字体别名。

-hlc-song-medium-r-normal--14-140-75-75-c-140-gb2312.1980-0 fzs14

这样在安装程序使用下面的资源时,X Window系统就知道要加载fzs14字体了。

style "font" {
  fontset="-*-helvetica-*-r-normal-*-14-*-*-*-*-*-iso8859-1, -*-medium-*-14-*-*-*-*-*-*-gb2312.1980-0"
}
回复

使用道具 举报

发表于 2004-10-13 10:40:42 | 显示全部楼层
还有这个:
http://www-900.ibm.com/developerWorks/cn/linux/i18n/gb18030/index.shtml

二、Linux的国际化和本地化机制
Linux的国际化和本地化机制非常灵活方便,这使得我们在Linux增加一种新的本地化支持非常容易,甚至基本上不需要去编译应用程序包,而只需要在系统核心的某些地方进行扩充和修改就可以了。
1.NLS简介
为了更好地对国际化和本地化进行支持,Linux系统 提供了符合Posix标准的 NLS(National Language Support)子系统。该子系统建筑在基于ASCII码的Linux核心上,为世界上不同地域、不同语言环境的应用提供国际化本地化支持。系统中所有支持多国语言的实用程序,包括X Window都是建立在这个基础上。在此基础上,可以建立支持各种不同的语言文化的民族特征数据库(LOCALE)、输入方法(IM)、字体(FONT)和消息机制(MESSAGE)等。在NLS子系统中,Glibc函数库中提供的与代码集相关的多字节字符与宽字符处理函数是Linux实用程序支持国际化本地化的核心,通过这些函数,实用程序把英文与各种本地文字同样处理;而 Locale 则是本地化工作的一个基石,因为不管是Glibc,还是系统的其它部分,都是通过读取系统当前的 Locale 设定来识别 当前的本地化区域,从而使用正确的字符映射表和消息函数。
2.Glibc的转换模式概念
libc对多字节编码的支持非常灵活和自由,它通过一种"转换模式"来实现。目前的Glibc采用UTF-8作为处理码。当接收到外部输入的多字节字符时,系统首先根据当前的 Locale 确定所使用的字符集,然后查找从当前字符集到UTF-8之间的转换模式,根据这种转换模式把输入的多字节字符转换为相应的UTF-8字符。相反,当需要输出字符时,系统再查找从UTF-8到当前字符集之间的转换模式,按照这种模式把要输出的UTF-8字符转换为当前字符集中的多字节字符。在Glibc内部,有一个gconv_modules的转换模式列表。这个列表作为一个文件的形式存在于/usr/lib/gconv 目录下。对于每种具体的转换模式,Glibc把它们的转换表和转换函数编译为一个独立的共享文件(.so),比如支持GB的转换模式的共享文件名为libGB.so,支持Big5的共享文件名为 libBIG5.so。当应用程序调用到Glibc中有关编码转换部分的函数时,Glibc首先从gconv_modules 这个转换模式列表中查找所应该采用的转换模式,然后把相应转换模式的共享文件调入内存。这种动态装载的方式,使得添加或者删除转换模式非常自由和方便,而且当Glibc 支持越来越多的编码时,libc.so这个文件本身并不会变得异常庞大。
3.Glibc对多字节字符和宽字符的转换处理
Glibc中提供了一种新的字符类型——宽字符。宽字符的好处就是它可以把这个字符作为一个单字来处理,而不会导致多字节字符在处理时遇到的删除半个字符的现象。为了更好地使用宽字节字符, Glibc提供了多字节字符和宽字符之间的转换函数以及其它的对宽字符处理的函数。前面介绍的当系统要将本地化编码集中的多字节字符转化为系统的处理内码UTF-8 时,使用的就是这类处理函数中的mbtowc()函数。下面就以这个函数的工作流程为例进行详细介绍:支持国际化本地化的应用程序在需要将一个多字节字符转换UTF-8处理码时,调用 mbtowc()函数进行处理。但是,mbtowc()函数只是一个外壳,它主要是调用 mbrtowc()函数。而在mbrtowc函数中,首先调用 update_conversion_ptrs() 函数来更改当前的转换函数,然后调用 _wcsmbs_gconv_fcts 结构的 towc 成员 的 fct 成员函数来完成实际的转换。而在 update_conversion_ptrs() 函数中, 主要是通过调用 __wcsmbs_load_conv() 函数来完成的。__wcsmbs_load_conv() 函数函数又调用了getfct() 函数来取得当前转换模式的结构信息,同时根据转换模式的结构信息调用相应的共享文件。getfct() 函数调用 gconv_find_transform()函数来查找当前应该采用的转换函数,并且把转换函数的名字放在转换模式的结构中一起返回。 mbtowc()函数实现的具体步骤如图1所示:


从上面的转换过程可以看出,要想在Linux上增加对GB18030-2000编码的支持,需要对Glibc进行一定的扩充。这种扩充重要就是增加新的支持GB18030-2000编码标准的转换模式。由于目前Linux源码的开放性,使得我们无论是了解程序的工作流程,还是进行具体的修改都十分方便。至于对Glibc所做的扩充,在第三部分将会详细介绍。

4.Locale简介
Locale是Linux本地化工作的基础,针对不同的区域, 它在 /usr/share/locales 目录下面有不同的Locale。
一般来说,Locale是由三个文件创建得到的,它们分别 是Charmap Source 文件、Locale Source文件和Method文件。其中Charmap Source 文件主要用来定义该Locale所支持的字符集中的每个字符; Locale Source文件的主要作用是定义Locale的六个域,它们分别是LC_CTYPE、LC_COLLATE、LC_TIME、 LC_NUMERIC、LC_MONETARY、LC_MESSAGES,在新的Glibc2.2版本中将会支持更多的 Locale域;而所谓Method文件,其实就是针对多字节处理所提供的一些函数。

Glibc 提供了 localedef 函数来生成具体的 Locale, localedef 的用法如下所示:

localedef -f charmapsourcefile -i localesourcefile -m methodfile localename

其中-f, -i 和 -m 参数分别表示指定 charmap source 文件, locale source 文件和 method 文件,而最后的一个参数表示所要生成的 locale 的名字。
回复

使用道具 举报

发表于 2004-10-13 10:49:13 | 显示全部楼层
虽然不能肯定他们说的一定就是对的。但我觉得他们都表达了一个意思:
那就是locale里面确实定义了编码转换,但那是locale里面的字符编码与系统内码的转换关系。编码到字形的转换可能还不在这里。

我还是想理解更详细的从编码到字形的转换过程呀。。

目前的Glibc采用UTF-8作为处理码,这个是真的吗?
回复

使用道具 举报

发表于 2004-10-13 11:25:41 | 显示全部楼层
不好意思,楼主,拿你的帖子做起了笔记了。
请原谅!!
回复

使用道具 举报

 楼主| 发表于 2004-10-14 12:28:28 | 显示全部楼层
我越看越晕,我希望能从比较浅的方式入手,现建立一个从编码到字形的最后现示的模型,现有个大概的概念,然后再深入研究,才不会偏离大的方向。
希望高人指教。
另外,如果是locale面的字符编码与系统内码的转换关系,那应该是系统内码在转换成字形,也就是说字符编码与自形不直接对应,那为什么字体有对多种编码的支持呢?这好像又是个矛盾吧
关于字体文件,我们以simsun为例子来讨论吧,应该是同时至少包含了英文字符和汉字字符吧,并且每个字符的字形在文件中应该是只有一份吧。根据simsun.ttf文件生成的fonts.dir有如下的内容:
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-ascii-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb18030.2000-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb2312.1980-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gbk-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso10646-1
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso8859-15
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso8859-1
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-koi8-r
是不是很能够说明一个字体文件能够应用到很多中编码格式下呢?
回复

使用道具 举报

发表于 2004-10-14 14:24:14 | 显示全部楼层
[quote:40192a2c0a="yg_sun"]我越看越晕,我希望能从比较浅的方式入手,现建立一个从编码到字形的最后现示的模型,现有个大概的概念,然后再深入研究,才不会偏离大的方向。
希望高人指教。
另外,如果是locale面的字符编码与系统内码的转换关系,那应该是系统内码在转换成字形,也就是说字符编码与自形不直接对应,那为什么字体有对多种编码的支持呢?这好像又是个矛盾吧
关于字体文件,我们以simsun为例子来讨论吧,应该是同时至少包含了英文字符和汉字字符吧,并且每个字符的字形在文件中应该是只有一份吧。根据simsun.ttf文件生成的fonts.dir有如下的内容:
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-ascii-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb18030.2000-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb2312.1980-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gbk-0
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso10646-1
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso8859-15
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-iso8859-1
:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-koi8-r
是不是很能够说明一个字体文件能够应用到很多中编码格式下呢?
[/quote]

-.
1:如果是locale里面定义的字符编码与系统内码的转换关系
我想是为了方便系统统一处理各种不同locale中的字符编码串呀!

2:那应该是系统内码再转换成某种选定字体中的字形
我没有这样说呀,我只是说出了自己的两点理解:
a. 一个字体文件能够应用到很多中编码格式下;
b. locale里面定义的字符编码与系统内码的转换关系.
我认为它们之间并不矛盾。b小点跟显示应该没什么关系。

二:
关于编码到字形抽象一点的概念应该是:
1.系统(Xserver)需要显示一个以某种编码格式(gb18030)编码(D6 D0)的字符(汉字'中').
2.系统下面的某一模块(注1:具体是什么模块我还不太清楚,好像基于gtk1,gtk2和qt的应用所用的模块还不太一样)根据需要显示的字符的编码格式(gb18030)和字体配置文件(注2:如fontsconfig或老的XF86config)去选中一种字体(找错了或者没有就会显示成乱码或者之间显示成编码,美化字体的关键就在于此步)比如(:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb18030.2000-0),该字体所用的大小,是否加粗或变斜都已定好。
3.上面说的模块将选好的字体信息和需要现实字符(汉字'中')的编码(注3:这里的编码需不需要经过转换,或者转换需要但将发生在下一步我不清楚)交给字体渲染引擎(注4:如xft等)。
4.字体渲染引擎通过编码(注3:这里的编码需不需要经过转换,或者转换需要但已发生在上一步我不清楚)找到该字形(simsun字体下的'中')的全部信息,将给定字形转换成字体点阵
5.系统(Xserver)将得到字体点阵显示到交互界面上。
整个过程我想应该就是这样吧。
其中标注的地方表示我还不太了解只是猜测,真的很难找到一个很完整地介绍资料。欢迎讨论或指教!
回复

使用道具 举报

 楼主| 发表于 2004-10-14 15:26:26 | 显示全部楼层
我想问问楼上的朋友,那你说的这些概念,怎么没和locale结合起来,比如需要显示gb18030,怎么知道要显示他呢,是不是要参考一下locale的参数。另外,也没有提到关于系统内码的问题,如果字符的显示与locale无关,干吗还要转换成系统内码,从你的描述过程中可以看出,直接用编码就可以显示字符了。
我觉得是不是,只用系统内的应用程序需要与locale沟通来确定本地的语言种类,而应用程序内部(mozilla显示的网页内容)的字符显示,是根据网页内容本身的编码来显示,然后重复
1.系统(Xserver)需要显示一个以某种编码格式(gb18030)编码(D6 D0)的字符(汉字'中').
2.系统下面的某一模块(注1:具体是什么模块我还不太清楚,好像基于gtk1,gtk2和qt的应用所用的模块还不太一样)根据需要显示的字符的编码格式(gb18030)和字体配置文件(注2:如fontsconfig或老的XF86config)去选中一种字体(找错了或者没有就会显示成乱码或者之间显示成编码,美化字体的关键就在于此步)比如(:1:simsun.ttf -misc-nsimsun-medium-r-normal--0-0-0-0-m-0-gb18030.2000-0),该字体所用的大小,是否加粗或变斜都已定好。
3.上面说的模块将选好的字体信息和需要现实字符(汉字'中')的编码(注3:这里的编码需不需要经过转换,或者转换需要但将发生在下一步我不清楚)交给字体渲染引擎(注4:如xft等)。
4.字体渲染引擎通过编码(注3:这里的编码需不需要经过转换,或者转换需要但已发生在上一步我不清楚)找到该字形(simsun字体下的'中')的全部信息,将给定字形转换成字体点阵
5.系统(Xserver)将得到字体点阵显示到交互界面上。
整个过程我想应该就是这样吧。
其中标注的地方表示我还不太了解只是猜测,真的很难找到一个很完整地介绍资料。欢迎讨论或指教!

以上步骤,只是我的猜测,请执教。
另外希望斑竹能将该帖置顶,以方便讨论!
回复

使用道具 举报

发表于 2004-10-14 16:30:57 | 显示全部楼层
恩,这样也不错,我提出假设,你来提疑问,希望这样的探讨能够把事实给揭露出来 。或者迎来能给我们答疑的高手也不错。
我的理解是locale存在的意思在于给应用界定一个输入输出字符集的范围(主要讨论这个)和一些诸如时间,符号的表达格式。linux下支持国际化本地化的应用都依赖于它的存在而获取当前locale下的字符集编码格式,并且已该种格式来理解他的输入输出字符编码串。

举例来说,我当前系统的locale设置为en_US.UTF-8,因为utf-8/unicode也包括中文编码,同时我又安装了中文字体,所以我的Gnome能够显示中文目录和文件名,但同样是中文的文件内容则有可能显示出来是乱码(如果以GB18030编码),因为文件内容的编码格式不由Gnome控制, 它还是以utf-8的编码格式去理解文件内容,像gedit也是。
同样是en_US.UTF-8的locale设置,为什么mozilla就能理解以GB2312字符集编码的网页呢,我开始也很迷惑,后来才猜测到是因为程序自身拥有处理多种编码格式的能力。菜单选项里面的view | encoding 就能说明问题了。就像uedit32,你用记事本打开时显示为乱码的内容可以在uedit里面看得很清楚。像这样自身拥有理解各种编码能力的程序当然可以多出locale以外的能力,而限制只不过在于字体的支持上。

前面说过字符的编码格式可以有很多种,一个字符在不同的编码格式下有可能是单子节(ansi)也有可能是宽字节(Unicode)或多字节(utf-.系统为了让应用尽可能的忽略这样的干挠,所以需要利用locale机制定义编码与内码(有资料说系统内码是utf-8,我觉得不太像,宽字节的unicode/UCS显然更何时一些,有人能够给出证据吗?)的转换,通过系统所提供的函数来格式化输入输出,使得应用内部只需要处理系统内码
编码的字符串,减少了很多麻烦。同时系统也能够相对于应用程序而言透明的添加对今后其它locale的支持。
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-27 21:27 , Processed in 0.098145 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

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