=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/term_ps.c,v retrieving revision 1.31 retrieving revision 1.32 diff -c -r1.31 -r1.32 *** src/usr.bin/mandoc/term_ps.c 2014/08/28 01:36:10 1.31 --- src/usr.bin/mandoc/term_ps.c 2014/10/27 20:41:16 1.32 *************** *** 1,4 **** ! /* $OpenBSD: term_ps.c,v 1.31 2014/08/28 01:36:10 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: term_ps.c,v 1.32 2014/10/27 20:41:16 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze *************** *** 57,68 **** #define PS_INLINE (1 << 0) /* we're in a word */ #define PS_MARGINS (1 << 1) /* we're in the margins */ #define PS_NEWPAGE (1 << 2) /* new page, no words yet */ size_t pscol; /* visible column (AFM units) */ size_t psrow; /* visible row (AFM units) */ char *psmarg; /* margin buf */ size_t psmargsz; /* margin buf size */ size_t psmargcur; /* cur index in margin buf */ ! char last; /* character buffer */ enum termfont lastf; /* last set font */ enum termfont nextf; /* building next font here */ size_t scale; /* font scaling factor */ --- 57,69 ---- #define PS_INLINE (1 << 0) /* we're in a word */ #define PS_MARGINS (1 << 1) /* we're in the margins */ #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 psrow; /* visible row (AFM units) */ char *psmarg; /* margin buf */ size_t psmargsz; /* margin buf size */ size_t psmargcur; /* cur index in margin buf */ ! char last; /* last non-backspace seen */ enum termfont lastf; /* last set font */ enum termfont nextf; /* building next font here */ size_t scale; /* font scaling factor */ *************** *** 1042,1048 **** */ if (p->ps->last != '\0') { ! assert(p->ps->last != 8); if (p->ps->nextf != p->ps->lastf) { ps_pclose(p); ps_setfont(p, p->ps->nextf); --- 1043,1049 ---- */ if (p->ps->last != '\0') { ! assert( ! (p->ps->flags & PS_BACKSP)); if (p->ps->nextf != p->ps->lastf) { ps_pclose(p); ps_setfont(p, p->ps->nextf); *************** *** 1061,1085 **** static void ps_letter(struct termp *p, int arg) { char c; c = arg >= 128 || arg <= 0 ? '?' : arg; /* ! * When receiving an initial character, merely buffer it, ! * because a backspace might follow to specify formatting. ! * When receiving a backspace, use the buffered character ! * to build the font instruction and clear the buffer. ! * Only when there are two non-backspace characters in a row, ! * activate the font built so far and print the first of them; ! * the second, again, merely gets buffered. ! * The final character will get printed from ps_fclose(). */ ! if (c == 8) { assert(p->ps->last != '\0'); ! assert(p->ps->last != 8); ! if ('_' == p->ps->last) { switch (p->ps->nextf) { case TERMFONT_BI: break; --- 1062,1091 ---- static void ps_letter(struct termp *p, int arg) { + size_t savecol; char c; c = arg >= 128 || arg <= 0 ? '?' : arg; /* ! * When receiving a backspace, merely flag it. ! * We don't know yet whether it is ! * a font instruction or an overstrike. */ ! if (c == '\b') { assert(p->ps->last != '\0'); ! assert( ! (p->ps->flags & PS_BACKSP)); ! p->ps->flags |= PS_BACKSP; ! return; ! } ! ! /* ! * Decode font instructions. ! */ ! ! if (p->ps->flags & PS_BACKSP) { ! if (p->ps->last == '_') { switch (p->ps->nextf) { case TERMFONT_BI: break; *************** *** 1089,1095 **** default: p->ps->nextf = TERMFONT_UNDER; } ! } else { switch (p->ps->nextf) { case TERMFONT_BI: break; --- 1095,1105 ---- default: p->ps->nextf = TERMFONT_UNDER; } ! p->ps->last = c; ! p->ps->flags &= ~PS_BACKSP; ! return; ! } ! if (p->ps->last == c) { switch (p->ps->nextf) { case TERMFONT_BI: break; *************** *** 1099,1106 **** default: p->ps->nextf = TERMFONT_BOLD; } } ! } else if (p->ps->last != '\0' && p->ps->last != 8) { if (p->ps->nextf != p->ps->lastf) { ps_pclose(p); ps_setfont(p, p->ps->nextf); --- 1109,1134 ---- default: p->ps->nextf = TERMFONT_BOLD; } + p->ps->flags &= ~PS_BACKSP; + return; } ! ! /* ! * This is not a font instruction, but rather ! * the next character. Prepare for overstrike. ! */ ! ! savecol = p->ps->pscol; ! } else ! savecol = SIZE_MAX; ! ! /* ! * We found the next character, so the font instructions ! * for the previous one are complete. ! * Use them and print it. ! */ ! ! if (p->ps->last != '\0') { if (p->ps->nextf != p->ps->lastf) { ps_pclose(p); ps_setfont(p, p->ps->nextf); *************** *** 1108,1114 **** --- 1136,1160 ---- p->ps->nextf = TERMFONT_NONE; ps_pletter(p, p->ps->last); } + + /* + * Do not print the current character yet because font + * instructions might follow; only remember it. + * For the first character, nothing else is done. + * The final character will get printed from ps_fclose(). + */ + p->ps->last = c; + + /* + * For an overstrike, back up to the previous position. + */ + + if (savecol != SIZE_MAX) { + ps_pclose(p); + p->ps->pscol = savecol; + p->ps->flags &= ~PS_BACKSP; + } } static void