static void ps_fclose(struct termp *p) { /* * Strong closure: if we have a last-char, spit it out after * checking that we're in the right font mode. This will of * course open a new scope, if applicable. * * Following this, close out any scope that's open. */ if ('\0' != p->ps->last) { if (p->ps->lastf != TERMFONT_NONE) { ps_pclose(p); ps_setfont(p, TERMFONT_NONE); } ps_pletter(p, p->ps->last); p->ps->last = '\0'; } if ( ! (PS_INLINE & p->ps->flags)) return; ps_pclose(p); }
static void ps_letter(struct termp *p, int arg) { char cc, c; /* LINTED */ c = arg >= 128 || arg <= 0 ? '?' : arg; /* * State machine dictates whether to buffer the last character * or not. Basically, encoded words are detected by checking if * we're an "8" and switching on the buffer. Then we put "8" in * our buffer, and on the next charater, flush both character * and buffer. Thus, "regular" words are detected by having a * regular character and a regular buffer character. */ if ('\0' == p->ps->last) { assert(8 != c); p->ps->last = c; return; } else if (8 == p->ps->last) { assert(8 != c); p->ps->last = '\0'; } else if (8 == c) { assert(8 != p->ps->last); if ('_' == p->ps->last) { if (p->ps->lastf != TERMFONT_UNDER) { ps_pclose(p); ps_setfont(p, TERMFONT_UNDER); } } else if (p->ps->lastf != TERMFONT_BOLD) { ps_pclose(p); ps_setfont(p, TERMFONT_BOLD); } p->ps->last = c; return; } else { if (p->ps->lastf != TERMFONT_NONE) { ps_pclose(p); ps_setfont(p, TERMFONT_NONE); } cc = p->ps->last; p->ps->last = c; c = cc; } ps_pletter(p, c); }
static void ps_letter(struct termp *p, int arg) { size_t savecol, wx; 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; case TERMFONT_BOLD: p->ps->nextf = TERMFONT_BI; break; 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; case TERMFONT_UNDER: p->ps->nextf = TERMFONT_BI; break; 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); } 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; } } /* * 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 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; }