=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/term_ps.c,v retrieving revision 1.5 retrieving revision 1.6 diff -c -r1.5 -r1.6 *** src/usr.bin/mandoc/term_ps.c 2010/06/29 15:49:52 1.5 --- src/usr.bin/mandoc/term_ps.c 2010/07/13 01:09:13 1.6 *************** *** 1,6 **** ! /* $Id: term_ps.c,v 1.5 2010/06/29 15:49:52 schwarze Exp $ */ /* ! * Copyright (c) 2008, 2009 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above --- 1,6 ---- ! /* $Id: term_ps.c,v 1.6 2010/07/13 01:09:13 schwarze Exp $ */ /* ! * Copyright (c) 2010 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above *************** *** 27,39 **** #include #include #include #include "out.h" #include "main.h" #include "term.h" struct glyph { ! int wx; /* WX in AFM */ }; struct font { --- 27,48 ---- #include #include #include + #include #include "out.h" #include "main.h" #include "term.h" + /* Convert PostScript point "x" to an AFM unit. */ + #define PNT2AFM(p, x) /* LINTED */ \ + (size_t)((double)(x) * (1000.0 / (double)(p)->engine.ps.scale)) + + /* Convert an AFM unit "x" to a PostScript points */ + #define AFM2PNT(p, x) /* LINTED */ \ + (size_t)((double)(x) / (1000.0 / (double)(p)->engine.ps.scale)) + struct glyph { ! size_t wx; /* WX in AFM */ }; struct font { *************** *** 49,344 **** */ static const struct font fonts[TERMFONT__MAX] = { ! { "Courier", { ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, } }, ! { "Courier-Bold", { ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, } }, ! { "Courier-Oblique", { ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, ! { 600 }, } }, }; --- 58,353 ---- */ static const struct font fonts[TERMFONT__MAX] = { ! { "Times-Roman", { ! { 250 }, ! { 333 }, ! { 408 }, ! { 500 }, ! { 500 }, ! { 833 }, ! { 778 }, ! { 333 }, ! { 333 }, ! { 333 }, ! { 500 }, ! { 564 }, ! { 250 }, ! { 333 }, ! { 250 }, ! { 278 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 278 }, ! { 278 }, ! { 564 }, ! { 564 }, ! { 564 }, ! { 444 }, ! { 921 }, ! { 722 }, ! { 667 }, ! { 667 }, ! { 722 }, ! { 611 }, ! { 556 }, ! { 722 }, ! { 722 }, ! { 333 }, ! { 389 }, ! { 722 }, ! { 611 }, ! { 889 }, ! { 722 }, ! { 722 }, ! { 556 }, ! { 722 }, ! { 667 }, ! { 556 }, ! { 611 }, ! { 722 }, ! { 722 }, ! { 944 }, ! { 722 }, ! { 722 }, ! { 611 }, ! { 333 }, ! { 278 }, ! { 333 }, ! { 469 }, ! { 500 }, ! { 333 }, ! { 444 }, ! { 500 }, ! { 444 }, ! { 500}, ! { 444}, ! { 333}, ! { 500}, ! { 500}, ! { 278}, ! { 278}, ! { 500}, ! { 278}, ! { 778}, ! { 500}, ! { 500}, ! { 500}, ! { 500}, ! { 333}, ! { 389}, ! { 278}, ! { 500}, ! { 500}, ! { 722}, ! { 500}, ! { 500}, ! { 444}, ! { 480}, ! { 200}, ! { 480}, ! { 541}, } }, ! { "Times-Bold", { ! { 250 }, ! { 333 }, ! { 555 }, ! { 500 }, ! { 500 }, ! { 1000 }, ! { 833 }, ! { 333 }, ! { 333 }, ! { 333 }, ! { 500 }, ! { 570 }, ! { 250 }, ! { 333 }, ! { 250 }, ! { 278 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 333 }, ! { 333 }, ! { 570 }, ! { 570 }, ! { 570 }, ! { 500 }, ! { 930 }, ! { 722 }, ! { 667 }, ! { 722 }, ! { 722 }, ! { 667 }, ! { 611 }, ! { 778 }, ! { 778 }, ! { 389 }, ! { 500 }, ! { 778 }, ! { 667 }, ! { 944 }, ! { 722 }, ! { 778 }, ! { 611 }, ! { 778 }, ! { 722 }, ! { 556 }, ! { 667 }, ! { 722 }, ! { 722 }, ! { 1000 }, ! { 722 }, ! { 722 }, ! { 667 }, ! { 333 }, ! { 278 }, ! { 333 }, ! { 581 }, ! { 500 }, ! { 333 }, ! { 500 }, ! { 556 }, ! { 444 }, ! { 556 }, ! { 444 }, ! { 333 }, ! { 500 }, ! { 556 }, ! { 278 }, ! { 333 }, ! { 556 }, ! { 278 }, ! { 833 }, ! { 556 }, ! { 500 }, ! { 556 }, ! { 556 }, ! { 444 }, ! { 389 }, ! { 333 }, ! { 556 }, ! { 500 }, ! { 722 }, ! { 500 }, ! { 500 }, ! { 444 }, ! { 394 }, ! { 220 }, ! { 394 }, ! { 520 }, } }, ! { "Times-Italic", { ! { 250 }, ! { 333 }, ! { 420 }, ! { 500 }, ! { 500 }, ! { 833 }, ! { 778 }, ! { 333 }, ! { 333 }, ! { 333 }, ! { 500 }, ! { 675 }, ! { 250 }, ! { 333 }, ! { 250 }, ! { 278 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 333 }, ! { 333 }, ! { 675 }, ! { 675 }, ! { 675 }, ! { 500 }, ! { 920 }, ! { 611 }, ! { 611 }, ! { 667 }, ! { 722 }, ! { 611 }, ! { 611 }, ! { 722 }, ! { 722 }, ! { 333 }, ! { 444 }, ! { 667 }, ! { 556 }, ! { 833 }, ! { 667 }, ! { 722 }, ! { 611 }, ! { 722 }, ! { 611 }, ! { 500 }, ! { 556 }, ! { 722 }, ! { 611 }, ! { 833 }, ! { 611 }, ! { 556 }, ! { 556 }, ! { 389 }, ! { 278 }, ! { 389 }, ! { 422 }, ! { 500 }, ! { 333 }, ! { 500 }, ! { 500 }, ! { 444 }, ! { 500 }, ! { 444 }, ! { 278 }, ! { 500 }, ! { 500 }, ! { 278 }, ! { 278 }, ! { 444 }, ! { 278 }, ! { 722 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 500 }, ! { 389 }, ! { 389 }, ! { 278 }, ! { 500 }, ! { 444 }, ! { 667 }, ! { 444 }, ! { 444 }, ! { 389 }, ! { 400 }, ! { 275 }, ! { 400 }, ! { 541 }, } }, }; *************** *** 359,371 **** } while (/* CONSTCOND */ 0) ! static void ps_letter(struct termp *, char); static void ps_begin(struct termp *); static void ps_end(struct termp *); - static void ps_advance(struct termp *, size_t); static void ps_endline(struct termp *); static void ps_fclose(struct termp *); ! static size_t ps_width(const struct termp *, char); static void ps_pclose(struct termp *); static void ps_pletter(struct termp *, int); static void ps_printf(struct termp *, const char *, ...); --- 368,382 ---- } while (/* CONSTCOND */ 0) ! static double ps_hspan(const struct termp *, ! const struct roffsu *); ! static size_t ps_width(const struct termp *, char); ! static void ps_advance(struct termp *, size_t); static void ps_begin(struct termp *); static void ps_end(struct termp *); static void ps_endline(struct termp *); static void ps_fclose(struct termp *); ! static void ps_letter(struct termp *, char); static void ps_pclose(struct termp *); static void ps_pletter(struct termp *, int); static void ps_printf(struct termp *, const char *, ...); *************** *** 377,433 **** ps_alloc(char *outopts) { struct termp *p; ! size_t pagex, pagey, margin; const char *toks[2]; char *v; if (NULL == (p = term_alloc(TERMENC_ASCII))) return(NULL); ! /* Default is USA letter. */ ! pagex = 612; ! pagey = 792; ! margin = 72; ! ! p->type = TERMTYPE_PS; ! p->letter = ps_letter; p->begin = ps_begin; p->end = ps_end; - p->advance = ps_advance; p->endline = ps_endline; p->width = ps_width; ! toks[0] = "paper"; toks[1] = NULL; while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): ! if (0 == strcasecmp(v, "a4")) { ! pagex = 595; ! pagey = 842; ! } else if (0 == strcasecmp(v, "letter")) { ! pagex = 612; ! pagey = 792; ! } break; default: break; } ! assert(margin * 2 < pagex); ! assert(margin * 2 < pagey); p->engine.ps.width = pagex; p->engine.ps.height = pagey; ! p->engine.ps.header = pagey - (margin / 2); ! p->engine.ps.top = pagey - margin; ! p->engine.ps.footer = (margin / 2); ! p->engine.ps.bottom = margin; ! p->engine.ps.left = margin; ! p->engine.ps.lineheight = 12; ! p->defrmargin = pagex - (margin * 2); return(p); } --- 388,487 ---- ps_alloc(char *outopts) { struct termp *p; ! size_t pagex, pagey, marginx, marginy, lineheight; const char *toks[2]; + const char *pp; char *v; if (NULL == (p = term_alloc(TERMENC_ASCII))) return(NULL); ! p->advance = ps_advance; p->begin = ps_begin; p->end = ps_end; p->endline = ps_endline; + p->hspan = ps_hspan; + p->letter = ps_letter; + p->type = TERMTYPE_PS; p->width = ps_width; ! toks[0] = "paper"; toks[1] = NULL; + pp = NULL; + while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): ! pp = v; break; default: break; } ! /* Default to US letter (millimetres). */ + pagex = 216; + pagey = 279; + + /* + * The ISO-269 paper sizes can be calculated automatically, but + * it would require bringing in -lm for pow() and I'd rather not + * do that. So just do it the easy way for now. Since this + * only happens once, I'm not terribly concerned. + */ + + if (pp && strcasecmp(pp, "letter")) { + if (0 == strcasecmp(pp, "a3")) { + pagex = 297; + pagey = 420; + } else if (0 == strcasecmp(pp, "a4")) { + pagex = 210; + pagey = 297; + } else if (0 == strcasecmp(pp, "a5")) { + pagex = 148; + pagey = 210; + } else if (0 == strcasecmp(pp, "legal")) { + pagex = 216; + pagey = 356; + } else if (2 != sscanf(pp, "%zux%zu", &pagex, &pagey)) + fprintf(stderr, "%s: Unknown paper\n", pp); + } else if (NULL == pp) + pp = "letter"; + + /* + * This MUST be defined before any PNT2AFM or AFM2PNT + * calculations occur. + */ + + p->engine.ps.scale = 11; + + /* Remember millimetres -> AFM units. */ + + pagex = PNT2AFM(p, ((double)pagex * 2.834)); + pagey = PNT2AFM(p, ((double)pagey * 2.834)); + + /* Margins are 1/9 the page x and y. */ + + marginx = /* LINTED */ + (size_t)((double)pagex / 9.0); + marginy = /* LINTED */ + (size_t)((double)pagey / 9.0); + + /* Line-height is 1.4em. */ + + lineheight = PNT2AFM(p, ((double)p->engine.ps.scale * 1.4)); + p->engine.ps.width = pagex; p->engine.ps.height = pagey; ! p->engine.ps.header = pagey - (marginy / 2) - (lineheight / 2); ! p->engine.ps.top = pagey - marginy; ! p->engine.ps.footer = (marginy / 2) - (lineheight / 2); ! p->engine.ps.bottom = marginy; ! p->engine.ps.left = marginx; ! p->engine.ps.lineheight = lineheight; ! p->defrmargin = pagex - (marginx * 2); return(p); } *************** *** 460,466 **** * into our growable margin buffer. */ ! if ( ! (PS_MARGINS & p->engine.ps.psstate)) { vprintf(fmt, ap); va_end(ap); return; --- 514,520 ---- * into our growable margin buffer. */ ! if ( ! (PS_MARGINS & p->engine.ps.flags)) { vprintf(fmt, ap); va_end(ap); return; *************** *** 489,495 **** /* See ps_printf(). */ ! if ( ! (PS_MARGINS & p->engine.ps.psstate)) { putchar(c); return; } --- 543,549 ---- /* See ps_printf(). */ ! if ( ! (PS_MARGINS & p->engine.ps.flags)) { putchar(c); return; } *************** *** 513,524 **** * well as just one. */ ! assert(0 == p->engine.ps.psstate); ! assert('\0' == p->engine.ps.last); ! assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]); ! printf("%s", p->engine.ps.psmarg); ! p->engine.ps.pages++; ! printf("showpage\n"); printf("%%%%Trailer\n"); printf("%%%%Pages: %zu\n", p->engine.ps.pages); --- 567,580 ---- * well as just one. */ ! if ( ! (PS_NEWPAGE & p->engine.ps.flags)) { ! assert(0 == p->engine.ps.flags); ! assert('\0' == p->engine.ps.last); ! assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]); ! printf("%s", p->engine.ps.psmarg); ! p->engine.ps.pages++; ! printf("showpage\n"); ! } printf("%%%%Trailer\n"); printf("%%%%Pages: %zu\n", p->engine.ps.pages); *************** *** 543,549 **** } p->engine.ps.psmargcur = 0; ! p->engine.ps.psstate = PS_MARGINS; p->engine.ps.pscol = p->engine.ps.left; p->engine.ps.psrow = p->engine.ps.header; --- 599,605 ---- } p->engine.ps.psmargcur = 0; ! p->engine.ps.flags = PS_MARGINS; p->engine.ps.pscol = p->engine.ps.left; p->engine.ps.psrow = p->engine.ps.header; *************** *** 558,566 **** (*p->footf)(p, p->argf); (*p->endline)(p); ! p->engine.ps.psstate &= ~PS_MARGINS; ! assert(0 == p->engine.ps.psstate); assert(p->engine.ps.psmarg); assert('\0' != p->engine.ps.psmarg[0]); --- 614,622 ---- (*p->footf)(p, p->argf); (*p->endline)(p); ! p->engine.ps.flags &= ~PS_MARGINS; ! assert(0 == p->engine.ps.flags); assert(p->engine.ps.psmarg); assert('\0' != p->engine.ps.psmarg[0]); *************** *** 578,599 **** printf("%%%%Orientation: Portrait\n"); printf("%%%%Pages: (atend)\n"); printf("%%%%PageOrder: Ascend\n"); - printf("%%%%Orientation: Portrait\n"); printf("%%%%DocumentMedia: Default %zu %zu 0 () ()\n", ! p->engine.ps.width, ! p->engine.ps.height); printf("%%%%DocumentNeededResources: font"); for (i = 0; i < (int)TERMFONT__MAX; i++) printf(" %s", fonts[i].name); printf("\n%%%%EndComments\n"); - printf("%%%%Page: %zu %zu\n", - p->engine.ps.pages + 1, - p->engine.ps.pages + 1); - - ps_setfont(p, TERMFONT_NONE); p->engine.ps.pscol = p->engine.ps.left; p->engine.ps.psrow = p->engine.ps.top; } --- 634,651 ---- printf("%%%%Orientation: Portrait\n"); printf("%%%%Pages: (atend)\n"); printf("%%%%PageOrder: Ascend\n"); printf("%%%%DocumentMedia: Default %zu %zu 0 () ()\n", ! AFM2PNT(p, p->engine.ps.width), ! AFM2PNT(p, p->engine.ps.height)); printf("%%%%DocumentNeededResources: font"); for (i = 0; i < (int)TERMFONT__MAX; i++) printf(" %s", fonts[i].name); printf("\n%%%%EndComments\n"); p->engine.ps.pscol = p->engine.ps.left; p->engine.ps.psrow = p->engine.ps.top; + p->engine.ps.flags |= PS_NEWPAGE; + ps_setfont(p, TERMFONT_NONE); } *************** *** 601,619 **** ps_pletter(struct termp *p, int c) { int f; /* * If we're not in a PostScript "word" context, then open one * now at the current cursor. */ ! if ( ! (PS_INLINE & p->engine.ps.psstate)) { ps_printf(p, "%zu %zu moveto\n(", ! p->engine.ps.pscol, ! p->engine.ps.psrow); ! p->engine.ps.psstate |= PS_INLINE; } /* * We need to escape these characters as per the PostScript * specification. We would also escape non-graphable characters --- 653,688 ---- ps_pletter(struct termp *p, int c) { int f; + + /* + * If we haven't opened a page context, then output that we're + * in a new page and make sure the font is correctly set. + */ + + if (PS_NEWPAGE & p->engine.ps.flags) { + printf("%%%%Page: %zu %zu\n", + p->engine.ps.pages + 1, + p->engine.ps.pages + 1); + ps_printf(p, "/%s %zu selectfont\n", + fonts[(int)p->engine.ps.lastf].name, + p->engine.ps.scale); + p->engine.ps.flags &= ~PS_NEWPAGE; + } /* * If we're not in a PostScript "word" context, then open one * now at the current cursor. */ ! if ( ! (PS_INLINE & p->engine.ps.flags)) { ps_printf(p, "%zu %zu moveto\n(", ! AFM2PNT(p, p->engine.ps.pscol), ! AFM2PNT(p, p->engine.ps.psrow)); ! p->engine.ps.flags |= PS_INLINE; } + assert( ! (PS_NEWPAGE & p->engine.ps.flags)); + /* * We need to escape these characters as per the PostScript * specification. We would also escape non-graphable characters *************** *** 639,651 **** if (c <= 32 || (c - 32 > MAXCHAR)) { ps_putchar(p, ' '); ! p->engine.ps.pscol += (fonts[f].gly[0].wx / 100); return; } ! ps_putchar(p, c); c -= 32; ! p->engine.ps.pscol += (fonts[f].gly[c].wx / 100); } --- 708,720 ---- if (c <= 32 || (c - 32 > MAXCHAR)) { ps_putchar(p, ' '); ! p->engine.ps.pscol += fonts[f].gly[0].wx; return; } ! ps_putchar(p, (char)c); c -= 32; ! p->engine.ps.pscol += fonts[f].gly[c].wx; } *************** *** 659,669 **** * or anything). */ ! if ( ! (PS_INLINE & p->engine.ps.psstate)) return; ps_printf(p, ") show\n"); ! p->engine.ps.psstate &= ~PS_INLINE; } --- 728,738 ---- * or anything). */ ! if ( ! (PS_INLINE & p->engine.ps.flags)) return; ps_printf(p, ") show\n"); ! p->engine.ps.flags &= ~PS_INLINE; } *************** *** 688,694 **** p->engine.ps.last = '\0'; } ! if ( ! (PS_INLINE & p->engine.ps.psstate)) return; ps_pclose(p); --- 757,763 ---- p->engine.ps.last = '\0'; } ! if ( ! (PS_INLINE & p->engine.ps.flags)) return; ps_pclose(p); *************** *** 773,787 **** * lines, we'll do nasty stuff. */ ! if (PS_MARGINS & p->engine.ps.psstate) return; /* * Put us down a line. If we're at the page bottom, spit out a * showpage and restart our row. */ - p->engine.ps.pscol = p->engine.ps.left; if (p->engine.ps.psrow >= p->engine.ps.lineheight + p->engine.ps.bottom) { p->engine.ps.psrow -= p->engine.ps.lineheight; --- 842,864 ---- * lines, we'll do nasty stuff. */ ! if (PS_MARGINS & p->engine.ps.flags) return; + /* Left-justify. */ + + p->engine.ps.pscol = p->engine.ps.left; + + /* If we haven't printed anything, return. */ + + if (PS_NEWPAGE & p->engine.ps.flags) + return; + /* * Put us down a line. If we're at the page bottom, spit out a * showpage and restart our row. */ if (p->engine.ps.psrow >= p->engine.ps.lineheight + p->engine.ps.bottom) { p->engine.ps.psrow -= p->engine.ps.lineheight; *************** *** 790,801 **** assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]); printf("%s", p->engine.ps.psmarg); - printf("%%%%Page: %zu %zu\n", - p->engine.ps.pages + 1, - p->engine.ps.pages + 1); printf("showpage\n"); p->engine.ps.pages++; p->engine.ps.psrow = p->engine.ps.top; } --- 867,877 ---- assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]); printf("%s", p->engine.ps.psmarg); printf("showpage\n"); p->engine.ps.pages++; p->engine.ps.psrow = p->engine.ps.top; + assert( ! (PS_NEWPAGE & p->engine.ps.flags)); + p->engine.ps.flags |= PS_NEWPAGE; } *************** *** 804,811 **** { assert(f < TERMFONT__MAX); - ps_printf(p, "/%s 10 selectfont\n", fonts[(int)f].name); p->engine.ps.lastf = f; } --- 880,897 ---- { assert(f < TERMFONT__MAX); p->engine.ps.lastf = f; + + /* + * If we're still at the top of the page, let the font-setting + * be delayed until we actually have stuff to print. + */ + + if (PS_NEWPAGE & p->engine.ps.flags) + return; + + ps_printf(p, "/%s %zu selectfont\n", + fonts[(int)f].name, p->engine.ps.scale); } *************** *** 815,822 **** { if (c <= 32 || c - 32 >= MAXCHAR) ! return(fonts[(int)TERMFONT_NONE].gly[0].wx / 100); c -= 32; ! return(fonts[(int)TERMFONT_NONE].gly[(int)c].wx / 100); } --- 901,955 ---- { if (c <= 32 || c - 32 >= MAXCHAR) ! return(fonts[(int)TERMFONT_NONE].gly[0].wx); c -= 32; ! return(fonts[(int)TERMFONT_NONE].gly[(int)c].wx); } + + + static double + ps_hspan(const struct termp *p, const struct roffsu *su) + { + double r; + + /* + * All of these measurements are derived by converting from the + * native measurement to AFM units. + */ + + switch (su->unit) { + case (SCALE_CM): + r = PNT2AFM(p, su->scale * 28.34); + break; + case (SCALE_IN): + r = PNT2AFM(p, su->scale * 72); + break; + case (SCALE_PC): + r = PNT2AFM(p, su->scale * 12); + break; + case (SCALE_PT): + r = PNT2AFM(p, su->scale * 100); + break; + case (SCALE_EM): + r = su->scale * + fonts[(int)TERMFONT_NONE].gly[109 - 32].wx; + break; + case (SCALE_MM): + r = PNT2AFM(p, su->scale * 2.834); + break; + case (SCALE_EN): + r = su->scale * + fonts[(int)TERMFONT_NONE].gly[110 - 32].wx; + break; + case (SCALE_VS): + r = su->scale * p->engine.ps.lineheight; + break; + default: + r = su->scale; + break; + } + + return(r); + } +