在 LuaTeX 中访问侧边距

在 LuaTeX 中访问侧边距

这个问题在 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参数一样使用13 为了进行比较,下面是使用 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 的字体加载器。

相关内容