#ifndef lint static char sccsid[] = "@(#)namedcolor.c 9.2 88/01/19 Copyright 1985 Sun Micro"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- Routines for dealing with phrases that name colors (eg. cs_setnamedcolor(gc,"redish brown")) namedcolor.c, Thu Sep 26 09:10:36 1985 James Gosling, Sun Microsystems */ #ifdef REF #include #include #endif #include #include "shape.h" static struct word { char *name; fract value; short type; } words[] = { "red", fracti(0)/360, 0, "green", fracti(120)/360, 0, "blue", fracti(240)/360, 0, "yellow", fracti(60)/360, 0, "magenta", fracti(300)/360, 0, "cyan", fracti(180)/360, 0, "brown", fracti(30)/360, 0, "dark", fracti(91)/255, 2, "bright", fracti(255)/255, 2, "deep", fracti(132)/255, 2, "medium", fracti(173)/255, 2, "light", fracti(214)/255, 2, "pale", fracti(127)/255, 1, "deep", fracti(191)/255, 1, "pure", fracti(255)/255, 1, "powder", fracti(30)/255, 1, "pastel", fracti(63)/255, 1, "saturated", fracti(255)/255, 1, 0 }; cs_setnamedcolor(gc, s) struct graphics_context *gc; register char *s; { struct axis { fract value; short weight; } axis[3]; int rgbhsv = 0; bzero(axis, sizeof axis); while (*s) { while (isspace(*s)) s++; if (isalpha(*s)) if (isdigit(s[1]) || s[1] == '.') { register char c = *s++; register n = 0; register dot = 0; register denom = 1; while (1) if (isdigit(*s)) { n = n * 10 + *s++ - '0'; if (dot) denom *= 10; } else if (*s == '.') if (dot) return -1; else s++, dot++; else break; n = fraction(n,denom); switch (c) { case 'h': c = 0; goto hsv; case 's': c = 1; goto hsv; case 'i': case 'v': c = 2; hsv: { register struct axis *a = &axis[c]; if (rgbhsv < 0 || a->weight) return -1; rgbhsv = 1; a->weight = 1; if (!dot) n/=c ? 100 : 360; if (n>fracti(1)) n = fracti(1); a->value = n; } break; case 'r': c = 0; goto rgb; case 'g': c = 1; goto rgb; case 'b': c = 2; rgb: { register struct axis *a = &axis[c]; if (rgbhsv > 0 || a->weight) return -1; rgbhsv = -1; a->weight = 1; if (!dot) n /= 100; if (n > fracti(1)) n = fracti(1); a->value = n; } break; default: return -1; } } else { register struct word *p; if (rgbhsv < 0) return -1; rgbhsv = 1; for (p = words;; p++) { if (p->name == 0) return -1; if (p->name[0] == *s) { register char *s1, *s2; s1 = s + 1; s2 = p->name + 1; while (*s2 && *s1++ == *s2) s2++; if (*s2) continue; s = s1; break; } } { register struct axis *a; register weight = 3; a = &axis[p->type]; if (s[0] == 'i' && s[1] == 's' && s[2] == 'h') weight = 2, s += 3; if (isalpha(*s)) return -1; if (a->weight == 0) { a->weight = weight; a->value = p->value; } else { a->value = (a->value * a->weight + p->value * weight) / (a->weight + weight); a->weight += weight; } } } else return -1; } if (rgbhsv == 0) return -1; if (rgbhsv > 0) { if (axis[1].weight == 0) axis[1].value = fraction(85, 100); if (axis[2].weight == 0) axis[2].value = fracti(1); cs_frsethsvcolor(gc,axis[0].value, axis[1].value, axis[2].value); } else cs_frsetrgbcolor(gc,axis[0].value, axis[1].value, axis[2].value); return 0; }