fonts.handlers.otf.addfeature in luaotfload can be used to create custom features for fonts.

The unicode values of glyphs can be used for CID fonts in the same way as for GID fonts, but some fonts have variant characters accessible via internal features. Can these be accessed individually by CID in custom features?

(E.g. Ten Mincho has ligatures and alternates for both Latin and CJK. In the example I will use the more easily available Source Han.)


The goal is to substitute any explicit CID for any other, in this case 40355 . (This would be easily solved with language features, but illustrates the main issue, if the font had alternate glyphs not well accessible individually otherwise.)

\pdfvariable compresslevel 0
\pdfvariable objcompresslevel 0

fonts.handlers.otf.addfeature {
  name = "noff",
  type = "multiple",
  data = {
    ["f_f"] = { "f", "f" },
fonts.handlers.otf.addfeature {
  name = "test",
  type = "substitution",
  data = {
    ["A"] = 0x8FF0, -- Unicode code point does not use the alternate.
    ["B"] = "Z", -- GID works for the CID font. Does the alternate have a GID?
    ["C"] = 40355, -- Decimal CID value is treated as decimal Unicode, 鶣.
    [37] = "Y", -- Attempt to turn CID 37 "D" into "Y"
    [38] = 40355, -- Attempt to turn CID 38 "E" into CID of alternate 述




{\addfontfeature{RawFeature=+noff}ff} %% has no expected effect as it uses CID

{\addfontfeature{Language=Chinese Simplified}述} %% glyph to be substituted

{\addfontfeature{RawFeature=+test}A B C D E} %% test the feature


  • 1
    source han may be easily available but it is rather painful for tests as it is so large. But beside this, there should be no problem to do such substituations - you only need the slot number used to store the glyph. – Ulrike Fischer Oct 13 '18 at 22:28
  • I used the smallest CID font I could find; the format is for large fonts after all. How can the slot number be found? Is it different from the CID? FontForge shows CID and an invalid UTF in the status bar, and a valid UTF in the detailed glyph info. – svenper Oct 13 '18 at 22:38
  • 1
    Look in the lua-file created in the luatex cache folder. – Ulrike Fischer Oct 13 '18 at 23:04
  • That worked well. For reference I used [65] = 997389 in the feature data. Short of a font file update, could anything stealthily change these slot numbers? – svenper Oct 14 '18 at 9:51
  • Depends a bit why it got there. The fontloader is moving glyphs around. Does it have a name too? – Ulrike Fischer Oct 14 '18 at 10:58

Your Answer

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

Browse other questions tagged or ask your own question.