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"