From 2dfa64040594cba00218ad3822b334d03a56d15b Mon Sep 17 00:00:00 2001 From: schwarze Date: Wed, 21 Jan 2015 19:40:22 +0000 Subject: [PATCH] Improve overstriking. When overstriking a wider character with a narrower one, center the latter horizontally. After a group of characters printed in the same position, advance by the width of the widest one among them. --- usr.bin/mandoc/term_ps.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/usr.bin/mandoc/term_ps.c b/usr.bin/mandoc/term_ps.c index 08cefafae09..4fc73dbcf21 100644 --- a/usr.bin/mandoc/term_ps.c +++ b/usr.bin/mandoc/term_ps.c @@ -1,7 +1,7 @@ -/* $OpenBSD: term_ps.c,v 1.36 2014/12/19 17:10:42 schwarze Exp $ */ +/* $OpenBSD: term_ps.c,v 1.37 2015/01/21 19:40:22 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2014 Ingo Schwarze + * Copyright (c) 2014, 2015 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -58,6 +58,7 @@ struct termp_ps { #define PS_NEWPAGE (1 << 2) /* new page, no words yet */ #define PS_BACKSP (1 << 3) /* last character was backspace */ size_t pscol; /* visible column (AFM units) */ + size_t pscolnext; /* used for overstrike */ size_t psrow; /* visible row (AFM units) */ char *psmarg; /* margin buf */ size_t psmargsz; /* margin buf size */ @@ -1067,7 +1068,7 @@ ps_fclose(struct termp *p) static void ps_letter(struct termp *p, int arg) { - size_t savecol; + size_t savecol, wx; char c; c = arg >= 128 || arg <= 0 ? '?' : arg; @@ -1139,7 +1140,30 @@ ps_letter(struct termp *p, int arg) ps_setfont(p, p->ps->nextf); } p->ps->nextf = TERMFONT_NONE; + + /* + * For an overstrike, if a previous character + * was wider, advance to center the new one. + */ + + if (p->ps->pscolnext) { + wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx; + if (p->ps->pscol + wx < p->ps->pscolnext) + p->ps->pscol = (p->ps->pscol + + p->ps->pscolnext - wx) / 2; + } + ps_pletter(p, p->ps->last); + + /* + * For an overstrike, if a previous character + * was wider, advance to the end of the old one. + */ + + if (p->ps->pscol < p->ps->pscolnext) { + ps_pclose(p); + p->ps->pscol = p->ps->pscolnext; + } } /* @@ -1153,13 +1177,19 @@ ps_letter(struct termp *p, int arg) /* * For an overstrike, back up to the previous position. + * If the previous character is wider than any it overstrikes, + * remember the current position, because it might also be + * wider than all that will overstrike it. */ if (savecol != SIZE_MAX) { + if (p->ps->pscolnext < p->ps->pscol) + p->ps->pscolnext = p->ps->pscol; ps_pclose(p); p->ps->pscol = savecol; p->ps->flags &= ~PS_BACKSP; - } + } else + p->ps->pscolnext = 0; } static void -- 2.20.1