From f33908e77d5b637d3f33f244ab7f1fdc7f63f6bb Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Sun, 7 Jul 2013 00:17:00 +0430 Subject: [PATCH] clr: color support with m command --- Makefile | 2 +- clr.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ out.c | 14 ++++++++++++-- post.c | 4 ++++ post.h | 10 ++++++++++ ps.c | 1 + 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 clr.c diff --git a/Makefile b/Makefile index 493f4af..2521254 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ LDFLAGS = 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 diff --git a/clr.c b/clr.c new file mode 100644 index 0000000..eb82cb8 --- /dev/null +++ b/clr.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#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; +} diff --git a/out.c b/out.c index db94fe2..7a372b3 100644 --- a/out.c +++ b/out.c @@ -5,9 +5,9 @@ #include #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 @@ void outpage(void) o_h = 0; p_s = 0; p_f = 0; + p_m = 0; } static void o_queue(struct glyph *g) @@ -109,6 +110,10 @@ static void out_fontup(int fid) { 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); @@ -166,6 +171,11 @@ void outsize(int s) o_s = s; } +void outcolor(int c) +{ + o_m = c; +} + static int draw_path; /* number of path segments */ static int draw_point; /* point was set for postscript newpath */ diff --git a/post.c b/post.c index 43531bb..f2b9a5e 100644 --- a/post.c +++ b/post.c @@ -259,6 +259,10 @@ static void postcmd(int c) nextutf8(cs); outc(cs); break; + case 'm': + nextword(cs); + outcolor(clr_get(cs)); + break; case 'N': nextnum(); break; diff --git a/post.h b/post.h index e35797d..7dda12a 100644 --- a/post.h +++ b/post.h @@ -71,6 +71,7 @@ void outv(int v); 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_header(void); 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); diff --git a/ps.c b/ps.c index 3539b79..6c14419 100644 --- a/ps.c +++ b/ps.c @@ -50,6 +50,7 @@ static char *prolog = "/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" -- 2.11.4.GIT