这似乎既不是最新的标签5.5.8,也不是iText 的主分支.
如本文和Microsoft的OpenType字体文件规范中所述,字形变体存储在Glyph Substitution Table (GSUB)字体文件中.访问字形变体需要从文件中读取此表,该文件实际上是在类中实现的com.itextpdf.text.pdf.fonts.otf.GlyphSubstitutionTableReader,尽管此类目前已禁用.
readGsubTable()课堂上的电话com.itextpdf.text.pdf.TrueTypeFontUnicode被注释掉了.
void process(byte ttfAfm[], boolean preload) throws DocumentException, IOException {
super.process(ttfAfm, preload);
//readGsubTable();
}
Run Code Online (Sandbox Code Playgroud)
事实证明,由于某些原因,此行被禁用,因为如果您尝试激活它,代码实际上不起作用.
所以,遗憾的是,没有办法使用字形变体,因为替换信息永远不会从字体文件中加载.
更新
最初的答案是关于iText API用于访问开箱即用的字形变体的可能性,这还没有.但是,低级代码已就绪,可以在一些黑客攻击后使用来访问字形替换映射表.
调用时read(),GlyphSubstitutionTableReader读取GSUB表并将所有要素的替换展平为一个映射Map<Integer, List<Integer>> rawLigatureSubstitutionMap.目前,功能的符号名称已被丢弃OpenTypeFontTableReader.rawLigatureSubstitutionMap将glyphId变量映射到基础glyphId,或者将结果映射glyphId到如下序列glyphIds:
629 -> 66 // a.feature -> a
715 -> 71, 71, 77 // ffl ligature
Run Code Online (Sandbox Code Playgroud)
可以反转此映射以获得基础的所有变体glyphId.因此,所有具有未知unicode值的扩展字形都可以通过它们与基本字形或字形序列的连接来计算出来.
接下来,为了能够将字形写入PDF,我们需要知道一个unicode值glyphId.关系unicode -> glyphId由cmap31字段映射TrueTypeFont.反转地图通过glyphId给出unicode.
扭捏
rawLigatureSubstitutionMap无法访问GlyphSubstitutionTableReader,因为它是一个private成员,并没有getter访问器.最简单的方法是复制粘贴原始类并为地图添加一个getter:
public class HackedGlyphSubstitutionTableReader extends OpenTypeFontTableReader {
// copy-pasted code ...
public Map<Integer, List<Integer>> getRawSubstitutionMap() {
return rawLigatureSubstitutionMap;
}
}
Run Code Online (Sandbox Code Playgroud)
接下来的问题是,GlyphSubstitutionTableReader需要对偏移GSUB表,被存储在信息protected HashMap<String, int[]> tables的TrueTypeFont类.放置在同一个包中的帮助程序类将桥接对受保护成员的访问TrueTypeFont.
package com.itextpdf.text.pdf;
import com.itextpdf.text.pdf.fonts.otf.FontReadingException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class GsubHelper {
private Map<Integer, List<Integer>> rawSubstitutionMap;
public GsubHelper(TrueTypeFont font) {
// get tables offsets from the font instance
Map<String, int[]> tables = font.tables;
if (tables.get("GSUB") != null) {
HackedGlyphSubstitutionTableReader gsubReader;
try {
gsubReader = new HackedGlyphSubstitutionTableReader(
font.rf, tables.get("GSUB")[0], glyphToCharacterMap, font.glyphWidthsByIndex);
gsubReader.read();
} catch (IOException | FontReadingException e) {
throw new IllegalStateException(e.getMessage());
}
rawSubstitutionMap = gsubReader.getRawSubstitutionMap();
}
}
/** Returns a glyphId substitution map
*/
public Map<Integer, List<Integer>> getRawSubstitutionMap() {
return rawSubstitutionMap;
}
}
Run Code Online (Sandbox Code Playgroud)
这将是更好的延长TrueTypeFont,但不会与工厂方法工作createFont()的BaseFont,创建一个字体时依赖于硬编码的类名称.
| 归档时间: |
|
| 查看次数: |
1272 次 |
| 最近记录: |