#include #include #include #include "plot.h" #include "istack.h" #include "dirimpl.h" #include "dir-clear.h" typedef struct priv PRIV; struct priv { int n; int err; int nosize; unsigned int x; unsigned int y; unsigned int bg; } ; DIRRV dir_clear(void **privp, DIROP op, ...) { va_list ap; PRIV *p; char *s; char c; unsigned int v; va_start(ap,op); switch (op) { default: abort(); break; case DIROP_INIT: p = malloc(sizeof(PRIV)); p->n = 0; p->err = 0; p->nosize = 0; *privp = p; return(DIRRV_MORE); break; case DIROP_ARG: p = *privp; s = va_arg(ap,char *); if (s == 0) { switch (p->n++) { default: abort(); break; case 0: istack_err("missing size"); if (0) { case 1: istack_err("missing Y size"); } if (0) { case 4: istack_err("missing B value"); } free(p); return(DIRRV_NOMORE); break; case 2: p->bg = 0; break; case 3: break; } if (! p->err) { if (p->nosize) { plot_justclear(p->bg); } else { plot_clear(p->x,p->y,p->bg); } } free(p); return(DIRRV_NOMORE); } if ((p->n == 0) && !strcmp(s,"same")) { p->nosize = 1; p->n = 2; return(DIRRV_MORE); } if (!p->err && (sscanf(s,"%u%c",&v,&c) != 1)) { p->err = 1; switch (p->n) { case 0: istack_err("invalid X size"); break; case 1: istack_err("invalid Y size"); break; case 2: istack_err("invalid R value"); break; case 3: istack_err("invalid G value"); break; case 4: istack_err("invalid B value"); break; default: abort(); break; } } if (p->err) { p->n ++; if (p->n < 5) return(DIRRV_MORE); free(p); return(DIRRV_NOMORE); } switch (p->n++) { case 0: p->x = v; break; case 1: p->y = v; break; case 2: if (v > 255) { istack_err("invalid R value"); p->err = 1; return(DIRRV_MORE); } p->bg = v * 0x010101; break; case 3: if (v > 255) { istack_err("invalid G value"); p->err = 1; return(DIRRV_MORE); } p->bg = (p->bg & 255) | (v << 8); break; case 4: if (v > 255) { istack_err("invalid B value"); free(p); return(DIRRV_NOMORE); } p->bg |= v << 16; break; } if (p->n > 4) { if (p->nosize) plot_justclear(p->bg); else plot_clear(p->x,p->y,p->bg); free(p); return(DIRRV_NOMORE); } return(DIRRV_MORE); break; } va_end(ap); abort(); }