在iText中访问OpenType字形变体 [英] Accessing OpenType glyph variants in iText
问题描述
在iText中使用OpenType字体构建PDF文档时,我想从字体中访问字形变体 - 特别是表格图。由于OpenType字形变体没有Unicode索引,我不知道如何指定我想使用一组特定的变体(表格图)或通过其字形ID调用特定的字形。只查找相关的iText类名称。
When building PDF documents with OpenType fonts in iText, I want to access glyph variants from within the font -- specifically tabular figures. Since OpenType glyph variants do not have Unicode indices, I am not sure how to either specify that I want to use a particular set of variants (tabular figures) or call a specific glyph by its glyph ID. Just looking for the relevant iText class name if one exists.
推荐答案
这似乎不可能在最新的标签中< a href =https://github.com/itext/itextpdf/tree/5.5.8\"rel =nofollow> 5.5.8 ,也不在 iText的主分支。
This does not seem to be possible neither in the latest tag 5.5.8, nor in the master branch of iText.
如这篇文章和微软的 OpenType字体文件规范,字形变体存储在字体文件的字形替换表(GSUB)
中。访问字形变体需要从文件中读取该表,该表实际上是在类 com.itextpdf.text.pdf.fonts.otf.GlyphSubstitutionTableReader
中实现的,尽管这个类是暂时禁用。
As explained in this article and in the Microsoft's OpenType font file specification, glyph variants are stored in the Glyph Substitution Table (GSUB)
of a font file. Accessing the glyph variants requires reading this table from the file, which is actually implemented in the class com.itextpdf.text.pdf.fonts.otf.GlyphSubstitutionTableReader
, though this class is disabled for now.
类 com.itextpdf中的调用
已注释掉。 readGsubTable()
。 text.pdf.TrueTypeFontUnicode
The call readGsubTable()
in the class com.itextpdf.text.pdf.TrueTypeFontUnicode
is commented out.
void process(byte ttfAfm[], boolean preload) throws DocumentException, IOException {
super.process(ttfAfm, preload);
//readGsubTable();
}
事实证明这条线因某种原因被禁用,因为代码实际上是如果你试图激活它不起作用。
It turns out that this line is disabled for a reason, as the code actually does not work if you try to activate it.
所以,遗憾的是,没有办法使用字形变体,因为替换信息永远不会从字体文件中加载。
So, unfortunately, there is no way to use glyph variants, as the substitution information is never loaded from the font file.
更新
原来的答案是关于使用<$ c $的可能性c> iText API 用于访问开箱即用的字形变体,但目前还没有。但是,低级代码已经就绪,可以在一些黑客攻击后使用来访问字形替换映射表。
The original answer was about possibility to use iText API
for accessing glyph variants out of the box, which is not there yet. However, the low level code is in place and can be used after some hacking to access the glyph substitution mapping table.
当调用时read()
, GlyphSubstitutionTableReader
读取 GSUB
表并将所有要素的替换展平为一个地图 Map< Integer,List< Integer>> rawLigatureSubstitutionMap
。目前, OpenTypeFontTableReader
会丢弃这些要素的符号名称。 rawLigatureSubstitutionMap
将 glyphId
变体映射到基数 glyphId
,或连字 glyphId
到 glyphIds
的序列,如下所示:
When called read()
, the GlyphSubstitutionTableReader
reads the GSUB
table and flattens substitutions of all features into one map Map<Integer, List<Integer>> rawLigatureSubstitutionMap
. The symbolic names of the features are currently discarded by OpenTypeFontTableReader
. The rawLigatureSubstitutionMap
maps a glyphId
variant to a base glyphId
, or a ligature glyphId
to a sequence of glyphIds
like this:
629 -> 66 // a.feature -> a
715 -> 71, 71, 77 // ffl ligature
此映射可以反转以获得基础的所有变体 glyphId
。所以所有具有未知unicode值的扩展字形都可以通过它们与基本字形或字形序列的连接来计算出来。
This mapping can be reversed to get all variants for a base glyphId
. So all extended glyphs with unknown unicode values can be figured out through their connection to a base glyph, or a sequence of glyphs.
接下来,为了能够写一个字形对于PDF,我们需要知道 glyphId
的unicode值。关系 unicode - > glyphId
由 TrueTypeFont
中的 cmap31
字段映射。反转地图会按字形提供unicode。
Next, to be able to write a glyph to PDF, we need to know a unicode value for that glyphId
. A relationship unicode -> glyphId
is mapped by a cmap31
field in TrueTypeFont
. Reversing the map gives unicode by glyphId.
调整
rawLigatureSubstitutionMap
无法在 GlyphSubstitutionTableReader
中访问,因为它是私有
成员而不是有一个吸气剂存取器。最简单的方法是复制粘贴原始类并为地图添加一个getter:
rawLigatureSubstitutionMap
cannot be accessed in GlyphSubstitutionTableReader
, as it's a private
member and does not have a getter accessor. The simplest hack would be to copy-paste the original class and add a getter for the map:
public class HackedGlyphSubstitutionTableReader extends OpenTypeFontTableReader {
// copy-pasted code ...
public Map<Integer, List<Integer>> getRawSubstitutionMap() {
return rawLigatureSubstitutionMap;
}
}
下一个问题是 GlyphSubstitutionTableReader
需要 GSUB
表的偏移量,存储在 protected HashMap< String,int []>中的信息表
的 TrueTypeFont
类。放置在同一个包中的帮助程序类将桥接对 TrueTypeFont
的受保护成员的访问。
Next problem is that GlyphSubstitutionTableReader
needs an offset for GSUB
table, information that is stored in protected HashMap<String, int[]> tables
of TrueTypeFont
class. A helper class placed into same package will bridge access to the protected members of 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;
}
}
扩展 TrueTypeFont
,但这不适用于工厂方法 createFont()
of BaseFont
,在创建字体时依赖于硬编码的类名。
It would be nicer to extend TrueTypeFont
, but that would not work with factory methods createFont()
of BaseFont
, which relies on hard coded class names when creating a font.
这篇关于在iText中访问OpenType字形变体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!