哪个系统组件负责在Java应用程序中绑定Unicode连接?

时间:2011-05-17 14:32:23

标签: java unicode character-encoding rendering system

这是我在尝试为我的另一个问题(Rendering Devanagari ligatures (Unicode) in Java Swing JComponent on Mac OS X)找到更好的规范时遇到的“元问题”。

我还不太了解的是,给定系统中哪个“组件”(想要更好的词)负责在Java中显示Unicode文本,更具体地说是连字

据我了解,以下组件会对流程产生影响:

  1. 系统字符编码(例如,Mac OS X 10.6上的UTF-8,Windows 7上的UTF-16(根据akira对此superuser.com post的评论))。
  2. Java Charset(在Mac OS X 10.6上默认为MacRoman,在Windows 7上为cp1252)。
  3. 用于呈现文本的字体,以及该字体的编码信息(由Donal Fellows在my other question上建议:
      

    “字体包含有关他们正在使用的编码的信息”。

  4. 显然,要呈现的字符是否存在于各自的Unicode代码点。
  5. 因此,如果一串Unicode字符没有正确显示 (在我的另一个问题中可以看到,s.a。),问题最可能出在哪里?即,什么“组件”(更好的词会是什么?)负责“绑定”结扎,它的组成?

    非常感谢您,如果您需要更多信息,请告诉我。

4 个答案:

答案 0 :(得分:4)

该系统组件称为字体渲染器或字体光栅器。它负责根据字体中定义的字形将一系列字符代码转换为像素。正如其他答案所述,您可以从Java获取和设置的各种字符编码值无关紧要。当JVM为字体渲染器提供一系列字符代码时,它会告诉它应用什么编码(可能是UTF16,但这对Java程序员来说是透明的。)字体渲染器使用字体文件中指定的字体编码来匹配相应的字形。

当前版本的Windows和Mac OS X配有出色的字体渲染器。

第一个困惑点是JRE带有自己的字体渲染器,作为Java2D平台的一部分,这就是Swing使用的。应该有一个选项来控制Java是使用自己的渲染器还是系统渲染器。

编辑:在注释中指出McDowell,在OS X上,您可以通过设置Java属性apple.awt.graphics.UseQuartz = true来启用系统渲染器。

第二个困惑点是连字在英语中是可选的。桌面发布应用程序在看到像“shuffle”这样的单词时会替换“ffl”连字(字体中的单个字形),但大多数其他应用程序都不会打扰。根据你所说的关于梵文的内容(以及我刚才在维基百科上看到的内容)我收集的连字词在该语言中不是可选的。

默认情况下,Java2D字体渲染器不执行连字。但是,java.awt.font.TextAttribute.LIGATURES的JavaDoc表示始终为编写需要它们的系统启用连字。如果这不是您的经验,您可能在Java2D字体渲染器中发现了一个错误。同时,尝试使用Font构造函数来获取字体属性的映射,包括TextAttribute.LIGATURES。

答案 1 :(得分:3)

我不是专家,但希望这些提示会指出你正确的方向......

源数据的编码与字体的呈现方式无关。 Java中的所有字符数据都是UTF-16,因此只要您将信息从源代码正确地转码为字符/字符串,就应保留数据的完整性。

但是,请注意:

  • AWT系统可以使用默认系统编码进行字体映射
  • 这不太适用于梵文(我不知道支持它的遗留编码)

AWT地图字体是通过fontconfig file。在我的Windows系统上,这会映射到Mangal字体:

allfonts.devanagari=Mangal

毫无疑问,Mac OS上使用了不同的字体。

在Java 6生命周期中的某个时候引入了本机文本呈现 - 我不知道这是否与字体支持有关,或者仅影响渲染速度/抗锯齿等。

答案 2 :(得分:2)

如果您将严格引用到视觉呈现,则“编码”和相关主题不再相关:渲染从String转到可视显示。 String具有已定义(且不可更改)的编码,即UTF-16。因此,所有问题,例如“我是否使用正确的编码读取此二进制流”必须首先解决

文本的实际渲染必须由图形子系统完成。对于“普通”Java或SWT或任何其他替代系统,这将是AWT / Swing。

第一步(严格来说,不是“渲染”的一部分)是将某些二进制数据转换为String。此可以涉及平台默认编码 iff 代码未明确指定某些编码。这是编码一般发挥作用的步骤。在那之后,我们处于快乐 - 幸福 - 纯粹的Unicode领域。

答案 3 :(得分:1)

类似于约阿希姆所说的,数据的来源是什么?如果您正在读取文件或流,我肯定信任系统默认编码。您应该在读取数据时明确设置编码,例如

BufferedReader br = new BufferedReader( new InputStreamReader( file, "UTF-8" ) );

或者您的信息流所处的编码。

请参阅:

http://download.oracle.com/javase/1.4.2/docs/api/java/io/InputStreamReader.html#InputStreamReader(java.io.InputStream,%20java.lang.String