Is there a way to adjust kerning for a specific character combination?

Adjusting font kerning

If you need to adjust the kerning within a font, the short answers are:

  1. No, not from within TeX.

  2. Yes, if you're willing to create a virtual font.

  3. Yes, if you're able to edit the font with fontforge (OpenType fonts only, for use in XeTeX or LuaTeX).

  4. Yes, if you're using LuaTeX and OpenType fonts; see §11 of the fontspec manual: ‘OpenType font feature files’.

I've only experience in options 1 and 4.

XeTeX's interchartoks

XeTeX offers a feature known as ‘interchartoks’ that allows tokens to be inserted automatically between characters of different ‘class’. This feature was added to facilitate, say, automatic font and language switching between two different scripts (e.g., Japanese to Arabic).

This feature can be used to add kerning between characters, as shown in Philipp's answer. (As well as between !!, you might also choose to adjust spacing around : for French typography, say.) As an example, if this feature is used then when XeTeX comes across !! in the input, it will interpret it as !\exclamkern! instead. Any kerning that happens there will independent of the current font, which is generally not going to be appropriate for changing the kerning between letters. But for very specific use cases this technique is suitable for minor adjustments.


With LuaTeX, you can patch fonts on the fly in arbitrary ways:

\documentclass{minimal}

\usepackage{fontspec}
\usepackage{luacode}

\begin{luacode*}
local function add_exclam_kern(fontdata)
  if fontdata then
    local chars = fontdata.characters
    if chars then
      local ch = chars[33]
      if ch then
        if not ch.kerns then
          ch.kerns = { }
        end
        ch.kerns[33] = -100000
      end
    end
  end
end
luatexbase.add_to_callback("luaotfload.patch_font",
  add_exclam_kern, "add_exclam_kern")
\end{luacode*}

\setmainfont{Arial}

\begin{document}
!!
\end{document}

With XeTeX, you can use inter-character tokens:

\documentclass{minimal}

\usepackage{fontspec}

\setmainfont{Arial}

\XeTeXinterchartokenstate=1
\newXeTeXintercharclass\ExclamClass
\XeTeXcharclass 33=\ExclamClass
\XeTeXinterchartoks\ExclamClass\ExclamClass={\kern-1.5pt }

\begin{document}
!!
\end{document}

A TeX only way without changing the fonts would be to make the character active and define it to check the next character (which is sort of a hacky way). For the example of replacing !! with !\kern 1.2pt! one could use:

\documentclass[preview,border=5mm]{standalone}

\begin{document}
!\kern 1.2pt!\\
\makeatletter
\let\exclamationmarkbak!
\catcode`\!=13
\def!{\@ifnextchar!{\exclamationmarkbak\kern 1.2pt}{\exclamationmarkbak}}
\makeatother
!!\\
!a
\end{document}

enter image description here

Tags:

Kerning