LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: swordhui

关于字体的问题

[复制链接]
发表于 2009-9-23 19:30:05 | 显示全部楼层
Post by swordhui;2029479
知道了:
BIG5的设计比较失败..
有"许盖功"问题;)
还有一个鸡肋的设计: 自造字区, 这在编码设计上来说, 是完全错误的, 因为有岐义性.
比GB2312好的地方只有汉字多
比GB18030就不如了

是"许功盖"还是"许盖功"?

好像叫"许功盖"?
回复 支持 反对

使用道具 举报

发表于 2009-9-23 21:09:03 | 显示全部楼层
呵呵,楼主听说过黑箱么。
偶自知愚笨,当准备接受新信息时,自不敢强求,采蚕食策略,分而治之,逻辑上分,层次上分……
必要时,使用黑箱原则。

您说了那么多,真正和字体有关的到不多,和字符编码到较上劲。

其实,现在选编码,中文用户,应当在 UTF-8 GB18030 中选:
都是 UNICODE 字符集具体编码实现,
覆盖字符完全,
对正则表达式,都可以认为是随机乱序排列生成。

UTF-8 是针对当前 *nix-like 系统设计的,便于国际化,大势所趋,缺点是一个中文字符至少3字节,貌似部首排序,不排除将来有更合适中文的编码替代者。
GB18030 设计之初即是以中文为主,一个中文字符绝大部分2字节,貌似音序排列,但不利于国际化。

一个人一辈子能产生多少字节,采用压缩算法则几乎可忽略差异,所以,个人用户随意选择即可。
商业用户也许会考虑多些其它非技术因素。
对开发者,UTF-8 更是适用于绝大部分情况。

个人观点,最好不要刻意人为影响中文字体,如果可能字体应尽量回归传统,至少要繁体(正体)、简体并用,由时间决定存废。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-24 11:42:57 | 显示全部楼层
Post by d00m3d;2029574
是"许功盖"还是"许盖功"?

好像叫"许功盖"?


"许功盖" 酱更符合平仄律;)

老兄来自台湾? 记得你曾说过"酱紫"
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-24 12:00:21 | 显示全部楼层
Post by 聚焦深空;2029606

您说了那么多,真正和字体有关的到不多,和字符编码到较上劲。



主体叫"关于字体的问题", 确实有点小, 应该叫文字系统.:flash:


Post by 聚焦深空;2029606

其实,现在选编码,中文用户,应当在 UTF-8 GB18030 中选:
都是 UNICODE 字符集具体编码实现


我个人认为, 从现在开始应该逐步用UTF编码代替GB编码. 这个越早开始越好.
用简体或繁体到不重要.

麻烦的是磁盘中以中文命名的文件, 需要用一个工具搜索并替换成UTF-8, 以后就可以高枕无忧了.

GB编码的文档, 再存储时应该默认选UTF-16或UTF-8, 根据汉字和英文字母的比例决定.(编辑器应该可以根据比例自动选择)
回复 支持 反对

使用道具 举报

发表于 2009-9-24 12:37:47 | 显示全部楼层
Post by swordhui;2029776
"许功盖" 酱更符合平仄律;)

老兄来自台湾? 记得你曾说过"酱紫"


非也,"酱紫"是台湾语吗?我还是几年前来 sir 的时候学的 :)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-24 13:44:12 | 显示全部楼层
知道了:
X系统对字库文件, 采用了搜索和注册机制.
X启动时对知道目录进行搜索, 根据fonts.dir, fonts.scale 将字库注册到系统中, 包括字库支持的编码体系, 大小, 名称等等, 并分配一个长长的字体名. 长长的字体名可以通过fonts.alias变成短短的字体名...

示例1: 用X绘制GB2312编码的混合文字. (系统中必须有zh_CN.GB2312的locale, 参见LFS中GLIBC的编译安装)


  1. // Written by Ch. Tronche ([url]http://tronche.lri.fr:8000/[/url])
  2. // Copyright by the author. This is unmaintained, no-warranty free software.
  3. // Please use freely. It is appreciated (but by no means mandatory) to
  4. // acknowledge the author's contribution. Thank you.
  5. // Started on Thu Jun 26 23:29:03 1997

  6. //
  7. // Xlib tutorial: 2nd program
  8. // Make a window appear on the screen and draw a line inside.
  9. // If you don't understand this program, go to
  10. // [url]http://tronche.lri.fr:8000/gui/x/xlib-tutorial/2nd-program-anatomy.html[/url]
  11. //

  12. // Modified by Zhang Lihui <swordhui@263.net>, for GB2312 text drawing.

  13. #include <X11/Xlib.h> // Every Xlib program must include this
  14. #include <assert.h>   // I include this to test return values the lazy way
  15. #include <unistd.h>   // So we got the profile for 10 seconds
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <locale.h>

  19. #define NIL (0)       // A name for the void pointer

  20. const char* g_csMsg="abc测试1245";

  21. //font set, cover ASCII and GB2312.
  22. const char* g_csFontName="-misc-fixed-*-*-*-*-15-*-*-*-*-*-*-*,\
  23.         -*-fangsong ti-*-*-*-*-16-*-*-*-*-*-gb2312.1980-*";

  24. main(int argc, char**argv)
  25. {
  26.         XFontStruct     *pFontStruct;
  27.         XFontSet        fontSet;
  28.         char            **plistMissingChars=NULL;
  29.         int             n_listMissingChars=0;
  30.         char            *defreturn=NULL;

  31.         if ( setlocale (LC_ALL,"zh_CN.GB2312") == NULL ) {
  32.                 (void) fprintf (stderr, "%s: cannot set locale.n",
  33.                 argv[0] );
  34.         }

  35.       // Open the display
  36.       Display *dpy = XOpenDisplay(NIL);
  37.       assert(dpy);

  38.       // Get some colors
  39.       int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
  40.       int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

  41.       // Create the window
  42.       Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
  43.                                      200, 100, 0, blackColor, whiteColor);

  44.       // We want to get MapNotify events
  45.       XSelectInput(dpy, w, StructureNotifyMask);

  46.       // "Map" the window (that is, make it appear on the screen)
  47.       XMapWindow(dpy, w);

  48.       //Create Font Set.
  49.       fontSet=XCreateFontSet(dpy, g_csFontName, &plistMissingChars,
  50.                       &n_listMissingChars,
  51.                       &defreturn);

  52.       if(fontSet==NULL)
  53.       {
  54.               printf("[Error] Create font set failed.\n");
  55.       }
  56.       else
  57.       {
  58.               if(n_listMissingChars!=0)
  59.                       printf("[Error] missing chars=%d\n", n_listMissingChars);
  60.               else
  61.                       printf("Font set create OK\n");
  62.       }

  63.       // Create a "Graphics Context"
  64.       GC gc = XCreateGC(dpy, w, 0, NIL);

  65.       // Tell the GC we draw using the white color
  66.       XSetForeground(dpy, gc, blackColor);

  67.       // Wait for the MapNotify event
  68.       for(;;) {
  69.             XEvent e;
  70.             XNextEvent(dpy, &e);
  71.             if (e.type == MapNotify)
  72.                   break;
  73.       }

  74.       // Draw the line
  75.       XDrawLine(dpy, w, gc, 10, 60, 180, 20);

  76.       // Draw GB2312 message.
  77.       XmbDrawString(dpy, w, fontSet, gc, 10, 20, g_csMsg,
  78.                       strlen(g_csMsg));


  79.       // Send the "DrawLine" request to the server
  80.       XFlush(dpy);

  81.       // Wait for 10 seconds
  82.       sleep(10);

  83. }
复制代码


Makefile如下:

  1. all: prog2
  2.         @echo "Done."

  3. prog2: prog-2.cc
  4.         g++ -pipe -o $@ $^ -lX11

  5. clean:
  6.         rm  prog2
复制代码




测试对Unicode的支持.
先定义一个Unicode串.

  1. //Unicode, "一丁12fgh"
  2. const wchar_t g_csUniMsg[]={0x4e00, 0x4e01, 0x0031, 0x0032, 0x0066, 0x0067, 0x0068};
复制代码


将上面画串的函数后加入:

  1. // Draw Unicode message.
  2.       XwcDrawString(dpy, w, fontSet, gc, 10, 40, g_csUniMsg,
  3.                      sizeof(g_csUniMsg)/sizeof(wchar_t));
复制代码


屏幕上会出现"一丁12fgh".
使用GB18030更好些, 因为GB18030包含所有的Unicode汉字.


我们再测试一下utf8字串的绘制.
首先定义一个utf8字串.

  1. //utf-8 message. "01一丁fg"
  2. const char g_csUtf8Msg[]={0x30, 0x31, 0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0x81, 0x66, 0x67};
复制代码


然后改变程序的Locale, 为"zh_CN.utf8", 这个名字很奇怪.. 直接叫utf8好了, 干嘛还加zh_CN? 和中文完全无关嘛

  1. if ( setlocale (LC_ALL,"zh_CN.utf8") == NULL ) {
  2.                 (void) fprintf (stderr, "%s: cannot set locale.n",
  3.                 argv[0] );
  4.         }
复制代码



然后绘制字符串

     
  1. // Draw utf8 message.
  2.       XmbDrawString(dpy, w, fontSet, gc, 10, 20, g_csUtf8Msg,
  3.                       sizeof(g_csUtf8Msg));
复制代码


屏幕上出现"12一丁fg".

如果想创建一个包含所有编码区间的超级字符集, 可以考虑安装unifont, 然后用下面语句:

  1. fontset = XCreateFontSet (dpy, "-*-*-*-*-*-*-16-*-*-*-*-*-*-*",
  2.                         &missing_charsets, &num_missing_charsets,
  3.                         &default_string);
复制代码


大多数程序使用GTK+Pango, 或QT4, 有空继续.
回复 支持 反对

使用道具 举报

发表于 2009-9-24 19:03:42 | 显示全部楼层
swordhui 兄是从哪这么快学会了这么多东西的?
能否把源处亮出来给大家共享一下?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-24 19:08:10 | 显示全部楼层
Post by Vamperor;2029923
swordhui 兄是从哪这么快学会了这么多东西的?
能否把源处亮出来给大家共享一下?


呵呵, 最好的源是google.

用好的关键字搜索, 事半功倍:flash:

Wiki也是另外一个不错的源.
回复 支持 反对

使用道具 举报

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

本版积分规则

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