bugGNU roff - Bugs: bug #60233, doc/groff.texi: ambiguity in .tkf...


bug #60233: doc/groff.texi: ambiguity in .tkf documentation

Submitter:  Dave <barx>
Submitted:  Sun 14 Mar 2021 11:18:09 PM UTC
Category:  Core Severity:  2 - Minor
Item Group:  Documentation Status:  Need Info
Privacy:  Public Assigned to:  None
Open/Closed:  Open Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup

Mon 22 May 2023 06:16:07 PM UTC, comment #4: 

comment #3:

> the concept introduction accurately says, "'Track kerning'
> expands or reduces the space between glyphs."

This doesn't say how this space is distributed--nor should it, IMHO: see bug #61828.

Dave <barx>
Group Member
Sat 15 Jan 2022 06:31:22 AM UTC, comment #3: 

Three more points:

  • Comment #2 quoted the manual text as it appeared in the original submission back in March, but since then an October commit (5380e8ad) changed "point size" to "type size."

  • The code snippet points out that the case of S2 <= S1 remains undocumented.
    • S1 == S2 is a legitimate use case if one wants only a specific type size affected, and that this (again, assuming I'm reading the code right) uses N1 as the adjustment, effectively discarding N2, ought to be documented.
    • The case of S2 < S1 is technically an error (the user is specifying a maximum less than the minimum), so documenting this is perhaps less important.  But it does seem notable that groff doesn't treat it as an error condition, silently using N1 here also.

  • While we're in the neighborhood: the concept introduction accurately says, "'Track kerning' expands or reduces the space between glyphs."  But the description of the .tkf request itself uses sloppier wording, saying "the width of every glyph is increased."  .tkf does not alter the width any glyphs, only the amount of space between them.
Dave <barx>
Group Member
Sat 15 Jan 2022 04:38:45 AM UTC, comment #2: 

So if I'm following the code correctly, the documentation could be made to match it by changing the phrase

if the point size is greater than or equal to S1 and less than or equal to S2


if the point size is greater than S1 and less than S2

or more simply

if the point size is between S1 and S2

or most (too?) simply



Dave <barx>
Group Member
Tue 11 Jan 2022 10:32:04 AM UTC, comment #1: 

Here is what I think is the relevant code from src/roff/troff/node.cpp.

hunits track_kerning_function::compute(int size)
  if (non_zero) {
    if (max_size <= min_size)
      return min_amount;
    else if (size <= min_size)
      return min_amount;
    else if (size >= max_size)
      return max_amount;
      return (scale(max_amount, size - min_size, max_size - min_size)
              + scale(min_amount, max_size - size, max_size - min_size));
    return H0;

It's very strange to me that track kerning functions get their own class, when there's only one implementation.  Either someone had big plans that never came to fruition, or I'm overlooking something.

G. Branden Robinson <gbranden>
Group administrator
Sun 14 Mar 2021 11:18:09 PM UTC, original submission:  

The description of the behavior of the .tkf request in doc/groff.texi contains a logic error.  It reads:

"if the current point size is less than or equal to S1 the width is increased by N1; if it is greater than or equal to S2 the width is increased by N2; if the point size is greater than or equal to S1 and less than or equal to S2 the increase in width is a linear function of the point size."

Translating these words to pseudocode, where PS is the current point size and W is the width:

if PS <= S1 then W += N1
if PS >= S2 then W += N2
if (PS >= S1 and PS <= S2) then W += f(PS)

This leaves two cases ambiguously defined: PS == S1 and PS == S2.  In the above statements, when PS == S1, the first and third conditions both apply; when PS == S2, the second and third both apply.

In practice, I don't think it matters: I believe (though someone should check my work) that for the case PS == S1, N1 and f(PS) are the same value; likewise, for the case PS == S2, N2 and f(PS) are equal.  If this is correct, the wording can be simplified and freed from ambiguity by striking either the first two or the last two of the "or equal to" phrases from the above.  (For ease of reading, I'd strike the last two, since that condition is already more complicated.)

If my evaluation is not correct, then someone will have to look at the code to see what is actually done in the PS == S1 and PS == S2 cases, and adjust the documentation accordingly.

Dave <barx>
Group Member


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by gbranden (Posted a comment)
  • -email is unavailable- added by barx (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.


    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-01-11 gbranden StatusNone Need Info

    Back to the top

    Powered by Savane 3.12