shithub: neatpost

Download patch

ref: f5144a0fb1334c32890f4077ea1ea937701b8d29
parent: 976bd33db97521c48309b9e4ed1a6ff466956c20
author: Ali Gholami Rudi <ali@rudi.ir>
date: Wed Jun 12 15:37:31 EDT 2013

post: drawing commands

--- a/dev.c
+++ b/dev.c
@@ -130,11 +130,9 @@
 	return fn < fn_n ? fn_font[fn] : NULL;
 }
 
-int dev_fontid(struct font *fn, int cur)
+int dev_fontid(struct font *fn)
 {
 	int i;
-	if (fn_font[cur] == fn)
-		return cur;
 	for (i = 0; i < fn_n; i++)
 		if (fn_font[i] == fn)
 			return i;
--- a/out.c
+++ b/out.c
@@ -12,16 +12,16 @@
 static int o_qv, o_qh, o_qend;	/* queued character position */
 char o_fonts[FNLEN * NFONTS] = " ";
 
-static void outf(char *s, va_list ap)
+static void outvf(char *s, va_list ap)
 {
 	vfprintf(stdout, s, ap);
 }
 
-void outvf(char *s, ...)
+void outf(char *s, ...)
 {
 	va_list ap;
 	va_start(ap, s);
-	outf(s, ap);
+	outvf(s, ap);
 	va_end(ap);
 }
 
@@ -28,9 +28,9 @@
 static void o_flush(void)
 {
 	if (o_qtype == 1)
-		outvf(") %d %d w\n", o_qh, o_qv);
+		outf(") %d %d w\n", o_qh, o_qv);
 	if (o_qtype == 2)
-		outvf("] %d %d g\n", o_qh, o_qv);
+		outf("] %d %d g\n", o_qh, o_qv);
 	o_qtype = 0;
 }
 
@@ -52,16 +52,15 @@
 		o_qh = o_h;
 		o_qv = o_v;
 		o_qtype = type;
-		outvf(type == 1 ? "(" : "[");
+		outf(type == 1 ? "(" : "[");
 	}
 	if (o_qtype == 1) {
 		if (num >= ' ' && num <= '~')
-			outvf("%s%c", strchr("()\\", num) ? "\\" : "", num);
+			outf("%s%c", strchr("()\\", num) ? "\\" : "", num);
 		else
-			outvf("\\%d%d%d",
-				(num >> 6) & 7, (num >> 3) & 7, num & 7);
+			outf("\\%d%d%d", (num >> 6) & 7, (num >> 3) & 7, num & 7);
 	} else {
-		outvf("/%s", g->id);
+		outf("/%s", g->id);
 	}
 	o_qend = o_h + charwid(g->wid, o_s);
 }
@@ -72,7 +71,7 @@
 	va_list ap;
 	o_flush();
 	va_start(ap, s);
-	outf(s, ap);
+	outvf(s, ap);
 	va_end(ap);
 }
 
@@ -106,12 +105,25 @@
 	}
 }
 
+static void out_fontup(int fid)
+{
+	char fnname[FNLEN];
+	struct font *fn;
+	if (fid != p_f || o_s != p_s) {
+		fn = dev_font(fid);
+		out("%d /%s f\n", o_s, fn->psname);
+		p_f = fid;
+		p_s = o_s;
+		sprintf(fnname, " %s ", fn->psname);
+		if (!strstr(o_fonts, fnname))
+			sprintf(strchr(o_fonts, '\0'), "%s ", fn->psname);
+	}
+}
+
 void outc(char *c)
 {
 	struct glyph *g;
 	struct font *fn;
-	char fnname[FNLEN];
-	int fontid;
 	int dh, dv;
 	g = dev_glyph(c, o_f);
 	fn = g ? g->font : dev_font(o_f);
@@ -119,15 +131,7 @@
 		outrel(*c == ' ' && fn ? charwid(fn->spacewid, o_s) : 1, 0);
 		return;
 	}
-	fontid = dev_fontid(fn, o_f);
-	if (fontid != p_f || o_s != p_s) {
-		out("%d /%s f\n", o_s, fn->psname);
-		p_f = fontid;
-		p_s = o_s;
-		sprintf(fnname, " %s ", fn->psname);
-		if (!strstr(o_fonts, fnname))
-			sprintf(strchr(o_fonts, '\0'), "%s ", fn->psname);
-	}
+	out_fontup(dev_fontid(fn));
 	fixpos(g, &dh, &dv);
 	o_h += dh;
 	o_v += dv;
@@ -160,4 +164,47 @@
 void outsize(int s)
 {
 	o_s = s;
+}
+
+void drawbeg(void)
+{
+	o_flush();
+	out_fontup(o_f);
+	outf("newpath %d %d m ", o_h, o_v);
+}
+
+void drawend(void)
+{
+	outf("stroke\n");
+}
+
+void drawl(int h, int v)
+{
+	outrel(h, v);
+	outf("%d %d drawl ", o_h, o_v);
+}
+
+void drawc(int c)
+{
+	outrel(c, 0);
+	outf("%d %d drawe ", c, c);
+}
+
+void drawe(int h, int v)
+{
+	outrel(h, 0);
+	outf("%d %d drawe ", h, v);
+}
+
+void drawa(int h1, int v1, int h2, int v2)
+{
+	outf("%d %d %d %d drawa ", h1, v1, h2, v2);
+	outrel(h1 + h2, v1 + v2);
+}
+
+void draws(int h1, int v1, int h2, int v2)
+{
+	outf("%d %d %d %d %d %d draws ", o_h, o_v, o_h + h1, o_v + v1,
+		o_h + h1 + h2, o_v + v1 + v2);
+	outrel(h1, v1);
 }
--- a/post.c
+++ b/post.c
@@ -88,7 +88,7 @@
 	int c;
 	do {
 		c = next();
-	} while (c != ' ');
+	} while (c == ' ');
 	if (c != '\n')
 		back(c);
 	return c == '\n';
@@ -117,24 +117,37 @@
 	*s = '\0';
 }
 
-static void draw(void)
+static void postspline(int h1, int v1)
 {
+	int h2, v2;
+	while (!iseol()) {
+		h2 = nextnum();
+		v2 = nextnum();
+		draws(h1, v1, h2, v2);
+		h1 = h2;
+		v1 = v2;
+	}
+	draws(h1, v1, 0, 0);
+}
+
+static void postdraw(void)
+{
 	int h1, h2, v1, v2;
 	int c = next();
+	drawbeg();
 	switch (c) {
 	case 'l':
 		h1 = nextnum();
 		v1 = nextnum();
-		outrel(h1, v1);
+		drawl(h1, v1);
 		break;
 	case 'c':
-		h1 = nextnum();
-		outrel(h1, 0);
+		drawc(nextnum());
 		break;
 	case 'e':
 		h1 = nextnum();
 		v1 = nextnum();
-		outrel(h1, 0);
+		drawe(h1, v1);
 		break;
 	case 'a':
 		h1 = nextnum();
@@ -141,19 +154,18 @@
 		v1 = nextnum();
 		h2 = nextnum();
 		v2 = nextnum();
-		outrel(h1 + h2, v1 + v2);
+		drawa(h1, v1, h2, v2);
 		break;
-	default:
+	case '~':
 		h1 = nextnum();
 		v1 = nextnum();
-		outrel(h1, v1);
-		while (!iseol()) {
-			h2 = nextnum();
-			v2 = nextnum();
-			outrel(h2, v2);
-		}
+		if (iseol())
+			drawl(h1, v1);
+		else
+			postspline(h1, v1);
 		break;
 	}
+	drawend();
 	nexteol();
 }
 
@@ -239,7 +251,7 @@
 		nextnum();
 		break;
 	case 'D':
-		draw();
+		postdraw();
 		break;
 	case 'x':
 		postx();
--- a/post.h
+++ b/post.h
@@ -42,7 +42,7 @@
 void dev_close(void);
 int dev_mnt(int pos, char *id, char *name);
 struct font *dev_font(int fn);
-int dev_fontid(struct font *fn, int cur);
+int dev_fontid(struct font *fn);
 int charwid(int wid, int sz);
 struct glyph *dev_glyph(char *c, int fn);
 struct glyph *dev_glyph_byid(char *id, int fn);
@@ -63,6 +63,14 @@
 void outsize(int s);
 void outpage(void);
 extern char o_fonts[];
+
+void drawbeg(void);
+void drawend(void);
+void drawl(int h, int v);
+void drawc(int c);
+void drawe(int h, int v);
+void drawa(int h1, int v1, int h2, int v2);
+void draws(int h1, int v1, int h2, int v2);
 
 /* postscript functions */
 void ps_header(void);
--- a/ps.c
+++ b/ps.c
@@ -32,14 +32,11 @@
 	"\n"
 	"/setup {\n"
 	"	counttomark 2 idiv {def} repeat pop\n"
-	"\n"
 	"	/scaling 72 resolution div def\n"
 	"	linewidth setlinewidth\n"
 	"	1 setlinecap\n"
-	"\n"
 	"	0 pagesize 1 get translate\n"
 	"	scaling scaling scale\n"
-	"\n"
 	"	0 0 moveto\n"
 	"} def\n"
 	"\n"
@@ -51,7 +48,7 @@
 	"} def\n"
 	"\n"
 	"/w {neg moveto show} bind def\n"
-	"/m {neg dup /y exch def moveto} bind def\n"
+	"/m {neg moveto} bind def\n"
 	"/g {neg moveto {glyphshow} forall} bind def\n"
 	"/done {/lastpage where {pop lastpage} if} def\n"
 	"\n"
@@ -59,6 +56,42 @@
 	"	dup /font exch def findfont exch\n"
 	"	dup /ptsize exch def scaling div dup /size exch def scalefont setfont\n"
 	"	linewidth ptsize mul scaling 10 mul div setlinewidth\n"
+	"} bind def\n"
+	"\n"
+	"/savedmatrix matrix def\n"
+	"/drawl {\n"
+	"	neg lineto\n"
+	"} bind def\n"
+	"/drawe {\n"
+	"	savedmatrix currentmatrix pop scale\n"
+	"	.5 0 rmoveto currentpoint .5 0 rmoveto .5 0 360 arc\n"
+	"	savedmatrix setmatrix\n"
+	"} bind def\n"
+	"/drawa {\n"
+	"	/dy2 exch def\n"
+	"	/dx2 exch def\n"
+	"	/dy1 exch def\n"
+	"	/dx1 exch def\n"
+	"	currentpoint dy1 neg add exch dx1 add exch\n"
+	"	dx1 dx1 mul dy1 dy1 mul add sqrt\n"
+	"	dy1 dx1 neg atan\n"
+	"	dy2 neg dx2 atan\n"
+	"	arc\n"
+	"} bind def\n"
+	"/draws {\n"
+	"	/y2 exch def\n"
+	"	/x2 exch def\n"
+	"	/y1 exch def\n"
+	"	/x1 exch def\n"
+	"	/y0 exch def\n"
+	"	/x0 exch def\n"
+	"	x0 5 x1 mul add 6 div\n"
+	"	y0 5 y1 mul add -6 div\n"
+	"	x2 5 x1 mul add 6 div\n"
+	"	y2 5 y1 mul add -6 div\n"
+	"	x1 x2 add 2 div\n"
+	"	y1 y2 add -2 div\n"
+	"	curveto\n"
 	"} bind def\n";
 
 void ps_header(void)