# \textlangle and \textrangle, with kpfonts-otf, not displayed with lualatex but displayed with xelatex

As shown by the following MCE, \textlangle and \textrangle are correctly displayed with pdflatex + kpfonts but not with lualatex + kpfonts-otf.

The latter case is not so unexpected since Daniel Flipo, the maintainer of kpfonts-otf, told me these characters are currently missing (he's working on it). But what is strange is these characters are correctly displayed with xelatex + kpfonts-otf.

Do you know why xelatex successfully display them?

\documentclass{article}
\usepackage{iftex}
\ifpdftex
\usepackage[T1]{fontenc}
\usepackage{kpfonts}
\else
\usepackage{kpfonts-otf}
\fi
\begin{document}
\verb|$\langle\rangle$| $=\langle\rangle$

\verb|\textlangle\textrangle| $=$ \textlangle\textrangle
\end{document}

• With pdflatex

• With xelatex

• With lualatex

• I would guess harfbuzz is being clever here (Unicode has "issues" with langle and rangle, let me look...) – David Carlisle Sep 22 at 15:18
• luatex log Missing character: There is no 〈 (U+2329) in font [KpRoman-Regular.otf]:mode=n (U+2329 is deprecated character should be U+27E8, but that doesn't help, looking... – David Carlisle Sep 22 at 15:26

LaTeX's \textlangle and \textrangle insert Unicode codepoints U+2329 and U+232A by default. In your font, these glyphs do not exists, but Unicode codepoints U+3008 and U+3009 are available. According to Unicode data tables, these are canonically equivalent (meaning they "should" always appear exactly the same) to U+2329 and U+232A, so HarfBuzz (used by XeTeX and when explicitly requested by LuaTex) substitutes these. (This is a bit problematic because U+3008 and U+3009 are CJK characters and therefore might be wider in many fonts, but that's not an issue with kpfonts.)

To get the correct glyphs also in LuaTeX you can enable HarfBuzz or change which codepoints LaTeX uses:

\documentclass{article}
\usepackage{iftex}
\ifpdftex
\usepackage[T1]{fontenc}
\usepackage{kpfonts}
\else
\usepackage{kpfonts-otf}
\DeclareTextSymbol{\textlangle}\UnicodeEncodingName{"3008}
\DeclareTextSymbol{\textrangle}\UnicodeEncodingName{"3009}
\fi

\begin{document}
\verb|$\langle\rangle$| $=\langle\rangle$
\verb|\textlangle\textrangle| $=$ \textlangle\textrangle
\end{document}


The luatex log shows

Missing character: There is no 〈 (U+2329) in font [KpRoman-Regular.otf]:mode=n


It works in luatex if you use HarfBuzz (like xetex)

\documentclass{article}
\usepackage{iftex}
\ifpdftex
\usepackage[T1]{fontenc}
\usepackage{kpfonts}
\else
\usepackage{fontspec}
\ifluatex
\defaultfontfeatures{Renderer=HarfBuzz}
\fi
\usepackage{kpfonts-otf}
\fi
\begin{document}

\verb|$\langle\rangle$| $=\langle\rangle$

\verb|\textlangle\textrangle| $=$ \textlangle\textrangle

\end{document}


In theory (but apparently not in practice) U+2329 shouldn't be used, it has an unfortunate Unicode normalization to a full width angle bracket in the CJK block and U+27E8 was added specifically to avoid this character.

• I suspect you need Ulrike or Marcel to explain what luaotfload is doing here:-) – David Carlisle Sep 22 at 15:45
• luaotfload is doing "the obvious thing": The font does not have U+2329, therefore it complains that it's missing. The font does have a character in U+3008 though (that's the one in the CJK font) which is picked up by HarfBuzz (because of semi-normalization like behavior). – Marcel Krüger Sep 22 at 15:53
• @MarcelKrüger ah it's 3008 I assumed it was harfbuzz normalization, I thought it was going to 27E8 but then I couldn't understand why it didn't work if I input that directly. – David Carlisle Sep 22 at 16:02