2

In luaotfload we can slant, extend or embolden a whole font by writing something like \font\x="xxx.otf:+slant=a;+extend=b;+embolden=c" at d pt. But what can I do when I would like to apply such changes only to one character or a range of characters?

Example: Let's get a slanted (\sum) as under the following link:

How do I get a slanted \sum symbol?

MWE:

\input luaotfload.sty

\font\mathfont="latinmodern-math.otf:mode=base;script=math;slant=.25" at 60 pt \textfont1=\mathfont

\Umathcode∑="1"1∑ \let\sum=∑

$∑ab$% How to apply the slant only to the sum?

\bye

As mentioned this will slant the whole math font. What has to be done so that the slant is only applied to the \sum?

If yes, can this be written as a new OTF feature as in this question?:

How to manipulate selected letters in LuaTeX?

Edit: I found out that I can add PDF commands to tfmdata.characters[...].commands but it does not work as expected. The width of the glyph ist set to 0 (overprinting) and the spacing in the following paragraphs is wrong. What is happening here?

How to write the comamnds properly? Please help me.

MWE 2:

\input luaotfload.sty

\directlua{ local function slantedsum(tfmdata) tfmdata.characters[8721].commands = { {'pdf', 'origin', 'q 1.04 0 .2 1 0 0 cm'}, {'char', 8721}, {'pdf', 'origin', 'Q'}, } end fonts.constructors.features.otf.register{ name = 'ssum', description = 'Slant sum symbol', manipulators = { base = slantedsum, }, } }

\font\mathfont="latinmodern-math.otf:mode=base;script=math;+ssum" at 10 pt \textfont1=\mathfont

\font\1="lmroman10-regular.otf" at 10 pt \1

\Umathcode∑="1"1∑ \let\sum=∑

abcd

$∑ab$% How to apply the slant only to the sum?

abcd

abcd

\bye

enter image description here

1 Answers1

2

To understand what is happening, we should start with a short note about "origin" mode for PDF literals: It allows you to act as if the origin of the PDF coordinate system is at the current point you are working on. This is done by applying a coordinate transform which moves the current coordinates (from TeX's point of view) to (0, 0) before your literal and by applying a transform which moves (0, 0) back to the current TeX point afterwards. Normally these two transforms cancel each other out, so except for your literal nothing else is affected by them. If you insert q in one 'origin' literal and Q in another, all transforms between them get discarded, so it's your responsibility that this cancelling out still works. This only works if both literals (from TeX's point of view) appear at the same position. If you use \pdfextension save and \pdfextension restore LuaTeX will warn you if this isn't the case, but for direct literals you are on your own.

Here this condition isn't satisfied since the char command moves you right by the width of your char. Now the width of the char is not set by zero but still has the right size, but after the glyph the coordinate system for the rest of the page (or until the next Q) is shifted left by the width of the glyph.

You can fix this by telling LuaTeX to put both your PDF literals at the same coordinates:

\input luaotfload.sty

\directlua{ local function slantedsum(tfmdata) tfmdata.characters[8721].commands = { {'pdf', 'origin', 'q 1.04 0 .2 1 0 0 cm'}, {'push'}, % Remember where we are {'char', 8721}, {'pop'}, % Move back there {'pdf', 'origin', 'Q'}, } end fonts.constructors.features.otf.register{ name = 'ssum', description = 'Slant sum symbol', manipulators = { base = slantedsum, }, } }

\font\mathfont="latinmodern-math.otf:mode=base;script=math;+ssum" at 10 pt \textfont1=\mathfont

\font\1="lmroman10-regular.otf" at 10 pt \1

\Umathcode∑="1"1∑ \let\sum=∑

abcd

$∑ab$% How to apply the slant only to the sum?

abcd

abcd

\bye

  • Thank you again, this is exactly what I want. All your answers show that you know very much about luaotfload. Is this the best way to slant a range of characters? Or do you know a better (simpler) solution? – Weißer Kater Sep 04 '22 at 07:26
  • @WeißerKater It depends a bit on how many characters you want to apply this to. Since you manually apply matrixes it can lead to rather big PDF files, especially when these characters are used a lot. Loading a slanted font and then pulling in individual letters from that through commands might be easier to optimize for the engine then. But I think doing it like this is fine, but trying to do fake bold like this might get tricky. – Marcel Krüger Sep 04 '22 at 15:31
  • OK, I understand. But how is the slant (and extend and embolden) font feature implemented in luaotfload? Does it apply such matrixes to every glyph? How does it work exactly? Sorry, I tried to find out by looking into the source code, but no chance. – Weißer Kater Sep 04 '22 at 16:33
  • luaotfload mostly just passes these on to the engine which directly implements them. Internally slant and extend set matrixes, but they manipulate the text matrix instead of the general graphics matrix. That matrix has to be set anyway (to set the position of the text) so it doesn't add a lot of overhead. embolden is a bit special since it's not a matrix but is being done by changing the text drawing mode to add an outline with a given width around every glyph. – Marcel Krüger Sep 04 '22 at 16:48
  • OK, can such a text matrix (that slants and extends glyphs) be set in the characters[...].commands to make this more efficient? If yes, how can I do it? – Weißer Kater Sep 04 '22 at 18:25
  • Not directly (well at least not in a way which would reuse the existing matrix) the input used there is set based on font settings AFAIK. That's why I mentioned loading a separate font with slant/extend features and then pulling glyphs from these: It reuses the existing system which already implements this. But if you only apply this to a relatively small number of glyphs then it shouldn't matter much anyway. – Marcel Krüger Sep 04 '22 at 19:17