在iText中访问OpenType字形变体 [英] Accessing OpenType glyph variants in iText

查看:157
本文介绍了在iText中访问OpenType字形变体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆