Hi, It is suggested that the width of each character should be adjusted in font files (font/devutf8/NOTES).
However, since the width of some Unicode character may differ under different locale settings, I wonder if font files are really sufficient for every user. The attached is a patch to compute character width on the fly. The patch is currently useless with the trunk, but with Colin Walters' charclass branch I confirmed that it renders Japanese man pages with the kinsoku shori applied correctly (er, mostly, it looks some kind of hyphenation is necessary for non-punct Japanese characters): http://ueno.fedorapeople.org/groff/kinsoku.png
=== modified file 'configure.ac' --- configure.ac 2009-06-25 16:37:53 +0000 +++ configure.ac 2010-07-29 03:43:11 +0000 @@ -77,7 +77,8 @@ # checks for headers AC_CHECK_HEADERS([stddef.h stdlib.h unistd.h dirent.h limits.h sys/dir.h \ - string.h strings.h math.h sys/time.h direct.h process.h]) + string.h strings.h math.h sys/time.h direct.h process.h \ + wchar.h]) GROFF_ISC_SYSV3 GROFF_POSIX @@ -128,7 +129,7 @@ # vsnprintf is in the same source file as snprintf AC_CHECK_FUNCS([vsnprintf], [], [AC_LIBOBJ([snprintf])]) LIBS="$saved_libs" -AC_CHECK_FUNCS([gettimeofday isatty kill rename setlocale strsep]) +AC_CHECK_FUNCS([gettimeofday isatty kill rename setlocale strsep wcwidth]) GROFF_MKSTEMP AC_CHECK_DECLS([sys_siglist, getc_unlocked]) AM_LANGINFO_CODESET === modified file 'src/devices/grotty/tty.cpp' --- src/devices/grotty/tty.cpp 2010-05-23 05:09:00 +0000 +++ src/devices/grotty/tty.cpp 2010-07-29 03:43:11 +0000 @@ -877,6 +877,7 @@ { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; + setlocale(LC_CTYPE, ""); while ((c = getopt_long(argc, argv, "bBcdfF:hiI:oruUv", long_options, NULL)) != EOF) switch(c) { === modified file 'src/include/lib.h' --- src/include/lib.h 2009-06-25 16:37:53 +0000 +++ src/include/lib.h 2010-07-29 03:43:11 +0000 @@ -48,6 +48,13 @@ #define getlocale(category) ((void)(category), (char *)"C") #endif /* !HAVE_SETLOCALE */ +#ifdef HAVE_WCWIDTH +#include <wchar.h> +#else +typedef int wchar_t; +#define wcwidth(c) ((wchar_t)-1) +#endif + char *strsave(const char *s); int is_prime(unsigned); double groff_hypot(double, double); === modified file 'src/libs/libgroff/font.cpp' --- src/libs/libgroff/font.cpp 2009-01-05 20:10:29 +0000 +++ src/libs/libgroff/font.cpp 2010-07-29 03:43:11 +0000 @@ -376,6 +376,9 @@ int width = 24; // value found in the original font files // XXX: this must be eventually moved back to the // font description file! + int w = wcwidth(get_code(g)); + if (w > 0) + width *= w; if (real_size == unitwidth || font::unscaled_charwidths) return width; else @@ -995,6 +998,11 @@ t.error("bad code `%1' for character `%2'", p, nm); return 0; } + // XXX: this could be moved to font files, as suggested in + // font/devutf8/NOTE. + int w = wcwidth(metric.code); + if (w > 0) + metric.width *= w; p = strtok(0, WS); if ((p == NULL) || (strcmp(p, "--") == 0)) { metric.special_device_coding = NULL; === modified file 'src/roff/troff/input.cpp' --- src/roff/troff/input.cpp 2009-12-31 07:49:45 +0000 +++ src/roff/troff/input.cpp 2010-07-29 03:43:11 +0000 @@ -7538,6 +7538,7 @@ #if defined(DEBUGGING) #define DEBUG_OPTION "D" #endif + setlocale(LC_CTYPE, ""); while ((c = getopt_long(argc, argv, "abciI:vw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU" DEBUG_OPTION, long_options, 0))
Regards, -- Daiki Ueno