=================================================================== RCS file: /cvs/mandoc/term_ps.c,v retrieving revision 1.24 retrieving revision 1.28 diff -u -p -r1.24 -r1.28 --- mandoc/term_ps.c 2010/06/30 20:57:41 1.24 +++ mandoc/term_ps.c 2010/07/04 19:24:00 1.28 @@ -1,4 +1,4 @@ -/* $Id: term_ps.c,v 1.24 2010/06/30 20:57:41 kristaps Exp $ */ +/* $Id: term_ps.c,v 1.28 2010/07/04 19:24:00 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -27,21 +27,27 @@ #include #include #include +#include #include "out.h" #include "main.h" #include "term.h" +#define MINMARGIN_MM 20 /* Minimum 2cm margins. */ +#define MINMARGIN_PNT 56.68 +#define DEFPAGEX_MM 216 /* Default page size is US-letter. */ +#define DEFPAGEY_MM 279 + /* Convert PostScript point "x" to an AFM unit. */ -#define PNT2AFM(p, x) \ +#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) \ +#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 { @@ -387,9 +393,9 @@ void * ps_alloc(char *outopts) { struct termp *p; - size_t pagex, pagey, margin, lineheight; + size_t pagex, pagey, marginx, marginy, lineheight; const char *toks[2]; - const char *paper; + const char *pp; char *v; if (NULL == (p = term_alloc(TERMENC_ASCII))) @@ -404,46 +410,89 @@ ps_alloc(char *outopts) p->type = TERMTYPE_PS; p->width = ps_width; - p->engine.ps.scale = 10; - 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; } - margin = PNT2AFM(p, 72); - lineheight = PNT2AFM(p, 12); + /* Default to US letter (millimetres). */ - if (0 == strcasecmp(paper, "a4")) { - pagex = PNT2AFM(p, 595); - pagey = PNT2AFM(p, 842); - } else { - pagex = PNT2AFM(p, 612); - pagey = PNT2AFM(p, 792); + pagex = DEFPAGEX_MM; + pagey = DEFPAGEY_MM; + + /* + * 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"; + + /* Enforce minimum page size >= (2 times) min-margin. */ + + if ((2 * MINMARGIN_MM) >= pagex) { + fprintf(stderr, "%s: Insufficient page width\n", pp); + pagex = DEFPAGEX_MM; + } else if ((2 * MINMARGIN_MM >= pagey)) { + fprintf(stderr, "%s: Insufficient page length\n", pp); + pagey = DEFPAGEY_MM; } - assert(margin * 2 < pagex); - assert(margin * 2 < pagey); + /* + * 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 = (size_t)((double)pagex / 9.0); + marginy = (size_t)((double)pagey / 9.0); + + lineheight = PNT2AFM(p, 16); + 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.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 - (margin * 2); + p->defrmargin = pagex - (marginx * 2); return(p); } @@ -658,7 +707,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; }