latex3 / fontspec

Font selection in LaTeX for XeTeX and LuaTeX
http://latex3.github.io/fontspec/
LaTeX Project Public License v1.3c
277 stars 34 forks source link

Case mapping for LuaLaTex #461

Closed zauguin closed 7 months ago

zauguin commented 2 years ago

Status

READY

Description

Expose luaotfload's support for casemapping through the Letters = Uppercase / Letters = Lowercase features. This allows to convert text to upper or lowercase on the font level and therefore avoids requiring the mapped content tp be expandable or similar. Additionally this allows to reuse the selected language of a font for applying properly tailored mappings.

Maybe the most interesting aspects:

  1. LuaTeX only.
  2. In addition to triggering the case maping itself, Letters = Uppercase automatically applies the equivalent of Style = Uppercase and Kerning = Uppercase. The idea is that these features are designed to be enabled for uppercase text, so if the text is mapped to uppercase it is a reasonable default to enable them.
  3. This reuses the Letters = Uppercase name which used to be what is now known as Style = Uppercase and is therefore a breaking change. A different name could be used instead to avoid this, but I think that this approach leads to a more consistent design. Actually mapping the characters to upper/lowercase is much more consistent with the behavior of Letters = SmallCaps etc. which also map to small caps instead of requiring text which is already in small caps. Also especially combined with the previous point this shouldn't be a big change even for existing LuaLaTeX documents using Letters = Uppercase in the old sense since this feature was already supposed to only be used on uppercase text, so case mapping such text again normally wouldn't have any effect. It does break such usage in XeLaTeX documents though. This could be avoided by keeping the old behavior there, but in my opinion having different behavior in both engines would be significantly worse than removing the opinion for XeLaTeX. Especially since the alternative Style = Uppercase has been available for more than two years now.
  4. For german and greek, luaotfload will support alternative tailorings (activating the use of the capital eszett and changing the handling of iota subscript's respectively) by passing the strings de-xeszett or el-xiota to the upper (or lower, but there these variations don't have an effect) features with the next release. This functionality is currently not exposed.(Mostly because I don't see a sensible interface for this at the moment)
  5. By default the tailoring of the case changing algorithm depends on the language passed to luaotfload. This can be overwritten by passing a language tag, but as above this isn't exposed. This is potentially problematic because fontspec does not pass the language to luaotfload if the font doesn't contain a language specific feature for the language in question. I think that fontspec should be changed here to always pass on the script and language to make this information available to the font processing, but that should probably be discussed independently. This isn't a huge issue since most languages work fine without language specific tailoring anyway.

Todos

Minimal example demonstrating the new/fixed functionality

\documentclass{article}
\usepackage{unicode-math}
\setmainfont{texgyrepagella}[
  Extension = .otf ,
  UprightFont = *-regular.otf ,
  ItalicFont  = *-italic.otf  ,
]
\begin{document}
We need {\addfontfeatures{Letters = Uppercase}you}!
\end{document}
zauguin commented 2 years ago

This could also be implemented for XeTeX based on TECkit mappings (see zauguin/casemapping-xetex) but that's much more messy since it requires huge mapping files and interferes with other mappings.

wspr commented 7 months ago

Again sorry for the very slow response... this looks great!