这是我在尝试为我的另一个问题(Rendering Devanagari ligatures (Unicode) in Java Swing JComponent on Mac OS X)找到更好的规范时遇到的“元问题”。
我还不太了解的是,给定系统中哪个“组件”(想要更好的词)负责在Java中显示Unicode文本,更具体地说是连字 。
据我了解,以下组件会对流程产生影响:
Charset
(在Mac OS X 10.6上默认为MacRoman,在Windows 7上为cp1252)。“字体包含有关他们正在使用的编码的信息”。
因此,如果一串Unicode字符没有正确显示 (在我的另一个问题中可以看到,s.a。),问题最可能出在哪里?即,什么“组件”(更好的词会是什么?)负责“绑定”结扎,它的组成?
非常感谢您,如果您需要更多信息,请告诉我。
答案 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地图字体是通过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" ) );
或者您的信息流所处的编码。
请参阅: