=================================================================== RCS file: /cvs/mandoc/term_ps.c,v retrieving revision 1.16 retrieving revision 1.19 diff -u -p -r1.16 -r1.19 --- mandoc/term_ps.c 2010/06/29 14:18:05 1.16 +++ mandoc/term_ps.c 2010/06/30 12:27:55 1.19 @@ -1,4 +1,4 @@ -/* $Id: term_ps.c,v 1.16 2010/06/29 14:18:05 kristaps Exp $ */ +/* $Id: term_ps.c,v 1.19 2010/06/30 12:27:55 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -358,13 +359,15 @@ static const struct font fonts[TERMFONT__MAX] = { } while (/* CONSTCOND */ 0) -static void ps_letter(struct termp *, char); +static size_t 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_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_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 *, ...); @@ -373,26 +376,51 @@ static void ps_setfont(struct termp *, enum termfon void * -ps_alloc(void) +ps_alloc(char *outopts) { struct termp *p; - size_t pagex, pagey, margin; + size_t pagex, pagey, margin, lineheight; + const char *toks[2]; + const char *paper; + char *v; if (NULL == (p = term_alloc(TERMENC_ASCII))) return(NULL); - pagex = 612; - pagey = 792; - margin = 72; - - p->type = TERMTYPE_PS; - p->letter = ps_letter; + p->advance = ps_advance; p->begin = ps_begin; p->end = ps_end; - p->advance = ps_advance; 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; + + paper = "letter"; + + while (outopts && *outopts) + switch (getsubopt(&outopts, UNCONST(toks), &v)) { + case (0): + paper = v; + break; + default: + break; + } + + if (0 == strcasecmp(paper, "a4")) { + pagex = 595 * 100; + pagey = 842 * 100; + } else { + pagex = 612 * 100; + pagey = 792 * 100; + } + + margin = 72 * 100; + lineheight = 12 * 100; + assert(margin * 2 < pagex); assert(margin * 2 < pagey); @@ -403,7 +431,7 @@ ps_alloc(void) p->engine.ps.footer = (margin / 2); p->engine.ps.bottom = margin; p->engine.ps.left = margin; - p->engine.ps.lineheight = 12; + p->engine.ps.lineheight = lineheight; p->defrmargin = pagex - (margin * 2); return(p); @@ -587,8 +615,8 @@ ps_pletter(struct termp *p, int c) if ( ! (PS_INLINE & p->engine.ps.psstate)) { ps_printf(p, "%zu %zu moveto\n(", - p->engine.ps.pscol, - p->engine.ps.psrow); + (size_t)(p->engine.ps.pscol / 100), + (size_t)(p->engine.ps.psrow / 100)); p->engine.ps.psstate |= PS_INLINE; } @@ -617,13 +645,13 @@ ps_pletter(struct termp *p, int c) if (c <= 32 || (c - 32 > MAXCHAR)) { ps_putchar(p, ' '); - p->engine.ps.pscol += (fonts[f].gly[0].wx / 100); + p->engine.ps.pscol += fonts[f].gly[0].wx; return; } ps_putchar(p, c); c -= 32; - p->engine.ps.pscol += (fonts[f].gly[c].wx / 100); + p->engine.ps.pscol += fonts[f].gly[c].wx; } @@ -793,8 +821,62 @@ ps_width(const struct termp *p, char c) { if (c <= 32 || c - 32 >= MAXCHAR) - return(fonts[(int)TERMFONT_NONE].gly[0].wx / 100); + return(fonts[(int)TERMFONT_NONE].gly[0].wx); c -= 32; - return(fonts[(int)TERMFONT_NONE].gly[(int)c].wx / 100); + return(fonts[(int)TERMFONT_NONE].gly[(int)c].wx); } + + +static size_t +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, which are (scalesize/1000). + * Since scalesize is 10 for us, we can just skip to (x/100). + */ + + switch (su->unit) { + case (SCALE_CM): + r = su->scale * 28.34 * 100; + break; + case (SCALE_IN): + r = su->scale * 72 * 100; + break; + case (SCALE_PC): + r = su->scale * 12 * 100; + break; + case (SCALE_PT): + r = 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; + 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; + } + + /* Explicitly disallow negative values. */ + + if (r < 0.0) + r = 0.0; + + return((size_t)/* LINTED */ + r); +} +