1

I am using LuaLaTeX (>=2022), OpenType fonts, microtype. Platform is Linux. I have permission to write files in the same directory (or subdirectory) as my main *.tex document. I cannot use --shell-escape, but I can use Lua io.open, write, read, close, as needed.

Although I am using a custom document class, this question should be applicable to standard classes. I have looked through the microtype documentation, and the fontspec documentation, without seeing what I need. I did find the Lua script sidebearings.lua by Philipp Gesang @phi-gamma which is functional, and possibly useful as a component of what I need.

Instead of reading a microtype.cfg file (standard, or one of my own design), I would like to (a) load the font using fontspec, (b) Get the side bearings of a few characters of my choice, (c) Create a custom-microtype.cfg on-the-fly, either in memory or written, (d) Use that configuration when I load microtype. In this regard, I do not load microtype until \AtBeginDocument.

Why I wish to do this: The output PDF will be robot-inspected for minimum margins. If a letter, such as lowercase j, intrudes into the margin, then the file will be rejected. It does not help to set protrusion=false, due to font kerning (which is required). If the document always used one or two fonts, I could manually learn what I need. But the document may use any OpenType fonts, including professional (not free) fonts that I cannot access, because there are other users.

I propose to use sidebearings.lua to discover the numbers, then nullify negative side bearings, using negative protrusion in a custom microtype configuration.

My questions: (1) Is this already available? I searched, but did not find. (2) If not already available, is it worth the effort to do this, or is there some "gotcha" that I do not understand? If it is worth the effort, I will do it myself.

EDIT: Here is a MWE for visualization only. Normally, there would be no black bars, and I would also compensate for the bearings of O.

\documentclass{article} % Compile with lualatex.
\RequirePackage{fontspec}
\setmainfont{Libre Caslon Text} % Already installed.
\begin{document}
% The rules are for visualization.
\noindent\rule{2pt}{10pt}Old Nick was a\\
jolly elf.\par
\noindent\rule{2pt}{10pt}Old Nick was a\\
\strut\hspace{.143em}jolly elf.\par % The .143 is from fontforge.
\end{document}

And here is the result. Note that the first j protrudes to the left of the reference bars. The second j does not. I am trying to do this without such an hspace trick.

screenshot of above result

EDIT2: Apparently, my request is possible, without needing to write a *.cfg file. Using the sidebearings method from

Accessing side-bearings in LuaTeX

I can do it while the document compiles. After loading microtype, the \SetProtrusion command works in Preamble. It can be used to re-set whatever was in the *cfg file.

6
  • side bearings tell you next to nothing about protrusion. For example "A" and "H" have (in CMR) almost the same side bearings, but "A" should be protruded by quite a bit, "H" not at all. The desired protrusion actually depends on the "optical weight" of the glyphs -- that is, the amount of "ink" -- on either side, which is something that is, AFAIK, not even accessible in luatex. So I don't think that protrusion can be calculated automatically. (But I'd love to be proven wrong.)
    – Robert
    Commented Jan 26, 2023 at 23:31
  • I realize that. Actually, I know more about graphics and typography than I do about TeX. But the word "protrusion" seems to be used two ways: (1) As used by microtype; (2) The visual result, no matter how it was achieved. I am trying to tweak (1) to get a result that is satisfactory by (2).
    – user287367
    Commented Jan 27, 2023 at 0:20
  • ah sorry, I didn't read your question carefully enough. So you basically want to cancel the "natural" protrusion that results from negative side bearings, correct? That should be doable. I'll have a look later (tomorrow), or maybe @MarcelKrüger will chime in...
    – Robert
    Commented Jan 27, 2023 at 13:23
  • Yes, that is what I am trying to do, cancel the "natural" protrusion due to negative side bearings. Incidentally: The issue with margins (by itself) is easily hacked by increasing side margins by a fudge factor. But that would not fix the visual alignment.
    – user287367
    Commented Jan 27, 2023 at 16:40
  • You can adjust expansion and protrusion in LuaTeX without microtype. In my opinion this is a bit more flexible: gist.github.com/hmenke/b8a1e7c47b92b8cf8778efa7d3eef315 Commented Jan 28, 2023 at 20:42

1 Answer 1

2

Instead of going through microtype it's nicer for this use-case to set the protrusion directly during font loading in a feature. There the protrusion for each character is set and the bounding box (and therefore the side-bearing) are directly available, so there is no need to write any files:

\documentclass{article}
\directlua{
  local function set_protrusion(tfmdata, _, value)
    % The bounding box is available in a dlightly hidden descriptions table 
    local descriptions = tfmdata.shared.rawdata.descriptions
    for i, char in next, tfmdata.characters do
      local bbox = descriptions[i].boundingbox
      % Determine the side bearings from the bounding box and width
      local left_bearing = bbox[1]
      local right_bearing = descriptions[i].width - bbox[3]
      % For negative bearings set protrusion parameters:
      if left_bearing < 0 then
        char.left_protruding = left_bearing
      end
      if right_bearing < 0 then
        char.right_protruding = right_bearing
      end
    end
  end
  % Setup this functionality to be controlled by the `bearing_prot` feature:
  fonts.constructors.features.otf.register{
    name = 'bearing_prot',
    description = 'Use protrusion to drop negative side-bearings',
    manipulators = {
      node = set_protrusion,
    },
  }
}
% And then load a font with this feature.
\usepackage{fontspec}
\setmainfont[RawFeature=bearing_prot]{Libre Caslon Text}
\begin{document}
% We have to enable protrusion since we don't use microtype:
\protrudechars=2
\noindent Old nick was a\par
% Print a rule to see the boundary of the text block
\hrule depth0pt height1pt
\noindent jolly elf.
\end{document}

enter image description here

2
  • Excellent! Answers my question "the way I asked it." Saves a lot of effort fooling around with microtype.
    – user287367
    Commented Jan 29, 2023 at 18:29
  • It can also be used with microtype: First remove negative bearings from problem characters (no need to remove tiny negatives), then use microtype protrusion to set acceptable values. For example on an OpenType font (grid 1000 per em) I consider protrusion 40 to be acceptable, this being about half vertical stem-width. So I can use the above answer to see if problem characters naturally protrude more than 40 left (j) or right (f). If so, zero the natural protrusion, then re-set it to 40. Now, that works for grid 1000, but I am not yet sure about TrueType grids (1024,2048).
    – user287367
    Commented Jan 31, 2023 at 19:41

You must log in to answer this question.