Hi, On 06/29/2010 11:15 AM, Paul Schalck wrote:
Hi,
I'm trying to use the full glyph range of the Palatino Linotype font shipped with XP (version 1.40; significantly different from the Windows 7 one) under MKIV. Everything works fine (oldstyle figures, sups for instance), except that the small cap "i" character has a dot whereas it shouldn't.
I borrowed one of the fonts from my wife's XP install (pala.ttf). The short answer: the font is borked, complain to Microsoft. The long answer: lookups are name-based, and if there are two glyphs with the same name, you can't know which one is used in any particular piece of software.
As far as I can see, it has to do with the messy name list of the glyphs. Both the normal small cap i and the small cap dotted i are named "i.sc"
The one with a dot is meant for Turkish.
Moreover, the small cap glyphs have no unicode numbers in this font, so I cannot pick them manually with \char"XXXX or even with \charXXXXX.
Any ideas how I can get the right dottless i?
Context always maps all unencoded glyphs into a private area starting at 0xF0000. For this font, the first i.sc (the one without dot) is at 0xF00AF and has glyph index 0x456, and the second is at 0xF00EB with glyph index 0x492. To find these numbers, run a file like this: \usemodule[fnt-10] \starttext \ShowCompleteFont{file:pala.ttf}{20pt}{1} \stoptext This means that to get the dotless version, you could enter \char"F00AF Really long answer: to fix the problem nicely, we have to rename one of the two glyphs. This could be done in an external editor, but as this is a system font, that may not be wise or even possible. Luckily, context allows to do this using a patching system that is active during initial font loading time (when the cache is generated). In the following, we will be patching the generated cache file before it is saved (by putting some lua code at the beginning of your test file). Remember that you have to delete the generated cache files after each iteration. In my case, they were /opt/tex/texmf- cache/luatex-cache/context/c24894930eb65eadf7b71f1e305ff518/fonts/otf/pala.tm*. If you forget to do this step in between runs, nothing will change in the output! The existing font patches are in font-pat.lua, and from that file it is possible to deduce that something like this is the correct program structure, theoretically: \startluacode function palapatch (data,filename) -- to be filled in end fonts.otf.enhancers.patches["^pala"] = palapatch \stopluacode The two arguments to the patch function are the data table from the luafontloader and the font file name, respectively. The function should patch the data table to our liking and does not have to return anything. In order to have a good look at the data, the first thing to do is to dump the data to a file. Put this code at the top of your test file, delete the data cache files, and run: \startluacode function palapatch (data,filename) io.savedata(filename .. '.lua', table.serialize(data)) end fonts.otf.enhancers.patches["^pala"] = palapatch \stopluacode \definefontfeature [...] Afterwards, open pala.ttf.lua (or pala.TTF.lua. not sure how this works out on an actual XP install) in an editor for browsing. Looking at the lua code in pala.ttf.lua, you will see that there is a pretty large sub-array called 'glyphs', which happens to be indexed by glyph id. There are two entries in that sub-array called 'i.sc' and we will want to change the second of those to 'i.scturkish' (the one at 0x492, the number we discovered above). Change the lua code to the code below, save your test file, delete the data cache again, and rerun. \startluacode function palapatch (data,filename) data.glyphs[0x492].name = "a.scturkish" end fonts.otf.enhancers.patches["^pala"] = palapatch \stopluacode That's one problem fixed. If you look at the test's pdf, it will now have dotless i's in the smallcaps. But now we have broken the turkish smallcaps code (it will now also use the first i.sc, which is wrong) so it is nice to fix that as well. Some searching back and forth through the pala.ttf.lua code reveals that there are two lookups that use i.sc: ss_latn_l_13_s (for normal latin) and ss_latn_l_14_s (for turkish). These lookups are part of the glyph definition of 'i' which lives at 0x92 (I found that number in the earlier font dump, but you could also count the entries in pala.ttf.lua, if you are bored or like counting stuff). Named lookups are small arrays (you can deduce that from the double braces in pala.ttf.lua), so the needed patch is: data.glyphs[0x92].lookups["ss_latn_l_14_s"][1].specification.variant="a.scturkish" And that will fix the turkish lookup. Now, I want to make sure we only run this code for palatino version 1.40 (it should be obvious why), and it is nice to do a terminal message as well. (note: testing for just the font version ignores the fact that different vendors may use the same font name for different fonts, but that is a complication that I think can be ignored in this particular case). The end result is: \startluacode function palapatch (data,filename) if data.version == "1.40" then logs.report("load otf", "patching smallcaps i") data.glyphs[0x92].lookups["ss_latn_l_14_s"][1].specification.variant="a.scturkish" data.glyphs[0x492].name = "a.scturkish" end end fonts.otf.enhancers.patches["^palatino"] = palapatch \stopluacode Updated test file attached. I hope this makes sense to someone who is willing to wikify the process. Best wishes, Taco