shithub: neatpost

Download patch

ref: f33908e77d5b637d3f33f244ab7f1fdc7f63f6bb
parent: 002e41a3c07346a8c1ebd805d65f1437c98443c6
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Jul 6 20:17:00 EDT 2013

clr: color support with m command

--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 all: post
 %.o: %.c post.h
 	$(CC) -c $(CFLAGS) $<
-post: post.o out.o ps.o font.o dev.o
+post: post.o out.o ps.o font.o dev.o clr.o
 	$(CC) -o $@ $^ $(LDFLAGS)
 clean:
 	rm -f *.o post
--- /dev/null
+++ b/clr.c
@@ -1,0 +1,56 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "post.h"
+
+/* returns a static buffer */
+char *clr_str(int c)
+{
+	static char clr_buf[32];
+	if (!c)
+		return "0";
+	sprintf(clr_buf, "#%02x%02x%02x", CLR_R(c), CLR_G(c), CLR_B(c));
+	return clr_buf;
+}
+
+static struct color {
+	char *name;
+	int value;
+} colors[] = {
+	{"black", CLR_RGB(0, 0, 0)},
+	{"red", CLR_RGB(0xff, 0, 0)},
+	{"green", CLR_RGB(0, 0xff, 0)},
+	{"yellow", CLR_RGB(0xff, 0xff, 0)},
+	{"blue", CLR_RGB(0, 0, 0xff)},
+	{"magenta", CLR_RGB(0xff, 0, 0xff)},
+	{"cyan", CLR_RGB(0, 0xff, 0xff)},
+	{"white", CLR_RGB(0xff, 0xff, 0xff)},
+};
+
+/* read color component */
+static int clrcomp(char *s, int len)
+{
+	static char *digs = "0123456789abcdef";
+	int n = 0;
+	int i;
+	for (i = 0; i < len; i++)
+		if (strchr(digs, tolower(s[i])))
+			n = n * 16 + (strchr(digs, tolower(s[i])) - digs);
+	return len == 1 ? n << 4 : n;
+}
+
+int clr_get(char *s)
+{
+	int i;
+	if (s[0] == '#' && strlen(s) == 7)
+		return CLR_RGB(clrcomp(s + 1, 2), clrcomp(s + 3, 2), clrcomp(s + 5, 2));
+	if (s[0] == '#' && strlen(s) == 4)
+		return CLR_RGB(clrcomp(s + 1, 1), clrcomp(s + 2, 1), clrcomp(s + 3, 1));
+	if (isdigit(s[0]) && atoi(s) >= 0 && atoi(s) < LEN(colors))
+		return colors[atoi(s)].value;
+	for (i = 0; i < LEN(colors); i++)
+		if (!strcmp(colors[i].name, s))
+			return colors[i].value;
+	return 0;
+}
--- a/out.c
+++ b/out.c
@@ -5,9 +5,9 @@
 #include <string.h>
 #include "post.h"
 
-static int o_f, o_s;		/* font and size */
+static int o_f, o_s, o_m;	/* font and size */
 static int o_h, o_v;		/* current user position */
-static int p_f, p_s;		/* output postscript font */
+static int p_f, p_s, p_m;	/* output postscript font */
 static int o_qtype;		/* queued character type */
 static int o_qv, o_qh, o_qend;	/* queued character position */
 char o_fonts[FNLEN * NFONTS] = " ";
@@ -41,6 +41,7 @@
 	o_h = 0;
 	p_s = 0;
 	p_f = 0;
+	p_m = 0;
 }
 
 static void o_queue(struct glyph *g)
@@ -109,6 +110,10 @@
 {
 	char fnname[FNLEN];
 	struct font *fn;
+	if (o_m != p_m) {
+		out("%d %d %d rgb\n", CLR_R(o_m), CLR_G(o_m), CLR_B(o_m));
+		p_m = o_m;
+	}
 	if (fid != p_f || o_s != p_s) {
 		fn = dev_font(fid);
 		out("%d /%s f\n", o_s, fn->fontname);
@@ -164,6 +169,11 @@
 void outsize(int s)
 {
 	o_s = s;
+}
+
+void outcolor(int c)
+{
+	o_m = c;
 }
 
 static int draw_path;	/* number of path segments */
--- a/post.c
+++ b/post.c
@@ -259,6 +259,10 @@
 		nextutf8(cs);
 		outc(cs);
 		break;
+	case 'm':
+		nextword(cs);
+		outcolor(clr_get(cs));
+		break;
 	case 'N':
 		nextnum();
 		break;
--- a/post.h
+++ b/post.h
@@ -71,6 +71,7 @@
 void outrel(int h, int v);
 void outfont(int f);
 void outsize(int s);
+void outcolor(int c);
 void outpage(void);
 extern char o_fonts[];
 
@@ -87,3 +88,12 @@
 void ps_trailer(int pages, char *fonts);
 void ps_pagebeg(int n);
 void ps_pageend(int n);
+
+/* colors */
+#define CLR_R(c)		(((c) >> 16) & 0xff)
+#define CLR_G(c)		(((c) >> 8) & 0xff)
+#define CLR_B(c)		((c) & 0xff)
+#define CLR_RGB(r, g, b)	(((r) << 16) | ((g) << 8) | (b))
+
+char *clr_str(int c);
+int clr_get(char *s);
--- a/ps.c
+++ b/ps.c
@@ -50,6 +50,7 @@
 	"/w {neg moveto show} bind def\n"
 	"/m {neg moveto} bind def\n"
 	"/g {neg moveto {glyphshow} forall} bind def\n"
+	"/rgb {255 div 3 1 roll 255 div 3 1 roll 255 div 3 1 roll setrgbcolor} bind def\n"
 	"/done {/lastpage where {pop lastpage} if} def\n"
 	"\n"
 	"/f {\n"