这个问题在 XeTeX 中已通过以下代码解决:
\def\kright#1{\leavevmode #1\kern-\XeTeXglyphbounds3 \the\XeTeXcharglyph`#1 }
\def\kleft#1{\leavevmode \kern-\XeTeXglyphbounds1 \the\XeTeXcharglyph`#1 #1}
\XeTeXglyphbounds1
通过访问侧边距测量值(和3
),我可以将文本与墨水更精确地对齐。
此 XeTeX 依赖关系是目前阻止我迁移到 LuaTeX(主要用于微类型)的唯一原因。LuaTeX 中是否有等效函数,或者计划提供该函数吗?
在阅读了更多内容后microtype
,是否可以通过适当定制的字符凸起来实现相同的效果?这样,我转向 LuaTeX 可能会简单得多。
答案1
在为 Luatex 准备字体时,字体加载器还会在字体结构中设置一些额外的表,其中包含 返回的未处理数据fontloader.open()
。其中包括字形数据:对于字体中的每个字形,都有一些未包含在characters
因为 Luatex 不需要渲染字体。例如,这是关于字形的信息的转储A:
table={
["boundingbox"]={ 45, -10, 432, 460 },
["depth"]=10,
["height"]=460,
["index"]=9,
["name"]="a",
["slookups"]={
["as_l_1_s"]={ 63209, 63329 },
["ss_cyrl_l_18_s"]=63209,
["ss_cyrl_l_44_s"]=63329,
["ss_grek_l_17_s"]=63209,
["ss_grek_l_43_s"]=63329,
["ss_l_16_s"]=63209,
["ss_l_37_s"]=63209,
["ss_l_42_s"]=63329,
},
["width"]=512,
}
我们在数组中找到了计算边距所需的一切
boundingbox
:第一个值是左侧边距。第三个值是边框宽度。(尺寸以 TeX 点的百分之一为单位。)
packagedata = packagedata or { }
packagedata.sidebearings = { }
local sidebearings = packagedata.sidebearings
local utfbyte = utf.byte
local texsprint = tex.sprint
local get_sidebearings = function (id, char)
local tfmdata = font.getfont (id)
if not (tfmdata and tfmdata.shared) then
return 0, 0
end
local descriptions = tfmdata.shared.rawdata.descriptions
local glyphdata = descriptions [char]
if not glyphdata then
--- font lacks the glyph
return 0, 0
end
local boundingbox = glyphdata.boundingbox
local lside = boundingbox [1] or 0
local wd = boundingbox [3] or glyphdata.width
local rside = glyphdata.width - wd
inspect (glyphdata)
return lside / 100, rside /100
end
local sidebearings = function (id, char, left)
char = utfbyte (char)
local lside, rside = get_sidebearings (id, char)
if left then
texsprint (tostring (lside), "pt")
else
texsprint (tostring (rside), "pt")
end
end
packagedata.sidebearings.left = function (char)
return sidebearings (font.current (), char, true)
end
packagedata.sidebearings.right = function (char)
return sidebearings (font.current (), char, false)
end
现在我们可以在 TeX 端包装这些函数,如下所示:
\def \lsidebearing #1{%
\directlua {packagedata.sidebearings.left [[#1]]}%
}
\def \rsidebearing #1{%
\directlua {packagedata.sidebearings.right [[#1]]}%
}
这些可以像\XeTeXglyphbounds
参数一样使用1和3
为了进行比较,下面是使用 Xetex 和 Luatex 运行的测试文件:
\ifdefined \directlua
\input luaotfload.sty
\directlua {require "sidebearings"}
\def \lsidebearing #1{%
\directlua {packagedata.sidebearings.left [[#1]]}%
}
\def \rsidebearing #1{%
\directlua {packagedata.sidebearings.right [[#1]]}%
}
\font \mainfont = "file:Iwona-Regular.otf"
\else
\def \lsidebearing #1{\the \XeTeXglyphbounds1 \the \XeTeXcharglyph`#1}
\def \rsidebearing #1{\the \XeTeXglyphbounds3 \the \XeTeXcharglyph`#1}
\font \mainfont = "[Iwona-Regular.otf]"
\fi
\mainfont
\def \test #1{[#1] left: \lsidebearing {#1}, right: \rsidebearing {#1}\par}
\test a
\test b
\test y
\test z
\test а
\test б
\test ю
\test я
\bye
答案2
是也不是。当你通过内置字体加载时字体加载器库(非常低级),您可以访问字体文件的所有信息。据我所知,这包括边界框(请参阅第 4.4.5.1.2 节“字形项目”LuaTeX 参考手动的)。
但通常你通过字体规格/加载包会丢弃这些信息并只保留 TeX 所需的信息。
我怀疑是否计划将这些信息纳入加载包,它基于 ConTeXt 的字体加载器。