From a29ea7a2be37e76f3696635a7d986e0befc664fc Mon Sep 17 00:00:00 2001 From: Max Chernoff Date: Fri, 21 Nov 2025 16:13:20 -0700 Subject: [PATCH 1/2] Round up embolden widths to avoid non-zero widths With "tfmdata.mode = 2" (PDF stroke and fill), if you set "tfmdata.width" to a non-zero integer, then the glyphs are stroked with a line of that thickness; this is documented in the LuaTeX manual. If you set "tfmdata.width" to zero, then the stroke width will be inherited from the environment; this isn't documented anywhere, but it's somewhat useful, and someone is probably relying on it. If you set "tfmdata.width" to a non-zero value that rounds to zero, then you get the same behaviour as if you set it to exactly zero; this is somewhat surprising, since it means that in most cases, "tfmdata.width = 0.49" produces much thicker glyphs than "tfmdata.width = 0.51". Example: \input{luaotfload.sty} \font\TestFontA={lmroman10-regular:embolden=0.000;} at 10.0pt \font\TestFontB={lmroman10-regular:embolden=0.006;} at 10.0pt \font\TestFontC={lmroman10-regular:embolden=0.005;} at 10.0pt \def\Test#1{% \par {\tt\string#1}: \pdfextension literal {10 w} #1 ooo \pdfextension literal { 1 w} #1 ooo \pdfextension literal { 0.00001 w} #1 ooo } \nopagenumbers \Test\TestFontA (Expected) \Test\TestFontB (Expected) \Test\TestFontC (Weird!) \bye The LuaTeX engine developers aren't planning on fixing this https://mailman.ntg.nl/archives/list/dev-luatex@ntg.nl/thread/7BRXFIAOVQDHMBZADBREXOV6YECYFHS3/ and this current behaviour is incompatible with XeLaTeX https://tex.stackexchange.com/q/755049 so this commit modifies the "embolden" manipulator to check if the computed stroke width is non-zero but would round to zero; if so, it sets the stroke width to 1 instead. This ensures that the stroke width will be inherited from an outer PDF group if and only if the embolden factor is exactly zero. An alternative (and simpler) solution would be to use "math.ceil" to unconditionally rounds up the computed embolden width; this could potentially cause backwards compatibility issues since this means that half of all embolden values would now be 0.001pt thicker than before. However, since this is applied only by the PDF renderer, this would not affect line breaking. --- src/luaotfload-embolden.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/luaotfload-embolden.lua b/src/luaotfload-embolden.lua index 3b25b041..a2da4dec 100644 --- a/src/luaotfload-embolden.lua +++ b/src/luaotfload-embolden.lua @@ -15,7 +15,12 @@ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded local otffeatures = fonts.constructors.newfeatures "otf" local function enableembolden(tfmdata, _, embolden) - tfmdata.mode, tfmdata.width = 2, tfmdata.size*embolden/6578.176 + tfmdata.mode = 2 + local width = math.round(tfmdata.size*embolden/6578.176) + if width == 0 and embolden ~= 0 then + width = 1 + end + tfmdata.width = width end otffeatures.register { From da00b61d49d89f9d5759e44403ef0e21c695eb38 Mon Sep 17 00:00:00 2001 From: Max Chernoff Date: Sat, 22 Nov 2025 23:33:07 -0700 Subject: [PATCH 2/2] Update embolden documentation. --- doc/luaotfload-main.tex | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/doc/luaotfload-main.tex b/doc/luaotfload-main.tex index 16d05bce..432afac2 100644 --- a/doc/luaotfload-main.tex +++ b/doc/luaotfload-main.tex @@ -1107,7 +1107,32 @@ \endaltitem \beginaltitem {embolden} - A factor, defined as a decimal number. + A factor, defined as a decimal number. This fakes a bold font by + stroking the glyph outlines with an outline of a constant width. This + is typographically not ideal, but can give acceptable output when the + factor and is rendered correctly by the PDF viewer. However, many PDF + viewers---most notably Chrome---completely misrender the effect at low + zoom levels, so you should only use this feature on fonts typeset at + large sizes, if you know for certain which PDF viewers will be used to + view the document, or if you're printing to paper. + + \identifier{luaotfload} defines the \identifier{embolden} feature to + give the same results as the same feature in \XeTeX, so its definition + is rather obscure: internally, the \identifier{embolden} parameter is + divided by~10, multiplied by the font size in \TeX{} points + (\verb|pt|), and then directly written to the PDF file as the stroke + width (therefore treating \TeX{} points as PostScript points + (\verb|bp|)). As an additional feature not present in \XeTeX, if you + set the \identifier{embolden} parameter to exactly~0, \LuaTeX{} will + stroke the font without setting the stroke width, meaning that the + stroke width will be inherited from the outer PDF graphics state. + + Setting \identifier{embolden} to values below~0.5 is only useful for + print documents, since many PDF viewers will always render the stroke + widths at some greater minimum value; setting \identifier{embolden} to + values above~20 is rarely useful since if the stroke overlaps with + itself, there will be significant visual artifacts. Useful values are + generally between~1 and~10. For example