bugGNU roff - Bugs: bug #57448, groff will not break a line at a...

 
 

bug #57448: groff will not break a line at a hard hyphen following some letter combinations

Submitter:  Dave <barx>
Submitted:  Thu 19 Dec 2019 01:16:37 PM UTC
   
 
Category:  Core Severity:  3 - Normal
Item Group:  Incorrect behaviour Status:  None
Privacy:  Public Assigned to:  None
Open/Closed:  Open Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 07 Aug 2023 04:11:31 AM UTC, comment #9: 

comment #8:

> My attempt to patch the font description file to rectify this shortcoming


Not to be coy, here is said patch, which by inspection looks like it should work when #64519 is fixed.

sed -Eni~ 'p;s/^([TVWY]) (-|hy) /\2 \1 /p' font/devps/TR

This works with GNU sed and is untested on any other variants.

This remains a side note to the current bug, but there seems little point in opening a new bug report for this until its blocker is removed.

Dave <barx>
Group Member
Mon 07 Aug 2023 03:28:11 AM UTC, comment #8: 

comment #3:

> (Side note: these four letters' glyphs are basically
> symmetrical, so it's unclear why this file lacks the same four
> combinations in reverse order; there are no kern pairs beginning
> with a hyphen.)


My attempt to patch the font description file to rectify this shortcoming stumbled into bug #64519.

Dave <barx>
Group Member
Sun 06 Aug 2023 03:45:01 PM UTC, comment #7: 

Here's a simpler example than the one in the original submission, showing that a combination of a single letter and a hyphen triggers the bug when there's a kernpair between that letter and the hyphen:

#!/bin/bash

(echo .ll 1p
 for letter in $(seq 65 90)
 do
   echo -e "\x$(printf %x $letter)"-shaped
   echo .br
 done
) | groff -Wbreak -a | grep .-.


Dave <barx>
Group Member
Thu 14 May 2020 06:40:59 AM UTC, comment #6: 

And it turns out that kern pairs need not even exist between every letter of a hyphen-containing phrase to trigger the bug.  For instance, the string "major-Y-axis" has only two kern pairs in the Times typeface: between "r" and "-", and "Y" and "-".  Yet groff will break at neither hyphen:


seq -w 0 99 | xargs -I FRACTION printf '.br\n.ll 3.FRACTIONc\nIt can show the major-Y-axis line\n' | groff -a | fgrep It | uniq


The problem disappears if the Y is turned into an X.

Dave <barx>
Group Member
Mon 23 Dec 2019 12:50:39 PM UTC, comment #5: 


>   If the kerning in front of the hyphen is removed (with '\&'),
> the expected result is there.


Well, not if the expected result is for kerning and line-breaking to simultaneously work. :)

If one needs a workaround, a better one is to add a zero-width breakpoint (\:) after the hyphen.

But the greater trick is figuring out all the places such a \: is needed.  In groff's default font set -- with relatively few kern pairs that have a hyphen as the second character -- the problem is limited in scope.  But for installed fonts with a larger set of kern pairs, the bug could crop up in unexpected places.  (And there is nothing magical about two characters: any number of kerned characters before a hyphen triggers the bug.)

Dave <barx>
Group Member
Sun 22 Dec 2019 11:37:45 PM UTC, comment #4: 

  If the kerning in front of the hyphen is removed (with '\&'),
the expected result is there.

  Whoever fixes this bug, should add (a lot of) explanations,
especially reasons.

Bjarni Ingi Gislason <bjarniig>
Fri 20 Dec 2019 10:36:27 AM UTC, comment #3: 

But you are correct that kerning appears to be what triggers the bug.

In the default font (TR), only four uppercase letters have kerning between them and a following hyphen:

$ sed -n '/^kernpairs/,/^$/p' /usr/share/groff/current/font/devps/TR | grep '^[[:upper:]] - '
T - -92
V - -100
W - -65
Y - -111

(Side note: these four letters' glyphs are basically symmetrical, so it's unclear why this file lacks the same four combinations in reverse order; there are no kern pairs beginning with a hyphen.)

Now look at all kern pairs beginning with any uppercase letter and ending with one of the above four:

$ sed -n '/^kernpairs/,/^$/p' /usr/share/groff/current/font/devps/TR | grep '^[[:upper:]] [TVWY]'

This generates my list of the 19 offending combinations.  Thus a more succinct bug description would be: groff fails to break a line at a hyphen following two uppercase letters when the font file specifies kerning both between those letters and between the second letter and the hyphen.

Curiously, the place where the line break should occur is never kerned: the break should always be after the hyphen, and no kern pairs have a hyphen as the first element.  It is kerning that occurs before (what should be) a breakpoint that somehow inhibits breaking at that point.

Dave <barx>
Group Member
Fri 20 Dec 2019 04:08:56 AM UTC, comment #2: 

How it kerns characters elsewhere on the line should have no effect on whether it is willing to break a line at a hard hyphen.  If it does, this is a bug.

groff will not break the line at a hyphen after these particular letter combinations.  You can verify this by varying the line length from 1 to 1.99 inches, a hundredth of an inch at a time, to see the various places groff breaks the line:

seq -w 0 99 | xargs -I FRACTION printf '.br\n.ll 1.FRACTIONi\nOne has the DW-style switch.\n' | groff -a | fgrep One | uniq

(The above is all one line, though this bug tracker will probably break it.)

Dave <barx>
Group Member
Thu 19 Dec 2019 11:13:40 PM UTC, comment #1: 

  The reason for this is the kerning,
which makes some of the text strings "XY-" to be thinner than others.

  Test with adding the ".kern 0" request.

  So I see no bug there.

Bjarni Ingi Gislason <bjarniig>
Thu 19 Dec 2019 01:16:37 PM UTC, original submission:  

I see this behavior in a build of the latest groff from git sources:

$ groff --version | head -1
GNU groff version 1.22.4.74-b400-dirty

as well as in earlier release versions, going back to at least 1.22.3.

$ groff -a <<EOF
.ll 1i
One has the AB-style switch.
EOF

This produces the output:

<beginning of page>
One has the AB-
style switch.

The same formatting is output by using any two capital letters in place of AB -- except in 19 of the possible 676 combinations.  If the two letters are AT, AV, AW, AY, DV, DW, DY, LT, LV, LW, LY, OT, OV, OW, OY, RT, RV, RW, or RY, groff will refuse to break the line at the hyphen, carrying over the entire "xx-style" phrase to the next line (or putting it all on the first line, if you increase .ll a bit).

This script generates all 676 combinations and shows which ones won't break at the hyphen:

#!/bin/bash

(echo .ll 1i
 for first in $(seq 65 90)
 do
   for second in $(seq 65 90)
   do
     echo -e One has the \
             "\x$(printf %x $first)\x$(printf %x $second)"-style \
             switch.
     echo .br
   done
 done
) | groff -a | grep -o ..-style

Dave <barx>
Group Member

 

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

Attach Files:
   
   
Comment:
   

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 bjarniig (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.

     

    No changes have been made to this item

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code