When rendering the \h (horizontal motion) low-level roff(7) escape
authorschwarze <schwarze@openbsd.org>
Mon, 10 Jan 2022 17:59:45 +0000 (17:59 +0000)
committerschwarze <schwarze@openbsd.org>
Mon, 10 Jan 2022 17:59:45 +0000 (17:59 +0000)
sequence in -T ps and -T pdf output mode, use an appropriate
horizontal distance by correctly using the term_len() utility
function.  Output from the -T ascii, -T utf8, and -T html modes
was already correct and remains unchanged.

Lennart Jablonka <hummsmith42 at gmail dot com> found and reported
this unit conversion bug (misinterpreting AFM units as if they were
en units) when rendering scdoc-generated manuals (which is a low
quality generator, but that's no excuse for mandoc misformatting \h)
on Alpine Linux.  Lennart also tested this patch.

usr.bin/mandoc/term.c

index 2be4eb4..9cc69aa 100644 (file)
@@ -1,6 +1,6 @@
-/* $OpenBSD: term.c,v 1.144 2021/10/04 18:56:24 schwarze Exp $ */
+/* $OpenBSD: term.c,v 1.145 2022/01/10 17:59:45 schwarze Exp $ */
 /*
- * Copyright (c) 2010-2021 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2022 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -634,12 +634,14 @@ term_word(struct termp *p, const char *word)
                        if (a2roffsu(seq, &su, SCALE_EM) == NULL)
                                continue;
                        uc += term_hen(p, &su);
-                       if (uc > 0)
-                               while (uc-- > 0)
+                       if (uc > 0) {
+                               while (uc > 0) {
                                        bufferc(p, ASCII_NBRSP);
-                       else if (p->col > (size_t)(-uc))
+                                       uc -= term_len(p, 1);
+                               }
+                       } else if (p->col > (size_t)(-uc)) {
                                p->col += uc;
-                       else {
+                       else {
                                uc += p->col;
                                p->col = 0;
                                if (p->tcol->offset > (size_t)(-uc)) {