6

I have a very strange effect while debugging yhmath math fonts items. I am generating cmex10.tfm from cmex10.mf, and convert the tfm to pl file.

Then I rename only rename the driver file to yrcmex10.mf, and add the following new glyph definitions in bigdel.mf, without changing anything in the rest of the files:

cmchar "\big left parenthesis";
beginchar(oct"200",8u#,rule_thickness#,2.5dh#-rule_thickness#);
adjust_fit(1.75u#,-.25u#); left_paren(hair,stem); endchar;

cmchar "\big left parenthesis";
beginchar(oct"201",10u#,rule_thickness#,3.5dh#-rule_thickness#);
adjust_fit(2.25u#,-.25u#); left_paren(hair,stem); endchar;


cmchar "\big left parenthesis";
beginchar(oct"202",12u#,rule_thickness#,4.5dh#-rule_thickness#);
adjust_fit(2.75u#,-.25u#); left_paren(hair,stem); endchar;

cmchar "\big left parenthesis";
beginchar(oct"203",13u#,rule_thickness#,5dh#-rule_thickness#);
adjust_fit(3u#,-.25u#); left_paren(hair,stem); endchar;


cmchar "\big left parenthesis";
beginchar(oct"204",15u#,rule_thickness#,6dh#-rule_thickness#);
adjust_fit(3.5u#,-.25u#); left_paren(hair,stem); endchar;

cmchar "\big left parenthesis";
beginchar(oct"205",17u#,rule_thickness#,7dh#-rule_thickness#);
adjust_fit(4u#,-.25u#); left_paren(hair,stem); endchar;

cmchar "\big left parenthesis";
beginchar(oct"206",19u#,rule_thickness#,8dh#-rule_thickness#);
adjust_fit(4.5u#,-.25u#); left_paren(hair,stem); endchar;

So the only diff between the cmex10 font and yrcmex10 font is the addition of the above characters.

Converting both tfm to pl, and making a diff I see changes in unrelated glpyphs, in particular the DP parameter changes:

--- cmex10.pl   2019-03-07 09:30:01.263513678 +0900
+++ yrcmex10.pl 2019-03-07 09:52:25.578670436 +0900
@@ -1,7 +1,7 @@
 (DESIGNSIZE R 10.0)
 (COMMENT DESIGNSIZE IS IN POINTS)
 (COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)
-(CHECKSUM O 37254272422)
+(CHECKSUM O 35311171576)
 (FONTDIMEN
    (SLANT R 0.0)
    (SPACE R 0.0)
@@ -20,85 +20,85 @@
 (CHARACTER O 0
    (CHARWD R 0.458336)
    (CHARHT R 0.039999)
-   (CHARDP R 1.160013)
+   (CHARDP R 1.135567)
    (NEXTLARGER O 20)
    )
 (CHARACTER O 1
    (CHARWD R 0.458336)
    (CHARHT R 0.039999)
-   (CHARDP R 1.160013)
+   (CHARDP R 1.135567)
    (NEXTLARGER O 21)
    )
...

This is very surprising, I would have guessed that the glyph dimensions of other non-changed glphs do not change. Furthermore, this changes become bigger the more additional glyphs I add.

Anyone having an explanation for this?

norbert
  • 8,235
  • Just to check: as you made two changes (renamed and added glyphs), can you double-check that simply renaming doesn't cause any changes? It would be crazy if that were the case, but still good to rule it out first, just in case. :-) Beyond that, I imagine one of the statements, maybe adjust_fit, has some side-effects (but saying so is practically only an restatement of the question, not an explanation). – ShreevatsaR Mar 07 '19 at 01:04
  • 1
    Yes, that I checked. Renaming only without adding the above code does not changes anything. A simple endinput. before the added code also suffices to get the original metrics. – norbert Mar 07 '19 at 03:51
  • did you get a warning about lengths changing, there are a fixed number of distinct lengths in a tfm file to bit-pack the information – David Carlisle Mar 07 '19 at 07:48
  • ah so you did get the warning:-) – David Carlisle Mar 07 '19 at 13:29
  • Actually not that I remember, but I will check ... I used maketextfm --destdir ... and I don't remember seeing a warning ... – norbert Mar 07 '19 at 14:18
  • Ok, the warning is there (some chardp values had to be adjusted by as much as 0.24446pt), just didn't see it ... :-( – norbert Mar 07 '19 at 14:33
  • In addition to the limit on number of different depths, it sometimes happens that other values don't change for consecutive glyphs in an .mf file, so they aren't repeated for the next or subsequent glyphs after the value is first set. If a new glyph is inserted between two such glyphs and a particular value is reset, the result can be a surprise for the glyphs following the new one. (Happens in one of the cm fonts. though I've forgotten which one; I can probably recover the info if you're interested.) – barbara beeton Mar 07 '19 at 17:03

1 Answers1

5

According to MetaFont, The Program:

Since it is quite common for many characters to have the same height, depth, or italic correction, the TFM format imposes a limit of 16 different heights, 16 different depths, and 64 different italic corrections.

Incidentally, the relation width[0]=height[0]=depth[0]= italic[0]=0 should always hold, so that an index of zero implies a value of zero.

So there can be at most 15 different depth values beside 0 in a single TFM file. Now let's look at the depth values in your yrcmex10.pl:

     1     (CHARDP R 0.300003)
     2     (CHARDP R 0.580007)
     3     (CHARDP R 0.900009)
     4     (CHARDP R 1.000013)
     5     (CHARDP R 1.135567)
     6     (CHARDP R 1.480014)
     7     (CHARDP R 1.780019)
     8     (CHARDP R 2.060022)
     9     (CHARDP R 2.222246)
    10     (CHARDP R 2.360025)
    11     (CHARDP R 2.660028)
    12     (CHARDP R 2.9600315)
    13     (CHARDP R 3.560038)
    14     (CHARDP R 4.160044)
    15     (CHARDP R 4.76005)

(List generated using grep 'CHARDP' yrcmex10.pl|sort|uniq|nl)

So your font already contains the maximal number of distinct depths, which explains the changes: The depth of 0 was 1.160013, but this value is not a part of the list above. So it would have to be added, but then there would be too many distinct depths. So when MetaFont read the additional characters, it realized that it could not store all the depths in the TFM file. So some values had to be rounded, and 1.135567 and 1.160013 are very close, making them ideal candidates.

This also explains why the change becomes bigger the more additional glyphs you add: If the new glyphs again have different depths, there are even more distinct depths MetaFont has to reduce to 15. This requires being more aggressive about "value unification", resulting in bigger changes.

  • Thanks for the hint, that is very valuable!!!! Now I only need to figure out a way how to deal with this when multiple glyphs are available ... thanks again! – norbert Mar 07 '19 at 11:26
  • Hi Marcel, since you are obviously very adept, another question: Does the same restriction apply to tfm files, esp. can I use a vpl file that has more different depth values than 15, and generate a vf and tfm from it? – norbert Mar 07 '19 at 14:19
  • Ahh, answering my own question: it is pertinent to tfm files, so no way around :-( – norbert Mar 07 '19 at 14:21
  • @norbert AFAICT you would need LuaTeX to fix this, and it does not sound like a LuaTeX only solution would fit your use-case. – Marcel Krüger Mar 07 '19 at 14:41
  • 1
    BTW (as I was curious about the amount of rounding error), the change here is 0.24446pt ≈ 0.003395in (≈ 0.086mm), which though very tiny for the eye to care about, can make a difference of at least one pixel (“dot”) at resolution of 300 dpi or higher. – ShreevatsaR Mar 07 '19 at 14:50
  • @ShreevatsaR Indeed the rounding error is tiny. But it messes up with how TeX chooses the next larger delimiter. See this TeX.SX question, which originated from this GitHub issue I opened. Now I’m convinced that the “15 depths” limit is solely responsible. – Ruixi Zhang Mar 07 '19 at 17:34
  • @RuixiZhang Oh that's sad. Shows how the tiniest errors can have large consequences (also seen with floating-point calculations outside of TeX). – ShreevatsaR Mar 07 '19 at 17:59
  • 1
    @ShreevatsaR In fact, I think I’m reminded yet again how Knuth is so efficient — everything is designed to be as compact as possible. If one wants more sizes, one must exploit the already very compact format… – Ruixi Zhang Mar 07 '19 at 18:51