4

I am using an OpenType Font (OTF) that provides a number of character variants, for example variants of B, E, H with swirls, tails etc. The variants are accessed through the OpenType features "swsh", "cv01", "cv02" etc. The usage is like this: {\addfontfeature{CharacterVariant=1}B}

The problem arises when I mix regular characters with swash variants, as in the word {\addfontfeature{CharacterVariant=1}B}ARRY, LaTeX does not apply the kerning between the B and the A, even though the font does have a kerning instruction for exactly that pair. I guess it may be because the } stops LaTeX from recognizing the whole thing as a word and it does not apply kerning.

Now you might propose that I use {\addfontfeature{CharacterVariant=1}BARRY} instead, and in fact LaTeX does apply the kerning correctly in that case. But that solution does not work unfortunately because it will display the swash versions of R and Y as well, which is not desired.

The following example shows the three cases, I. correct kerning with regular B and A, II. lack of kerning between swash-B and A, III. correct kerning between swash-B and A but undesired swash variant of R and Y:

I. BARRY\\
II. {\addfontfeature{CharacterVariant=1}B}ARRY\\
III. {\addfontfeature{CharacterVariant=1}BARRY}\\

enter image description here

Am I doing something wrong here or is there really no way to get correct kerning when mixing swashes and regular characters in a word?

The font, for reference, is this one: https://github.com/lvcivs/honoria-font

(My environment: XeTeX with the Fontspec package on Ubuntu).

Edit: Found this relevant issue in the fontspec bug tracker.

6
  • 2
    you are effectively using two fonts, and there is not kerning between two fonts. Dec 29, 2020 at 17:23
  • It is the same font, but with different features activated.
    – lvcivs
    Dec 29, 2020 at 17:34
  • 1
    it is technically a different font. Imagine that you use also say Scale or Embolden, would you still think of it as the same font? Dec 29, 2020 at 17:42
  • In this case, {\addfontfeature{CharacterVariant=1}BA}RRY. In general, I think for now you’d need to define a character variant that changes only B and not R. Some fonts might expose the variants in their private-use area.
    – Davislor
    Dec 29, 2020 at 18:22
  • Well, I don't know how this is implemented. But if cv01 etc. are handled as different fonts internally, which then prevents kerning, it is an inadequate implementation. Using swashes for initials is a rather straight-forward use case of such OpenType features and should not prevent kerning.
    – lvcivs
    Dec 29, 2020 at 18:46

2 Answers 2

6

Of course, you are using the same font, but technically: TeX loads each variant of (the same) font with given font features (set or unset) as single individual font instance. Each such font instance is loaded by \font primitive, i.e. the parameters of \font primitive includes name of the font plus set or unset font features.

For example, if you are loading KPfonts without swash, then the following is done internally at TeX level (roughly speaking)

\font\fntA=KpRoman-Regular:+tlig

If you are using the same font with swash, then following is done:

\font\fntB=KpRoman-Regular:+tling;+swsh

This is the same font file, but different font from TeX point of view. Now, you are doing somewhat like this:

\fntA{\fntB B}ARRY

TeX never puts kerning between letters from different fonts, \fntA and \fntB in such example.

I don't know, how actual font you are using, but you can print its full name loaded internally by \font primitive by \fontname\font:

{\addfontfeature{CharacterVariant=1}B:"\fontname\font"}ARRY:"\fontname\font".

You can see that these two names differs.

Edit The desired kern can be calculated via \setbox. We prepare the macro \specletter{<font selection>}{<letter>}<next text>:

\def\specletter#1#2{{#1#2}\def\specletterD{#2}\futurelet\next\specletterA}
\def\specletterA{\expandafter\ifx\space\next\else
   \setbox0=\hbox{\specletterD\next}\setbox1=\hbox{\specletterD\kern0pt\next}%
   \kern\dimexpr\wd0-\wd1\relax
   \fi
}


Test:

\specletter{\bf}{A}VA

The {\bf A} is joined with next V by kern. In your example:

\specletter{\addfontfeature{CharacterVariant=1}}{B}ARRY
2
  • Thank you for helping me understand this. The conclusion, then, is that it is a limitation of the way in which the (Xe)TeX/fontspec/HarfBuzz-stack implements OpenType features.
    – lvcivs
    Dec 29, 2020 at 19:38
  • @Ulmo I added a macro which can solve your problem.
    – wipet
    Dec 29, 2020 at 20:10
5

With lualatex you can access the glyph variant.

\documentclass{report}
\usepackage{fontspec}

\setmainfont{Honoria-Regular.otf}
\begin{document}
BARRY

\char\directlua{tex.sprint(luaotfload.aux.slot_of_name(font.current(), "B.left", false))}ARRY

{\addfontfeature{CharacterVariant=1}B}ARRY

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.