请查看以下 MWE:
\documentclass[20pt]{extarticle}
\usepackage{unicode-math}
\usepackage{luacode}
%% Works: change width of
答案1
我想我们应该从结尾开始:
我在某处看到了
tfmdata.shared.rawdata.descriptions
和 某处tfmdata.characters
。有人能解释一下两者的区别吗?什么时候用前者,什么时候用后者?
切勿改变 中的任何内容tfmdata.shared.rawdata
。顾名思义,它是不受任何选定功能影响的原始数据,并且由不同的 TeX 级别字体共享。因此,如果您在自定义功能中更改它,然后使用此功能和不使用此功能加载字体,则您的更改可能会影响两者。或者不会。取决于顺序、实现定义的内部内容(关于何时共享或不共享内容)、所有受影响组件的版本和月相。(好吧,最后一个不太可能发生,但我不能保证它不会发生......)此外,依赖原始数据会错过其他功能更改的任何内容。
因此,应该在 中更改内容tfmdata.characters
。现在,如果您在其中设置某些内容,initializers
则不会产生太大影响,因为它会被 rawdata 覆盖。initializers
更多用于初始化、参数解析和设置动态处理器,实际的字符操作是在 中完成的manipulators
。注意:manipulators
与 相比initializers
,在缩放字体后运行。因此,您还必须缩放您的更改。
因此,更改宽度最好使用
local function newwidth(tfmdata)
tfmdata.characters[119891].width=3000 * tfmdata.parameters.factor
end
fonts.constructors.features.otf.register{
name = 'width',
description = 'Overwrite width values',
manipulators = {
base = newwidth,
},
}
你也可以通过这种方式改变重音的位置:
local function newacc(tfmdata)
tfmdata.characters[119891].top_accent = 900 * tfmdata.parameters.factor
end
fonts.constructors.features.otf.register{
name = 'acc',
description = 'Overwrite accent values',
manipulators = {
base = newacc,
},
}
另一方面,覆盖边界框实际上没有多大意义,因为边界框是字形外观的物理属性。它只是提供信息,除了确定 之前的初始高度/深度/斜体外,不会在任何地方使用initializers
,因此在代码运行时它不再被访问。你实际上想通过更改它来存档什么?
如果要将字形相对于原点水平移动,可以使用虚拟字体命令来应用偏移。这实际上会改变侧边距:
local function moveright(tfmdata)
tfmdata.characters[119891].commands={
{'right', 900 * tfmdata.parameters.factor},
{'char', 119891}
}
end
fonts.constructors.features.otf.register{
name = 'moveright',
manipulators = {
base = moveright,
},
}
如果要将字形向左移动,您仍可以使用命令,'right'
但只需使用负数即可。没有'left'
命令。您也可以使用它'down'
进行垂直调整。