在最新的标记5.5.8和iText
的master分支中似乎都无法做到这一点。
如本文和Microsoft的OpenType字体文件规范中所述,字形变体存储在
GlyphSubstitution Table(GSUB)字体文件的中。访问字形变体需要从文件中读取此表,该文件实际上是在类中实现的
com.itextpdf.text.pdf.fonts.otf.GlyphSubstitutionTableReader,尽管该类目前已禁用。
该
readGsubTable()课程中的通话已
com.itextpdf.text.pdf.TrueTypeFontUnipre被注释掉。
void process(byte ttfAfm[], boolean preload) throws documentException, IOException { super.process(ttfAfm, preload); //readGsubTable();}事实证明,此行被禁用是有原因的,因为如果您尝试激活它,该代码实际上将无法工作。
因此,不幸的是,由于从未从字体文件中加载替代信息,因此无法使用字形变体。
更新资料
最初的答案是关于
iTextAPI开箱即用访问字形变体的可能性,目前尚不存在。但是,低级代码已经就位,并且在经过一些黑客攻击后可以用于访问字形替换映射表。
调用时
read(),
GlyphSubstitutionTableReader读取
GSUB表并将所有要素的替换展平到一张地图中
Map<Integer,List<Integer>>rawLigatureSubstitutionMap。目前,功能的符号名称已被丢弃
OpenTypeFontTableReader。该
rawLigatureSubstitutionMap映射将一个
glyphId变体映射到base
glyphId,或者将一个连字映射
glyphId到这样的序列
glyphIds:
629 -> 66 // a.feature -> a715 -> 71, 71, 77 // ffl ligature
可以颠倒此映射关系以获得base的所有变体
glyphId。因此,具有未知unipre值的所有扩展字形都可以通过与基本字形或一系列字形的连接来找出。
接下来,要能够将字形写入PDF,我们需要知道该字符的unipre值
glyphId。关系
unipre ->glyphId由中的
cmap31字段映射
TrueTypeFont。反向映射通过glyphId给出unipre。
调整
rawLigatureSubstitutionMap无法在中进行访问
GlyphSubstitutionTableReader,因为它是
private成员,并且没有getter访问器。最简单的技巧是复制粘贴原始类并为地图添加吸气剂:
public class HackedGlyphSubstitutionTableReader extends OpenTypeFontTableReader { // copy-pasted pre ... public Map<Integer, List<Integer>> getRawSubstitutionMap() { return rawLigatureSubstitutionMap; }}接下来的问题是,
GlyphSubstitutionTableReader需要对偏移
GSUB表,被存储在信息
protectedHashMap<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(); } } public Map<Integer, List<Integer>> getRawSubstitutionMap() { return rawSubstitutionMap; }}这将是更好的延长
TrueTypeFont,但不会与工厂方法工作
createFont()的
baseFont,创建一种字体时依赖于硬编码的类名称。



