=================================================================== RCS file: /cvs/mandoc/term_ps.c,v retrieving revision 1.12 retrieving revision 1.15 diff -u -p -r1.12 -r1.15 --- mandoc/term_ps.c 2010/06/25 19:50:23 1.12 +++ mandoc/term_ps.c 2010/06/28 23:26:09 1.15 @@ -1,4 +1,4 @@ -/* $Id: term_ps.c,v 1.12 2010/06/25 19:50:23 kristaps Exp $ */ +/* $Id: term_ps.c,v 1.15 2010/06/28 23:26:09 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -25,12 +25,13 @@ #include #include #include +#include #include "out.h" #include "main.h" #include "term.h" -#define PS_CHAR_WIDTH 6 +/* TODO: all this will go away with different paper sizes. */ #define PS_CHAR_HEIGHT 12 #define PS_CHAR_TOPMARG (792 - 24) #define PS_CHAR_TOP (PS_CHAR_TOPMARG - 36) @@ -38,6 +39,317 @@ #define PS_CHAR_BOTMARG 24 #define PS_CHAR_BOT (PS_CHAR_BOTMARG + 36) +struct glyph { + int wx; /* WX in AFM */ +}; + +struct font { + const char *name; /* FontName in AFM */ +#define MAXCHAR 95 /* total characters we can handle */ + struct glyph gly[MAXCHAR]; /* glyph metrics */ +}; + +/* + * We define, for the time being, three fonts: bold, oblique/italic, and + * normal (roman). The following table hard-codes the font metrics for + * ASCII, i.e., 32--127. + */ + +static const struct font fonts[3] = { + { "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 }, + } }, +}; + +/* These work the buffer used by the header and footer. */ #define PS_BUFSLOP 128 #define PS_GROWBUF(p, sz) \ do if ((p)->engine.ps.psmargcur + (sz) > \ @@ -62,7 +374,7 @@ 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 *, char); +static void ps_pletter(struct termp *, int); static void ps_printf(struct termp *, const char *, ...); static void ps_putchar(struct termp *, char); static void ps_setfont(struct termp *, enum termfont); @@ -76,8 +388,7 @@ ps_alloc(void) if (NULL == (p = term_alloc(TERMENC_ASCII))) return(NULL); - p->defrmargin = 78; - p->tabwidth = 5; + p->defrmargin = 612 - (PS_CHAR_LEFT * 2); p->type = TERMTYPE_PS; p->letter = ps_letter; @@ -183,6 +494,7 @@ ps_end(struct termp *p) static void ps_begin(struct termp *p) { + time_t t; /* * Print margins into margin buffer. Nothing gets output to the @@ -221,7 +533,15 @@ ps_begin(struct termp *p) * stuff gets printed to the screen, so make sure we're sane. */ - printf("%s\n", "%!PS"); + t = time(NULL); + + printf("%%!PS\n"); + printf("%%%%Creator: mandoc-%s\n", VERSION); + printf("%%%%CreationDate: %s", ctime(&t)); + printf("%%%%PageOrder: Ascend\n"); + printf("%%%%Orientation: Portrait\n"); + printf("%%%%EndComments\n"); + ps_setfont(p, TERMFONT_NONE); p->engine.ps.pscol = PS_CHAR_LEFT; p->engine.ps.psrow = PS_CHAR_TOP; @@ -229,8 +549,9 @@ ps_begin(struct termp *p) static void -ps_pletter(struct termp *p, char c) +ps_pletter(struct termp *p, int c) { + int f; /* * If we're not in a PostScript "word" context, then open one @@ -265,8 +586,17 @@ ps_pletter(struct termp *p, char c) /* Write the character and adjust where we are on the page. */ + f = (int)p->engine.ps.lastf; + + if (c <= 32 || (c - 32 > MAXCHAR)) { + ps_putchar(p, ' '); + p->engine.ps.pscol += (fonts[f].gly[0].wx / 100); + return; + } + ps_putchar(p, c); - p->engine.ps.pscol += PS_CHAR_WIDTH; + c -= 32; + p->engine.ps.pscol += (fonts[f].gly[c].wx / 100); } @@ -376,7 +706,7 @@ ps_advance(struct termp *p, size_t len) */ ps_fclose(p); - p->engine.ps.pscol += len ? len * PS_CHAR_WIDTH : 0; + p->engine.ps.pscol += len; } @@ -419,14 +749,7 @@ static void ps_setfont(struct termp *p, enum termfont f) { - if (TERMFONT_BOLD == f) - ps_printf(p, "/Courier-Bold\n"); - else if (TERMFONT_UNDER == f) - ps_printf(p, "/Courier-Oblique\n"); - else - ps_printf(p, "/Courier\n"); - - ps_printf(p, "10 selectfont\n"); + ps_printf(p, "/%s 10 selectfont\n", fonts[(int)f].name); p->engine.ps.lastf = f; } @@ -436,5 +759,9 @@ static size_t ps_width(const struct termp *p, char c) { - return(1); + 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); }