=================================================================== RCS file: /cvs/mandoc/term_ps.c,v retrieving revision 1.20 retrieving revision 1.26 diff -u -p -r1.20 -r1.26 --- mandoc/term_ps.c 2010/06/30 12:30:36 1.20 +++ mandoc/term_ps.c 2010/07/02 10:53:28 1.26 @@ -1,4 +1,4 @@ -/* $Id: term_ps.c,v 1.20 2010/06/30 12:30:36 kristaps Exp $ */ +/* $Id: term_ps.c,v 1.26 2010/07/02 10:53:28 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -27,13 +27,22 @@ #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 { - int wx; /* WX in AFM */ + size_t wx; /* WX in AFM */ }; struct font { @@ -49,296 +58,296 @@ struct font { */ 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 }, + { "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}, } }, - { "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 }, + { "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 }, } }, - { "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 }, + { "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 }, } }, }; @@ -381,7 +390,7 @@ ps_alloc(char *outopts) struct termp *p; size_t pagex, pagey, margin, lineheight; const char *toks[2]; - const char *paper; + const char *pp; char *v; if (NULL == (p = term_alloc(TERMENC_ASCII))) @@ -395,32 +404,60 @@ ps_alloc(char *outopts) p->letter = ps_letter; p->type = TERMTYPE_PS; p->width = ps_width; + + p->engine.ps.scale = 11; toks[0] = "paper"; toks[1] = NULL; - paper = "letter"; + pp = NULL; while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): - paper = v; + pp = v; break; default: break; } - if (0 == strcasecmp(paper, "a4")) { - pagex = 595 * 100; - pagey = 842 * 100; - } else { - pagex = 612 * 100; - pagey = 792 * 100; + margin = PNT2AFM(p, 72); + lineheight = PNT2AFM(p, 12); + + /* 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); } - margin = 72 * 100; - lineheight = 12 * 100; + /* Remember millimetres -> AFM units. */ + pagex = PNT2AFM(p, ((double)pagex * 2.834)); + pagey = PNT2AFM(p, ((double)pagey * 2.834)); + assert(margin * 2 < pagex); assert(margin * 2 < pagey); @@ -584,10 +621,9 @@ ps_begin(struct termp *p) 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); + 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); @@ -615,8 +651,8 @@ ps_pletter(struct termp *p, int c) if ( ! (PS_INLINE & p->engine.ps.psstate)) { ps_printf(p, "%zu %zu moveto\n(", - (size_t)(p->engine.ps.pscol / 100), - (size_t)(p->engine.ps.psrow / 100)); + AFM2PNT(p, p->engine.ps.pscol), + AFM2PNT(p, p->engine.ps.psrow)); p->engine.ps.psstate |= PS_INLINE; } @@ -649,7 +685,7 @@ ps_pletter(struct termp *p, int c) return; } - ps_putchar(p, c); + ps_putchar(p, (char)c); c -= 32; p->engine.ps.pscol += fonts[f].gly[c].wx; } @@ -796,11 +832,11 @@ ps_endline(struct termp *p) assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]); printf("%s", p->engine.ps.psmarg); + printf("showpage\n"); + p->engine.ps.pages++; 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; } @@ -810,7 +846,8 @@ ps_setfont(struct termp *p, enum termfont f) { assert(f < TERMFONT__MAX); - ps_printf(p, "/%s 10 selectfont\n", fonts[(int)f].name); + ps_printf(p, "/%s %zu selectfont\n", + fonts[(int)f].name, p->engine.ps.scale); p->engine.ps.lastf = f; } @@ -835,29 +872,28 @@ ps_hspan(const struct termp *p, const struct roffsu *s /* * All of these measurements are derived by converting from the - * native measurement to AFM units, which are (scalesize/1000). - * Since scalesize is 10 for us, we can just skip to (x/100). + * native measurement to AFM units. */ switch (su->unit) { case (SCALE_CM): - r = su->scale * 28.34 * 100; + r = PNT2AFM(p, su->scale * 28.34); break; case (SCALE_IN): - r = su->scale * 72 * 100; + r = PNT2AFM(p, su->scale * 72); break; case (SCALE_PC): - r = su->scale * 12 * 100; + r = PNT2AFM(p, su->scale * 12); break; case (SCALE_PT): - r = su->scale * 100; + 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 = su->scale * 2.834 * 100; + r = PNT2AFM(p, su->scale * 2.834); break; case (SCALE_EN): r = su->scale *