-/* $Id: term_ps.c,v 1.25 2010/07/01 14:23:45 kristaps Exp $ */
+/* $Id: term_ps.c,v 1.34 2010/07/13 23:53:20 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
#include "out.h"
#include "main.h"
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 *pp;
char *v;
p->type = TERMTYPE_PS;
p->width = ps_width;
- p->engine.ps.scale = 11;
-
toks[0] = "paper";
toks[1] = NULL;
break;
}
- margin = PNT2AFM(p, 72);
- lineheight = PNT2AFM(p, 12);
-
/* Default to US letter (millimetres). */
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));
- assert(margin * 2 < pagex);
- assert(margin * 2 < pagey);
+ /* 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 - (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);
}
* into our growable margin buffer.
*/
- if ( ! (PS_MARGINS & p->engine.ps.psstate)) {
+ if ( ! (PS_MARGINS & p->engine.ps.flags)) {
vprintf(fmt, ap);
va_end(ap);
return;
/* See ps_printf(). */
- if ( ! (PS_MARGINS & p->engine.ps.psstate)) {
+ if ( ! (PS_MARGINS & p->engine.ps.flags)) {
putchar(c);
return;
}
* 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");
+ 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);
}
p->engine.ps.psmargcur = 0;
- p->engine.ps.psstate = PS_MARGINS;
+ p->engine.ps.flags = PS_MARGINS;
p->engine.ps.pscol = p->engine.ps.left;
p->engine.ps.psrow = p->engine.ps.header;
(*p->footf)(p, p->argf);
(*p->endline)(p);
- p->engine.ps.psstate &= ~PS_MARGINS;
+ p->engine.ps.flags &= ~PS_MARGINS;
- assert(0 == p->engine.ps.psstate);
+ assert(0 == p->engine.ps.flags);
assert(p->engine.ps.psmarg);
assert('\0' != p->engine.ps.psmarg[0]);
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;
+ p->engine.ps.flags |= PS_NEWPAGE;
+ ps_setfont(p, TERMFONT_NONE);
}
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.psstate)) {
+ 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.psstate |= PS_INLINE;
+ 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
* or anything).
*/
- if ( ! (PS_INLINE & p->engine.ps.psstate))
+ if ( ! (PS_INLINE & p->engine.ps.flags))
return;
ps_printf(p, ") show\n");
- p->engine.ps.psstate &= ~PS_INLINE;
+ p->engine.ps.flags &= ~PS_INLINE;
}
p->engine.ps.last = '\0';
}
- if ( ! (PS_INLINE & p->engine.ps.psstate))
+ if ( ! (PS_INLINE & p->engine.ps.flags))
return;
ps_pclose(p);
* lines, we'll do nasty stuff.
*/
- if (PS_MARGINS & p->engine.ps.psstate)
+ 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;
/*
* 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;
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);
p->engine.ps.psrow = p->engine.ps.top;
+ assert( ! (PS_NEWPAGE & p->engine.ps.flags));
+ p->engine.ps.flags |= PS_NEWPAGE;
}
{
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);
- p->engine.ps.lastf = f;
}