luaotfload icon indicating copy to clipboard operation
luaotfload copied to clipboard

Allow creation of small caps font variant

Open BrainStone opened this issue 6 years ago • 8 comments

It would be very nice to be able to create a small caps font (variant) from a font that doesn't have one.
Feature request posted here as suggested by @u-fischer.

BrainStone avatar Nov 07 '19 11:11 BrainStone

This is hard to do right. There are multiple ways this could be implemented:

  • Use virtual fonts to replace the glyphs without telling the shaper what is going on. Probably would work ok for ligatures, kerning would be weird. Maybe we would have to disable positioning which would break all kinds of things.
  • Use virtual fonts and adjust the fontloader tables -- Would break isolation and don't work with HarfBuzz. (Probably less of a problem because scripts which really need HarfBuzz don't have the concept of small capitals) HarfBuzz support could be added by adding it directly to the harf code, but that would be ugly.
  • Do something similar to the multiscript code and actually replace lower-case letter with small upper-case letters before shaping. Probably works best, but it is slow. Especially it would affect the performance even for paragraphs which do not even use the functionality.
  • Convert everything to upper-case, track which characters used to be lower case, identify them post-shaping and make them smaller. Probably breaks if a big and a small character would otherwise form a ligature. Might be doable by inserting ZWNJs at appropriate locations.

I think I prefer the last option.

Further remarks:

  • What do we do if people insert characters which behave oddly in this context? E.g. the specific title case codepoints.
  • This uses case mapping. ~~> Coordinate with expl3? We probably need a Lua implementation though.

zauguin avatar Nov 07 '19 14:11 zauguin

Nothing sounds very convincing (and I wouldn't give this a high priority ;-)).

I wouldn't try to get it working in harf mode, I don't think that it is relevant there.

I don't think converting to uppercase would be good: Font \scshape{Font} should copy & paste as Font Font, not Font FONT. But I think one could get it working for short words if one had a virtual font where the lower case glyphs are replaced by upper case glyphs (along this line https://tex.stackexchange.com/q/370799/2388, but this also change copy&paste). Then one could either with macros or with combofont make the uppercase letters larger.

u-fischer avatar Nov 07 '19 15:11 u-fischer

IMHO, the best way to do fake small-caps should be in a layer above luaotfload i.e. in fontspec itself, by converting text to upper case (which is language-sensitive) then scale the glyphs down and may be slightly embolden and widen them. This breaks text copying, but one could use a better font with real small-caps instead of faking them (or fontspec could tag the text).

Luaotfload is simply too low level for this kind of business.

khaledhosny avatar Nov 07 '19 22:11 khaledhosny

Admittedly my original goal was for fontspec to have a FakeSmallCaps property, like they have for FakeBold and FakeSlanted. I thought this was the right place though.

Will open the suggestion there then.

BrainStone avatar Nov 08 '19 16:11 BrainStone

Admittedly my original goal was for fontspec to have a FakeSmallCaps property, like they have for FakeBold and FakeSlanted. I thought this was the right place though.

Will open the suggestion there then.

There is an issue for that at https://github.com/wspr/fontspec/issues/379. I don't believe fontspec is the right place though, especially the whole text conversion stuff has to happen on a much lower level than fontspec. I think luaotfload is a good place for that or a separate package could be used.

zauguin avatar Nov 08 '19 17:11 zauguin

@BrainStone I don't think either that fontspec is the right place. Basically it should be either luaotfload having some low-level support (which fontspec then can use) or a macro solution which does something like this:

\documentclass{article}
\usepackage{fontspec}

\setmainfont{Arial}
\newfontfamily\smallerArial{Arial}[Scale=0.8,FakeBold=1.2]

\begin{document}
\ExplSyntaxOn
G{\smallerArial\tl_upper_case:n {rüße~an~die}}~
W{\smallerArial\tl_upper_case:n {elt}}
\ExplSyntaxOff
\end{document}

image

u-fischer avatar Nov 08 '19 17:11 u-fischer

This very example shows why fontspec is the more ideal place :)

khaledhosny avatar Nov 08 '19 17:11 khaledhosny

If such a macro solution were used I agree that this might belong into fontspec and certainly not into luaotfload, but I think the entire point behind these requests (correct me if I'm wrong @BrainStone) is that people want an interface which behaves like a real small caps font, while such a macro solution will behave quite differently, probably relying on expandable arguments, not integrating with NFSS, etc.

zauguin avatar Nov 08 '19 17:11 zauguin