【发布时间】:2021-02-25 17:47:59
【问题描述】:
这个问题与很久以前提出的几个问题有关。我看到 cmets 说 Java 不支持 Opentype 字体,但这是 11 年前的事了。现在他们是。唯一的问题是 kerning pair 仅在 GPOS 表中给出。我已经看到它们在那里,但很难确保代码是正确的。
我目前正在转储 GPOS 表,试图跟随指针直到字距调整对。
到目前为止的代码如下,其中 GPOS 表之前已复制到数组gpos。转储表的函数是dumpGPOS()。我需要帮助来确定我所做的是否正确以及如何编写 TODO 部分:
byte[] gpos;
char[] hexasc( char[] hex, byte num ) {
int up = num >> 4;
int down = num & 15;
hex[0] = (char) ((up < 10)? '0' + up : 'A' + up - 10);
hex[1] = (char) ((down < 10)? '0' + down : 'A' + down - 10);
return hex;
}
char[] hex = { '0', '0' };
void printHex(byte b) {
hexasc(hex, b);
System.out.print(hex[0]);
System.out.print(hex[1]);
}
void dumpGPOS() {
int i, j;
System.out.println("GPOS header");
System.out.print("Version: ");
for ( i = 0; i < 4; i++ ) printHex(gpos[i]);
System.out.println(" (" + (gpos[0] << 8 | gpos[1]) + "." + (gpos[2] << 8 | gpos[3]) + ")" );
j = i;
System.out.print("TheScriptList: ");
for ( i = 4; i < 6; i++ ) printHex(gpos[i]);
System.out.println(" (" + (gpos[j] << 8 | gpos[j+1]) + ")" );
j = i;
System.out.print("TheFeatureList: ");
for ( i = 6; i < 8; i++ ) printHex(gpos[i]);
System.out.println(" (" + (gpos[j] << 8 | gpos[j+1]) + ")" );
j = i;
System.out.print("TheLookupList: ");
for ( i = 8; i < 10; i++ ) printHex(gpos[i]);
int lookup = (gpos[j] << 8 | gpos[j+1]);
System.out.println(" (" + lookup + ")" );
j = i;
System.out.println("Lookup List Table");
System.out.print("lookupCount: ");
for ( i = lookup; i <= lookup+1; i++ ) printHex(gpos[i]);
System.out.print('\n');
int count = (gpos[lookup] << 8 | gpos[lookup+1]);
int tab = lookup + 2;
int[] LookupList = new int[count];
for ( j = 0; j < count; j++ ) {
System.out.print("lookup[" + j + "] = ");
printHex(gpos[tab]);
printHex(gpos[tab + 1]);
System.out.println(" (" + ( LookupList[j] = (gpos[tab] << 8 | gpos[tab+1]) ) + ")" );
tab += 2;
}
int item, sub, size;
for ( j = 0; j < count; j++ ) {
item = lookup + LookupList[j];
System.out.println("Lookup [" + j + "]");
System.out.println("Lookup Type: " + (gpos[item] << 8 | gpos[item + 1]) );
System.out.print("Lookup flag: ");
printHex(gpos[item + 2]);
printHex(gpos[item + 3]);
size = (gpos[item + 4] << 8 | gpos[item + 5]);
System.out.println("\nNumber of subtables: " + size);
sub = item + 6;
int[] subTable = new int[size];
System.out.println("Subtable offsets");
for ( i = 0; i < size; i++ ) {
subTable[i] = (gpos[sub] << 8 | gpos[sub +1 ]);
sub += 2;
System.out.println( " " + subTable[i] );
}
for ( i = 0; i < size; i++ ) {
System.out.println("Subtable [" + i + "]");
sub = item + subTable[i];
printSubtable(sub);
}
}
}
void printSubtable(int sub) {
int format = gpos[sub] << 8 | gpos[sub + 1];
System.out.println("Format: " + format );
if (format == 1) {
/* TODO format 1*/
return;
}
/* TODO format 2*/
}
这个问题也和问题How to use kerning pairs extracted from a TTF file to correctly show glyphs as Path2D in Java?有关。
上下文是相同的,但由于Apache FOP 不读取 Opentype 字体,并且 Opentype 字体仅使用 GPOS 表中的字距调整信息,因此要困难得多。
我使用的是 Microsoft Opentype 参考,但它太过分了(太模糊,没有图纸,没有示例代码,也没有足够的示例)。还有什么提示、一些图纸、代码 sn-ps、更多示例(尤其是用于从 GPOS 表中提取字距调整表)? p>
我怎样才能 100% 确定这段代码确实在做它应该做的事情?
【问题讨论】:
-
虽然 GPOS 处理(而不是古老的
kern表处理)可能看起来有点过头了,但非常困难,因为语言非常困难:GPOS 是脚本, langsys,并且依赖于功能,并且可能需要以特定顺序多次通过各种 GPOS 查找来执行正确的整形。最好的办法是查看其他人已经编写的解析器代码(Harfbuzz、Opentype.js 等)。但是,在正确的位置发帖也是明智之举:typedrawers.com 是迄今为止询问字体工程的更好论坛 =) -
嗨@Mike'Pomax'Kamermans!自 80 年代末以来,我一直从事图形工作。您的贝塞尔曲线入门是一项了不起的工作!恭喜!我觉得语言并不难。可怕的是 Truetype 和 Opentype(尤其是第二个)的文档。我知道你是一个 JS 人,但那是我讨厌的语言。 Harfbuss 是用 C++ 编写的,我已经编写了很多年,但是 C++ 中的代码并不是特别清晰,除非它有很好的注释。感谢 typedrawers.com 的建议。我一定会检查出来的。我不知道它存在。太久没有认真做字体了。
-
我不反对讨厌 JS 的人,它可以在网络上运行,但网络只是网络(即使它有很深的影响力)。 Harfbuzz 基本上是解析方面的权威,Behdad 在这方面做得非常好,但如果它的来源不够,大多数 OG 字体的人都在打字机上,所以如果你想从字面上的人那里得到建议编写 OT 规范:这就是应该做的地方 =)
-
@Mike'Pomax'Kamermans,我下载了Opentype.js 和font-inspector.html。我在本地使用 font-inspector.html 运行它。我还复制了 site.css 进行格式化。我修改了inspector.html 以显示GPOS 表。它有效,但很奇怪。我必须使用按钮加载文件。它无法加载我在代码中提供的文件。这就是我讨厌这种语言的原因,:-)))
-
虽然说起来非常奇怪,因为这与 javascript 无关,而与“该 html 文件的编写方式”有关。任何具有 JS 知识的人都可以更新该文件,这样您就无需使用“浏览”按钮加载文件。这有点像说你讨厌 C#,因为你不喜欢某些孩子的 CLI 实用程序需要你传递全部大写的运行时标志:这与 C# 本身无关 =) (现代 JS 永远不需要运行 HTML自从几年前 Node 发布以来,它是一种脚本语言,如 php、python 等,也可以在浏览器中运行)