#include #include #include #include typedef struct RGBA { int r; int g; int b; int a; u32int c; } RGBA; int dlevel; int ncolors; /* Number of checkpoint colors; 2-9. */ int nrows; /* Number of rows; always 1 for now. */ int nsteps; /* Number of steps to insert between checkpoint colors; 1-9. */ int nchips; /* Number of displayed chips; (ncolors - 1) * (nsteps + 1) + 1 */ RGBA* colors; /* Checkpoint colors specified on the commane line. */ RGBA* row; /* A filled-in row of colors. */ void usage(void) { fprint(2, "usage: %s [-D] [-f filename] [-s nsteps] color1 color2 [color3...]\n", argv0); exits("usage"); } void debug(int level, char* s) { if (dlevel >= level) fprint(2, s); } void c2rgba(RGBA *rgba, u32int color, int ext) { if (!ext) { debug(2, smprint("ext")); color = rgba->c; } rgba->r = color >> 24 & 0xFF; rgba->g = color >> 16 & 0xFF; rgba->b = color >> 8 & 0xFF; rgba->a = color & 0xFF; rgba->c = color; debug(1, smprint("%X %X %X %X %X\n", rgba->r, rgba->g, rgba->b, rgba->a, rgba->c)); } void mkrow(void) { int i, j, n, ΔR, ΔG, ΔB, ΔA; float sR, sG, sB, sA; i = 0; for (n = 0; n < ncolors - 1; n++) { debug(1, smprint("n=%d", n)); ΔR = (colors[n+1].r) - (colors[n].r); ΔG = (colors[n+1].g) - (colors[n].g); ΔB = (colors[n+1].b) - (colors[n].b); ΔA = (colors[n+1].a) - (colors[n].a); sR = (float)ΔR / (nsteps + 1); sG = (float)ΔG / (nsteps + 1); sB = (float)ΔB / (nsteps + 1); sA = (float)ΔA / (nsteps + 1); debug(1, smprint(" ΔR: %X, ΔG: %X, ΔB: %X, ΔA: %X\n", ΔR, ΔG, ΔB, ΔA)); debug(1, smprint(" sR: %f sG: %f, sB: %f, sA: %f\n", sR, sG, sB, sA)); if (n < ncolors - 1) { row[i] = colors[n]; debug(2, smprint("i=%d added %uX... \n", i, colors[n].c)); i++; } for (j = 1; j <= nsteps; j++) { row[i].r = colors[n].r + (int)(sR * j); row[i].g = colors[n].g + (int)(sG * j); row[i].b = colors[n].b + (int)(sB * j); row[i].a = colors[n].a + (int)(sA * j); row[i].c = (row[i].r << 24) | (row[i].g << 16) | (row[i].b << 8) | row[i].a; debug(2, smprint("i=%d added %uX from %uX... \n", i, row[i].c, colors[n].c)); i++; } } row[i] = colors[n]; debug(2, smprint("i=%d added %uX... \n", i, colors[n].c)); } void drawrow(Point start, int margin, int width, int height) { int i, x, y; Rectangle r; Image *chip; x = start.x; y = start.y; for (i = 0; i < nchips; i++) { r = Rect(x, y, x+width, y+height-font->height-2); x = x+width+margin; chip = allocimagemix(display, row[i].c, row[i].c); draw(screen, r, chip, nil, ZP); string(screen, Pt(r.min.x, r.max.y + margin), display->black, ZP, font, smprint("%u.8X", row[i].c)); flushimage(display, 1); } } void eresized(int new) { int margin, width, height, x, y; debug(2, smprint("got resize\n")); if(new && getwindow(display, Refmesg) < 0) fprint(2,"can't reattach to window"); margin = 4; x = screen->r.min.x + margin; y = screen->r.min.y + 2 * margin + font->height; width = (screen->r.max.x - screen->r.min.x - margin * (nchips + 1)) / nchips; height = (screen->r.max.y - y - margin * (nrows +1)) / nrows; drawrow(Pt(x, y), margin, width, height); flushimage(display, 1); } void main(int argc, char *argv[]) { int i; // char *colorfile; Event e; dlevel = 0; nsteps = 4; nrows = 1; ARGBEGIN{ case 'D': dlevel++; break; case 'f': // colorfile = nrows++; break; case 's': nsteps = atoi(EARGF(usage())); if (nsteps < 1 || nsteps > 9) { fprint(2, "%s: must have 1-9 steps.\n", argv0); exits("nsteps"); } break; default: usage(); }ARGEND if (argc < 2 || argc > 9){ fprint(2, "%s: must specify 2-9 colors.\n", argv0); exits("ncolors"); } ncolors = argc; debug(1, smprint("debug level: %d\n", dlevel)); colors = malloc(argc * sizeof(RGBA)); for (i = 0; i < argc; i++) { debug(2, smprint("ingest %d of %d: %s\n", i, argc, argv[i])); if (strlen(argv[i]) == 8) c2rgba(&colors[i], strtol(argv[i], 0, 16), 1); else if (strlen(argv[i]) == 6) c2rgba(&colors[i], (strtol(argv[i], 0, 16) << 8 | 0xFF), 1); else usage(); } nchips = (ncolors - 1) * (nsteps + 1) + 1; row = malloc(nchips * sizeof(RGBA)); debug(1, smprint("ncolors %d nsteps %d nchips %d ", ncolors, nsteps, nchips)); debug(1, smprint("sizeof(RGBA) %d \n", sizeof(RGBA))); mkrow(); if(initdraw(0, 0, argv0) < 0) sysfatal("initdraw failed: %r"); einit(Ekeyboard|Emouse); eresized(0); for(;;){ switch(eread(Ekeyboard|Emouse, &e)) { case Ekeyboard: if(e.kbdc==0x7F || e.kbdc=='q') exits(0); break; default: break; } } exits(0); }