]> granicus.if.org Git - graphviz/commitdiff
add hsva, cmyk outputs
authorellson <devnull@localhost>
Fri, 26 Sep 2008 14:20:55 +0000 (14:20 +0000)
committerellson <devnull@localhost>
Fri, 26 Sep 2008 14:20:55 +0000 (14:20 +0000)
lib/inkpot/inkpot.h
lib/inkpot/inkpot_scheme.c
lib/inkpot/inkpot_structs.h
lib/inkpot/inkpot_tables.h
lib/inkpot/inkpot_xlate.c
lib/inkpot/test.c

index 636dd9699531e9a6e78b24172565cbe26f7709ea..3531e9e8b9f0d9ae625acddeebd06446eba17809 100644 (file)
@@ -1,18 +1,18 @@
 /* $Id$ $Revision$ */
 /* vim:set shiftwidth=4 ts=8: */
 
-/**********************************************************
-*      This software is part of the graphviz package      *
-*                http://www.graphviz.org/                 *
-*                                                         *
-*            Copyright (c) 1994-2004 AT&T Corp.           *
-*                and is licensed under the                *
-*            Common Public License, Version 1.0           *
-*                      by AT&T Corp.                      *
-*                                                         *
-*        Information and Software Systems Research        *
-*              AT&T Research, Florham Park NJ             *
-**********************************************************/
+/***********************************************************
+ *      This software is part of the graphviz package      *
+ *                http://www.graphviz.org/                 *
+ *                                                         *
+ *            Copyright (c) 1994-2008 AT&T Corp.           *
+ *                and is licensed under the                *
+ *            Common Public License, Version 1.0           *
+ *                      by AT&T Corp.                      *
+ *                                                         *
+ *        Information and Software Systems Research        *
+ *              AT&T Research, Florham Park NJ             *
+ **********************************************************/
 
 #ifndef INKPOT_H
 #define INKPOT_H
@@ -55,18 +55,16 @@ extern inkpot_status_t inkpot_set         ( inkpot_t *inkpot, const char *color );
 /* set inkpot color to the default (from the first scheme specified) */
 extern inkpot_status_t inkpot_set_default     ( inkpot_t *inkpot );
 /* set inkpot color by value, which may or may not have a name in the current or any schemes */
-extern inkpot_status_t inkpot_set_rgba       ( inkpot_t *inkpot, unsigned char rgba[4] );
+extern inkpot_status_t inkpot_set_rgba       ( inkpot_t *inkpot, double rgba[4] );
 
 /* get inkpot color name in the translation scheme, or for colors without a name in the translated scheme,
  * set NULL and return INKPOT_COLOR_NONAME */
 extern inkpot_status_t inkpot_get            ( inkpot_t *inkpot, const char **color );
 
 /* get inkpot color value in various formats */
-extern inkpot_status_t inkpot_get_rgba       ( inkpot_t *inkpot, unsigned char *rgba );
-extern inkpot_status_t inkpot_get_hsva       ( inkpot_t *inkpot, unsigned char *hsva );
-extern inkpot_status_t inkpot_get_cmyk       ( inkpot_t *inkpot, unsigned char *cmyk );
-extern inkpot_status_t inkpot_get_RGBA       ( inkpot_t *inkpot, double *RGBA );
-extern inkpot_status_t inkpot_get_HSVA       ( inkpot_t *inkpot, double *HSVA );
+extern inkpot_status_t inkpot_get_rgba       ( inkpot_t *inkpot, double rgba[4] );
+extern inkpot_status_t inkpot_get_hsva       ( inkpot_t *inkpot, double hsva[4] );
+extern inkpot_status_t inkpot_get_cmyk       ( inkpot_t *inkpot, double cmyk[4] );
 extern inkpot_status_t inkpot_get_index              ( inkpot_t *inkpot, unsigned int *index );
 
 /* output the current color to out_writer (default stdout) */
index 66e80cc602533549e1368857f596b6cac1ea05cd..6f9ac465cd47267078c3fd44d388069b6cc595c4 100644 (file)
@@ -1,11 +1,11 @@
 /* $Id$ $Revision$ */
 /* vim:set shiftwidth=4 ts=8: */
 
-/**********************************************************
+/***********************************************************
  *      This software is part of the graphviz package      *
  *                http://www.graphviz.org/                 *
  *                                                         *
- *            Copyright (c) 1994-2004 AT&T Corp.           *
+ *            Copyright (c) 1994-2008 AT&T Corp.           *
  *                and is licensed under the                *
  *            Common Public License, Version 1.0           *
  *                      by AT&T Corp.                      *
@@ -22,6 +22,7 @@
 
 #include "inkpot.h"
 #include "inkpot_tables.h"
+#include "inkpot_xlate.h"
 
 static size_t inkpot_writer (void *closure, const char *data, size_t length)
 {
@@ -296,33 +297,6 @@ static inkpot_status_t inkpot_set_index ( inkpot_t *inkpot, int index )
     return ((inkpot->status = INKPOT_SUCCESS));
 }
 
-inkpot_status_t inkpot_set( inkpot_t *inkpot, const char *color )
-{
-    int index, r, g, b, a=255;
-    unsigned char rgba[4];
-    inkpot_status_t rc = INKPOT_COLOR_UNKNOWN;
-
-    if (!color)
-        return ((inkpot->status = INKPOT_COLOR_UNKNOWN));
-
-    if (sscanf(color, "#%2x%2x%2x%2x", &r, &g, &b, &a) >= 3) {
-       rgba[0] = r;
-       rgba[1] = g;
-       rgba[2] = b;
-       rgba[3] = a;
-       rc = inkpot_set_rgba(inkpot, rgba);
-    }
-
-    if (rc != INKPOT_SUCCESS)
-        if (sscanf(color, "%d", &index) == 1)
-            rc = inkpot_set_index(inkpot, index);
-
-    if (rc != INKPOT_SUCCESS)
-        rc = inkpot_set_name(inkpot, color);
-
-    return rc;
-}
-
 inkpot_status_t inkpot_set_default( inkpot_t *inkpot )
 {
     if (inkpot->value_idx != inkpot->default_value_idx) {
@@ -335,21 +309,15 @@ inkpot_status_t inkpot_set_default( inkpot_t *inkpot )
 
 static int inkpot_rgba_cmpf ( const void *key, const void *base)
 {
-    unsigned char *rgba_key = (unsigned char *)key;
-    unsigned char *rgba_base = (unsigned char *)base;
-
-    if (*rgba_key   > *rgba_base  ) return  1;
-    if (*rgba_key++ < *rgba_base++) return -1;
-    if (*rgba_key   > *rgba_base  ) return  1;
-    if (*rgba_key++ < *rgba_base++) return -1;
-    if (*rgba_key   > *rgba_base  ) return  1;
-    if (*rgba_key++ < *rgba_base++) return -1;
-    if (*rgba_key   > *rgba_base  ) return  1;
-    if (*rgba_key++ < *rgba_base++) return -1;
+    RGBA rgba_key = *(RGBA*)key;
+    RGBA rgba_base = *(RGBA*)base;
+
+    if (rgba_key > rgba_base) return  1;
+    if (rgba_key < rgba_base) return -1;
     return 0;
 }
 
-inkpot_status_t inkpot_set_rgba ( inkpot_t *inkpot, unsigned char *rgba ) 
+static inkpot_status_t inkpot_set_RGBA ( inkpot_t *inkpot, RGBA *rgba ) 
 {
     inkpot_value_t *value;
     inkpot_name_t *name;
@@ -418,6 +386,50 @@ inkpot_status_t inkpot_set_rgba ( inkpot_t *inkpot, unsigned char *rgba )
 #endif
 }
 
+inkpot_status_t inkpot_set( inkpot_t *inkpot, const char *color )
+{
+    int index;
+    unsigned int rgba;
+    inkpot_status_t rc = INKPOT_COLOR_UNKNOWN;
+
+    if (!color)
+        return ((inkpot->status = INKPOT_COLOR_UNKNOWN));
+
+    if (sscanf(color, "#%6x", &rgba)) {
+       rgba = (rgba << SZB_RED) | MAX_RED;
+       rc = inkpot_set_RGBA(inkpot, &rgba);
+    }
+
+    if (rc != INKPOT_SUCCESS)
+        if (sscanf(color, "#%8x", &rgba))
+           rc = inkpot_set_RGBA(inkpot, &rgba);
+
+    if (rc != INKPOT_SUCCESS)
+        if (sscanf(color, "%d", &index) == 1)
+            rc = inkpot_set_index(inkpot, index);
+
+    if (rc != INKPOT_SUCCESS)
+        rc = inkpot_set_name(inkpot, color);
+
+    return rc;
+}
+
+inkpot_status_t inkpot_set_rgba ( inkpot_t *inkpot, double rgba[4] )
+{
+    unsigned int myrgba = 0, v;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+       myrgba <<= SZB_RED;
+       v = rgba[i];
+       v = (v < 0.0) ? 0.0 : v;
+       v = (v > 1.0) ? 1.0 : v;
+       myrgba |= (int)(v * MAX_RED);
+    }
+
+    return inkpot_set_RGBA ( inkpot, &myrgba );
+}
+
 inkpot_status_t inkpot_get ( inkpot_t *inkpot, const char **color )
 {
     inkpot_name_t *out_name;
@@ -463,45 +475,57 @@ inkpot_status_t inkpot_get ( inkpot_t *inkpot, const char **color )
     return ((inkpot->status = INKPOT_FAIL));
 }
 
-inkpot_status_t inkpot_get_rgba ( inkpot_t *inkpot, unsigned char *rgba )
+static inkpot_status_t inkpot_get_RGBA ( inkpot_t *inkpot, RGBA *rgba )
 {
     IDX_VALUES value_idx = inkpot->value_idx;
-    unsigned char *p = rgba, *q;
-    int m;
 
     if (value_idx < SZT_VALUES)
-       q = TAB_VALUES[value_idx].rgba;
+       *rgba = TAB_VALUES[value_idx].rgba;
     else {
        assert (value_idx < SZT_VALUES + SZT_NONAME_VALUES);
-       q = TAB_NONAME_VALUES[value_idx - SZT_VALUES].rgba;
+       *rgba = TAB_NONAME_VALUES[value_idx - SZT_VALUES].rgba;
     }
-    for (m = 0; m < 4; m++) *p++ = *q++;
 
     return ((inkpot->status = INKPOT_SUCCESS));
 }
 
-inkpot_status_t inkpot_get_hsva ( inkpot_t *inkpot, unsigned char *hsva )
+inkpot_status_t inkpot_get_rgba ( inkpot_t *inkpot, double rgba[4] )
 {
-    /* FIXME */
-    return ((inkpot->status = INKPOT_FAIL));
+    inkpot_status_t rc;
+    RGBA myrgba;
+    int i;
+
+    rc = inkpot_get_RGBA( inkpot, &myrgba );
+    if (rc == INKPOT_SUCCESS) {
+       for (i = 3; i >= 0; i--) {
+           rgba[i] = (myrgba & MSK_RED) / (double)MAX_RED;
+           myrgba >>= SZB_RED;
+       }
+    }
+    return rc;
 }
-
-inkpot_status_t inkpot_get_cmyk ( inkpot_t *inkpot, unsigned char *cmyk )
+inkpot_status_t inkpot_get_hsva ( inkpot_t *inkpot, double hsva[4] )
 {
-    /* FIXME */
-    return ((inkpot->status = INKPOT_FAIL));
-}
+    inkpot_status_t rc;
+    double rgba[4];
 
-inkpot_status_t inkpot_get_RGBA ( inkpot_t *inkpot, double *RGBA )
-{
-    /* FIXME */
-    return ((inkpot->status = INKPOT_FAIL));
+    rc = inkpot_get_rgba(inkpot, rgba);
+    if (rc == INKPOT_SUCCESS)
+       rgba2hsva( rgba, hsva );
+    return rc;
 }
 
-inkpot_status_t inkpot_get_HSVA ( inkpot_t *inkpot, double *HSVA )
+inkpot_status_t inkpot_get_cmyk ( inkpot_t *inkpot, double cmyk[4] )
 {
-    /* FIXME */
-    return ((inkpot->status = INKPOT_FAIL));
+    inkpot_status_t rc;
+    double rgba[4];
+
+    rc = inkpot_get_rgba(inkpot, rgba);
+    if (rc == INKPOT_SUCCESS)
+       rgba2cmyk( rgba, cmyk );
+    return rc;
 }
 
 inkpot_status_t inkpot_get_index ( inkpot_t *inkpot, unsigned int *index )
@@ -578,15 +602,21 @@ static inkpot_status_t inkpot_debug_scheme_names( inkpot_t *inkpot, int scheme_b
     return INKPOT_SUCCESS;
 }
 
-static void inkpot_debug_rgba( inkpot_t *inkpot, unsigned char *rgba )
+static void inkpot_debug_rgba( inkpot_t *inkpot, RGBA rgba )
 {
     char buf[20];
+    unsigned int r, g, b, a;
 
-    sprintf(buf, "%d,%d,%d,%d", rgba[0], rgba[1], rgba[2], rgba[3]);
+    a = rgba & MSK_RED; rgba >>= SZB_RED;
+    b = rgba & MSK_RED; rgba >>= SZB_RED;
+    g = rgba & MSK_RED; rgba >>= SZB_RED;
+    r = rgba & MSK_RED;
+
+    sprintf(buf, "%d,%d,%d,%d", r, g, b, a);
     errputs(inkpot, buf);
 }
 
-static inkpot_status_t inkpot_debug_names_schemes( inkpot_t *inkpot, BIT_SCHEMES_NAME scheme_bits, inkpot_scheme_index_t *scheme_index )
+static inkpot_status_t inkpot_debug_names_schemes( inkpot_t *inkpot, MSK_SCHEMES_NAME scheme_bits, inkpot_scheme_index_t *scheme_index )
 {
     inkpot_name_t *name;
     IDX_NAMES i;
@@ -637,7 +667,7 @@ static inkpot_status_t inkpot_debug_names_schemes( inkpot_t *inkpot, BIT_SCHEMES
 
 inkpot_status_t inkpot_debug_names( inkpot_t *inkpot )
 {
-    BIT_SCHEMES_NAME scheme_bits = inkpot->scheme_bits;
+    MSK_SCHEMES_NAME scheme_bits = inkpot->scheme_bits;
     inkpot_scheme_index_t *scheme_index = inkpot->scheme_index;
 
     errputs(inkpot, "names (in):\n");
@@ -646,7 +676,7 @@ inkpot_status_t inkpot_debug_names( inkpot_t *inkpot )
 
 inkpot_status_t inkpot_debug_names_out( inkpot_t *inkpot )
 {
-    BIT_SCHEMES_NAME scheme_bits = inkpot->out_scheme_bit;
+    MSK_SCHEMES_NAME scheme_bits = inkpot->out_scheme_bit;
     inkpot_scheme_index_t *scheme_index = inkpot->out_scheme_index;
 
     errputs(inkpot, "names (out):\n");
@@ -663,7 +693,7 @@ inkpot_status_t inkpot_debug_values( inkpot_t *inkpot )
     inkpot_name_t *name;
     IDX_VALUES i;
     IDX_NAMES t;
-    BIT_SCHEMES_NAME scheme_bits;
+    MSK_SCHEMES_NAME scheme_bits;
     int found;
 
     errputs(inkpot, "values:\n");
@@ -698,9 +728,8 @@ inkpot_status_t inkpot_write ( inkpot_t *inkpot )
     inkpot_status_t rc;
     const char *color;
     IDX_VALUES value_idx;
-    unsigned char *p, *q, rgba[4];
-    int m;
-    char buf[10] = "#12345678"; /* sets up "#........\0" */
+    RGBA rgba;
+    char buf[10];
 
     rc = inkpot_get(inkpot, &color);
     if (rc == INKPOT_SUCCESS)
@@ -708,17 +737,13 @@ inkpot_status_t inkpot_write ( inkpot_t *inkpot )
     if (rc == INKPOT_COLOR_NONAME) {
         value_idx = inkpot->value_idx;
         if (value_idx < SZT_VALUES)
-           q = TAB_VALUES[value_idx].rgba;
+           rgba = TAB_VALUES[value_idx].rgba;
         else {
            assert (value_idx < SZT_VALUES + SZT_NONAME_VALUES);
-           q = TAB_NONAME_VALUES[value_idx - SZT_VALUES].rgba;
+           rgba = TAB_NONAME_VALUES[value_idx - SZT_VALUES].rgba;
         }
 
-/* FIXME - this is ugly */
-       p = rgba;
-       for (m = 0; m < 4; m++) *p++ = *q++;  
-       sprintf(buf, "#%02x%02x%02x%02x", rgba[0], rgba[1], rgba[2], rgba[3]);
-
+       sprintf(buf, "#%08x", rgba);
        inkpot->disc.out_writer(inkpot->out_closure, buf, sizeof(buf));
     }
     return rc;
index 29b6aaaf7cfa5d6ec9c83886e0bcc8d415524c7e..691204c2bbb2bed6be65067d0764d09e73f8a5f3 100644 (file)
@@ -1,18 +1,18 @@
 /* $Id$ $Revision$ */
 /* vim:set shiftwidth=4 ts=8: */
 
-/**********************************************************
-*      This software is part of the graphviz package      *
-*                http://www.graphviz.org/                 *
-*                                                         *
-*            Copyright (c) 1994-2004 AT&T Corp.           *
-*                and is licensed under the                *
-*            Common Public License, Version 1.0           *
-*                      by AT&T Corp.                      *
-*                                                         *
-*        Information and Software Systems Research        *
-*              AT&T Research, Florham Park NJ             *
-**********************************************************/
+/***********************************************************
+ *      This software is part of the graphviz package      *
+ *                http://www.graphviz.org/                 *
+ *                                                         *
+ *            Copyright (c) 1994-2008 AT&T Corp.           *
+ *                and is licensed under the                *
+ *            Common Public License, Version 1.0           *
+ *                      by AT&T Corp.                      *
+ *                                                         *
+ *        Information and Software Systems Research        *
+ *              AT&T Research, Florham Park NJ             *
+ **********************************************************/
 
 #ifndef INKPOT_STRUCTS_H
 #define INKPOT_STRUCTS_H
@@ -59,7 +59,7 @@ typedef struct inkpot_name_s {        /* Color_name used by one or more
            value_idx;          /* An index into TAB_VALUE for this
                                 * inkpot_name_t */
 
-       BIT_SCHEMES_NAME
+       MSK_SCHEMES_NAME
            scheme_bits;        /* A bit for each inkpot_scheme_name_t
                                 * that includes this inkpot_name_t  */
 
@@ -80,7 +80,7 @@ typedef struct inkpot_value_s {       /* Numeric color values used by the set
                                 * are numerically sorted by rgb value
                                 * in TAB_VALUES[] */
 
-       unsigned char rgba[4];  /* rgba */
+       RGBA rgba;
 
        IDX_NAMES
            toname_idx;         /* An index into TAB_NAMES to the toname
@@ -100,14 +100,14 @@ typedef struct inkpot_noname_value_s {    /* Numeric color values used by the remai
                                 * inkpot_noname_value_t instances are unique and
                                 * are numerically sorted by rgba value
                                 * in TAB_NONAME_VALUES[] */
+       RGBA rgba;
 
-       unsigned char rgba[4];  /* rgba */
 } inkpot_noname_value_t;
 
 /* typedef struct inkpot_s inkpot_t; */  /* public opaque type in inkpot.h */
 
 struct inkpot_s {              /* The Ink Pot */
-       BIT_SCHEMES_NAME
+       MSK_SCHEMES_NAME
            scheme_bits,        /* One bit per inkpot_scheme_name_t */
            out_scheme_bit;     /* One scheme only for output. */
 
index f61a814eb16e91d14d5d9444005ce4e99552e0a6..11cb879af4031ae8d64077beaf0e05f044fefe4e 100644 (file)
@@ -1,12 +1,32 @@
-typedef unsigned char IDX_STRINGS;
-typedef unsigned char BIT_SCHEMES_NAME;
-typedef unsigned char IDX_SCHEMES_NAME;
-typedef unsigned char IDX_SCHEMES_INDEX;
-typedef unsigned char IDX_NAMES;
-typedef unsigned char IDX_NAME_ALTS;
-typedef unsigned char IDX_VALUES;
-typedef unsigned char IDX_TONAMES;
-typedef unsigned char IDX_IXVALUES;
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/***********************************************************
+ *      This software is part of the graphviz package      *
+ *                http://www.graphviz.org/                 *
+ *                                                         *
+ *            Copyright (c) 1994-2008 AT&T Corp.           *
+ *                and is licensed under the                *
+ *            Common Public License, Version 1.0           *
+ *                      by AT&T Corp.                      *
+ *                                                         *
+ *        Information and Software Systems Research        *
+ *              AT&T Research, Florham Park NJ             *
+ **********************************************************/
+
+typedef unsigned int   IDX_STRINGS;
+typedef unsigned short MSK_SCHEMES_NAME;
+typedef unsigned char  IDX_SCHEMES_NAME;
+typedef unsigned char  IDX_SCHEMES_INDEX;
+typedef unsigned int   IDX_NAMES;
+typedef unsigned char  IDX_NAME_ALTS;
+typedef unsigned int   IDX_VALUES;
+typedef unsigned int   IDX_IXVALUES;
+
+typedef unsigned int   RGBA;
+#define SZB_RED 8
+#define MSK_RED 255
+#define MAX_RED 255
 
 #include "inkpot_structs.h"
 
@@ -63,22 +83,22 @@ IDX_NAMES TAB_NAME_ALTS[] = {
 };
 #define SZT_NAME_ALTS (sizeof(TAB_NAME_ALTS)/sizeof(TAB_NAME_ALTS[0]))
 
-inkpot_value_t TAB_VALUES[] = { /* Must be LC_ALL=C sort'ed by r,g,b,a */
-       {{0,    0,      0,      255},   0 },  /* black */
-       {{0,    0,      255,    255},   1 },  /* bleu, blue */
-       {{0,    255,    0,      255},   3 },  /* green, vert */
-       {{255,  0,      0,      255},   5 },  /* red, rouge */
-       {{255,  192,    0,      255},   7 },  /* yellow (svg) */
-       {{255,  255,    0,      255},   8 },  /* yellow (x11), jaune */
-       {{255,  255,    255,    255},   10},  /* white */
+inkpot_value_t TAB_VALUES[] = { /* Must be sort'ed */
+       { 0x000000ff, 0 },  /* black */
+       { 0x0000ffff, 1 },  /* bleu, blue */
+       { 0x00ff00ff, 3 },  /* green, vert */
+       { 0xff0000ff, 5 },  /* red, rouge */
+       { 0xffcf00ff, 7 },  /* yellow (svg) */
+       { 0xffff00ff, 8 },  /* yellow (x11), jaune */
+       { 0xffffffff, 10},  /* white */
 }; 
 #define SZT_VALUES (sizeof(TAB_VALUES)/sizeof(TAB_VALUES[0]))
 
-inkpot_noname_value_t TAB_NONAME_VALUES[] = { /* Must be LC_ALL=C sort'ed by r,g,b,a */
-       {{0,    0,      128,    255}},
-       {{0,    0,      160,    255}},
-       {{0,    0,      192,    255}},
-       {{0,    0,      224,    255}},
+inkpot_noname_value_t TAB_NONAME_VALUES[] = { /* Must be sort'ed */
+       { 0x000080ff },
+       { 0x0000a4ff },
+       { 0x0000c8ff },
+       { 0x0000eaff },
 }; 
 #define SZT_NONAME_VALUES (sizeof(TAB_NONAME_VALUES)/sizeof(TAB_NONAME_VALUES[0]))
 
index 4a3d5b8236306c6c853b36e3d6efacdea71a8ad2..d5aa5eb65e553c9af5b6a28cee99e002a7746b7d 100644 (file)
@@ -1,44 +1,35 @@
 /* $Id$ $Revision$ */
 /* vim:set shiftwidth=4 ts=8: */
 
-/**********************************************************
-*      This software is part of the graphviz package      *
-*                http://www.graphviz.org/                 *
-*                                                         *
-*            Copyright (c) 1994-2004 AT&T Corp.           *
-*                and is licensed under the                *
-*            Common Public License, Version 1.0           *
-*                      by AT&T Corp.                      *
-*                                                         *
-*        Information and Software Systems Research        *
-*              AT&T Research, Florham Park NJ             *
-**********************************************************/
+/***********************************************************
+ *      This software is part of the graphviz package      *
+ *                http://www.graphviz.org/                 *
+ *                                                         *
+ *            Copyright (c) 1994-2008 AT&T Corp.           *
+ *                and is licensed under the                *
+ *            Common Public License, Version 1.0           *
+ *                      by AT&T Corp.                      *
+ *                                                         *
+ *        Information and Software Systems Research        *
+ *              AT&T Research, Florham Park NJ             *
+ **********************************************************/
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "inkpot.h"
 #include "inkpot_xlate.h"
 
-#ifndef MIN
-#define MIN(a,b)    ((a)<(b)?(a):(b))
-#endif
-
-#ifndef MAX
-#define MAX(a,b)    ((a)>(b)?(a):(b))
-#endif
-
-static void hsv2rgb(double h, double s, double v, double *r, double *g, double *b)
+void hsva2rgba(double hsva[4], double rgba[4])
 {
     int i;
-    double f, p, q, t;
+    double f, p, q, t, h, s, v;
+
+    rgba[3] = hsva[3]; /* copy alpha */
+    h = hsva[0];
+    s = hsva[1];
+    v = hsva[2];
 
     if (s <= 0.0) {            /* achromatic */
-       *r = v;
-       *g = v;
-       *b = v;
+       rgba[0] = v;
+       rgba[1] = v;
+       rgba[2] = v;
     } else {
        if (h >= 1.0)
            h = 0.0;
@@ -50,333 +41,89 @@ static void hsv2rgb(double h, double s, double v, double *r, double *g, double *
        t = v * (1 - (s * (1 - f)));
        switch (i) {
        case 0:
-           *r = v;
-           *g = t;
-           *b = p;
+           rgba[0] = v;
+           rgba[1] = t;
+           rgba[2] = p;
            break;
        case 1:
-           *r = q;
-           *g = v;
-           *b = p;
+           rgba[0] = q;
+           rgba[1] = v;
+           rgba[2] = p;
            break;
        case 2:
-           *r = p;
-           *g = v;
-           *b = t;
+           rgba[0] = p;
+           rgba[1] = v;
+           rgba[2] = t;
            break;
        case 3:
-           *r = p;
-           *g = q;
-           *b = v;
+           rgba[0] = p;
+           rgba[1] = q;
+           rgba[2] = v;
            break;
        case 4:
-           *r = t;
-           *g = p;
-           *b = v;
+           rgba[0] = t;
+           rgba[1] = p;
+           rgba[2] = v;
            break;
        case 5:
-           *r = v;
-           *g = p;
-           *b = q;
+           rgba[0] = v;
+           rgba[1] = p;
+           rgba[2] = q;
            break;
        }
     }
 }
 
-static void rgb2hsv(double r, double g, double b, double *h, double *s, double *v)
+void rgba2hsva(double rgba[4], double hsva[4])
 {
 
     double rgbmin, rgbmax;
     double rc, bc, gc;
     double ht = 0.0, st = 0.0;
 
-    rgbmin = MIN(r, MIN(g, b));
-    rgbmax = MAX(r, MAX(g, b));
+    hsva[3] = rgba[3];  /* copy alpha */
+
+    rgbmin = (rgba[1] < rgba[2]) ? rgba[1] : rgba[2];
+    rgbmin = (rgba[0] < rgbmin ) ? rgba[0] : rgbmin;
+
+    rgbmax = (rgba[1] > rgba[2]) ? rgba[1] : rgba[2];
+    rgbmax = (rgba[0] > rgbmax ) ? rgba[0] : rgbmax;
 
     if (rgbmax > 0.0)
        st = (rgbmax - rgbmin) / rgbmax;
 
     if (st > 0.0) {
-       rc = (rgbmax - r) / (rgbmax - rgbmin);
-       gc = (rgbmax - g) / (rgbmax - rgbmin);
-       bc = (rgbmax - b) / (rgbmax - rgbmin);
-       if (r == rgbmax)
+       rc = (rgbmax - rgba[0]) / (rgbmax - rgbmin);
+       gc = (rgbmax - rgba[1]) / (rgbmax - rgbmin);
+       bc = (rgbmax - rgba[2]) / (rgbmax - rgbmin);
+       if (rgba[0] == rgbmax)
            ht = bc - gc;
-       else if (g == rgbmax)
+       else if (rgba[1] == rgbmax)
            ht = 2 + rc - bc;
-       else if (b == rgbmax)
+       else if (rgba[2] == rgbmax)
            ht = 4 + gc - rc;
        ht = ht * 60.0;
        if (ht < 0.0)
            ht += 360.0;
     }
-    *h = ht / 360.0;
-    *v = rgbmax;
-    *s = st;
+    hsva[0] = ht / 360.0;
+    hsva[1] = st;
+    hsva[2] = rgbmax;
 }
 
-static void rgb2cmyk(double r, double g, double b, double *c, double *m, double *y, double *k)
+void rgba2cmyk(double rgba[4], double cmyk[4])
 {
-    *c = 1.0 - r;
-    *m = 1.0 - g;
-    *y = 1.0 - b;
-    *k = *c < *m ? *c : *m;
-    *k = *y < *k ? *y : *k;
-    *c -= *k;
-    *m -= *k;
-    *y -= *k;
-}
-
-#if 0
-static char *canoncolortoken(const char *str)
-{
-    static char *canon;
-    static int allocated;
-    const char *p;
-    char *q, c;
-    int len;
-
-    p = str;
-    len = strlen(str);
-    if (len >= allocated) {
-       allocated = len + 1 + 10;
-       canon = realloc(canon, allocated);
-       if (!canon)
-           return NULL;
-    }
-    q = canon;
-    while ((c = *p++)) {
-       if (! isalnum(c))
-           continue;
-       if (isupper(c))
-           c = tolower(c);
-       *q++ = c;
-    }
-    *q = '\0';
-    return canon;
-}
-#endif
-
-inkpot_status_t colorxlate(const char *str, gvcolor_t * color, color_type_t target_type)
-{
-    static unsigned char *canon;
-    static int allocated;
-    unsigned char *p, *q;
-    unsigned char c;
-    double H, S, V, A, R, G, B;
-    double C, M, Y, K;
-    unsigned int r, g, b, a;
-    unsigned int rgba[4], hsva[4];
-    int len;
-    inkpot_status_t rc;
-
-    color->type = target_type;
-
-    rc = INKPOT_SUCCESS;
-    for (; *str == ' '; str++);        /* skip over any leading whitespace */
-    p = (unsigned char *) str;
-
-    /* test for rgb value such as: "#ff0000"
-     * or rgba value such as "#ff000080" */
-    a = 255;                   /* default alpha channel value=opaque in case not supplied */
-    if ((*p == '#')
-       && (sscanf((char *) p, "#%2x%2x%2x%2x", &r, &g, &b, &a) >= 3)) {
-       switch (target_type) {
-       case HSVA_DOUBLE:
-           R = r / 255.0;
-           G = g / 255.0;
-           B = b / 255.0;
-           A = a / 255.0;
-           rgb2hsv(R, G, B, &H, &S, &V);
-           color->u.HSVA[0] = H;
-           color->u.HSVA[1] = S;
-           color->u.HSVA[2] = V;
-           color->u.HSVA[3] = A;
-           break;
-       case RGBA_BYTE:
-           color->u.rgba[0] = r;
-           color->u.rgba[1] = g;
-           color->u.rgba[2] = b;
-           color->u.rgba[3] = a;
-           break;
-       case CMYK_BYTE:
-           R = r / 255.0;
-           G = g / 255.0;
-           B = b / 255.0;
-           rgb2cmyk(R, G, B, &C, &M, &Y, &K);
-           color->u.cmyk[0] = (int) C *255;
-           color->u.cmyk[1] = (int) M *255;
-           color->u.cmyk[2] = (int) Y *255;
-           color->u.cmyk[3] = (int) K *255;
-           break;
-       case RGBA_WORD:
-           color->u.rrggbbaa[0] = r * 65535 / 255;
-           color->u.rrggbbaa[1] = g * 65535 / 255;
-           color->u.rrggbbaa[2] = b * 65535 / 255;
-           color->u.rrggbbaa[3] = a * 65535 / 255;
-           break;
-       case RGBA_DOUBLE:
-           color->u.RGBA[0] = r / 255.0;
-           color->u.RGBA[1] = g / 255.0;
-           color->u.RGBA[2] = b / 255.0;
-           color->u.RGBA[3] = a / 255.0;
-           break;
-       case COLOR_STRING:
-           break;
-       case COLOR_INDEX:
-           break;
-       }
-       return rc;
-    }
-
-    /* test for hsv value such as: ".6,.5,.3" */
-    if (((c = *p) == '.') || isdigit(c)) {
-       len = strlen((char*)p);
-       if (len >= allocated) {
-           allocated = len + 1 + 10;
-           canon = realloc(canon, allocated);
-           if (! canon) {
-               rc = INKPOT_MALLOC_FAIL;
-               return rc;
-           }
-       }
-       q = canon;
-       while ((c = *p++)) {
-           if (c == ',')
-               c = ' ';
-           *q++ = c;
-       }
-       *q = '\0';
-
-       A = 1.0; /* default alpha channel value=opaque in case not supplied */
-       if (sscanf((char *) canon, "%lf%lf%lf%lf", &H, &S, &V, &A) >= 3) {
-           /* clip to reasonable values */
-           H = MAX(MIN(H, 1.0), 0.0);
-           S = MAX(MIN(S, 1.0), 0.0);
-           V = MAX(MIN(V, 1.0), 0.0);
-           A = MAX(MIN(A, 1.0), 0.0);
-           switch (target_type) {
-           case HSVA_DOUBLE:
-               color->u.HSVA[0] = H;
-               color->u.HSVA[1] = S;
-               color->u.HSVA[2] = V;
-               color->u.HSVA[3] = A;
-               break;
-           case RGBA_BYTE:
-               hsv2rgb(H, S, V, &R, &G, &B);
-               color->u.rgba[0] = (int) (R * 255);
-               color->u.rgba[1] = (int) (G * 255);
-               color->u.rgba[2] = (int) (B * 255);
-               color->u.rgba[3] = (int) (A * 255);
-               break;
-           case CMYK_BYTE:
-               hsv2rgb(H, S, V, &R, &G, &B);
-               rgb2cmyk(R, G, B, &C, &M, &Y, &K);
-               color->u.cmyk[0] = (int) C *255;
-               color->u.cmyk[1] = (int) M *255;
-               color->u.cmyk[2] = (int) Y *255;
-               color->u.cmyk[3] = (int) K *255;
-               break;
-           case RGBA_WORD:
-               hsv2rgb(H, S, V, &R, &G, &B);
-               color->u.rrggbbaa[0] = (int) (R * 65535);
-               color->u.rrggbbaa[1] = (int) (G * 65535);
-               color->u.rrggbbaa[2] = (int) (B * 65535);
-               color->u.rrggbbaa[3] = (int) (A * 65535);
-               break;
-           case RGBA_DOUBLE:
-               hsv2rgb(H, S, V, &R, &G, &B);
-               color->u.RGBA[0] = R;
-               color->u.RGBA[1] = G;
-               color->u.RGBA[2] = B;
-               color->u.RGBA[3] = A;
-               break;
-           case COLOR_STRING:
-               break;
-           case COLOR_INDEX:
-               break;
-           }
-           return rc;
-       }
-    }
-
-//    rc = inkpot_set(inkpot, str);
-    if (rc == INKPOT_SUCCESS) {
-       switch (target_type) {
-       case HSVA_DOUBLE:
-//         inkpot_get_hsva(inkpot, hsva);
-           color->u.HSVA[0] = hsva[0] / 255.0;
-           color->u.HSVA[1] = hsva[1] / 255.0;
-           color->u.HSVA[2] = hsva[2] / 255.0;
-           color->u.HSVA[3] = hsva[3] / 255.0;
-           break;
-       case RGBA_BYTE:
-//         inkpot_get_rgba(inkpot, rgba);
-           color->u.rgba[0] = rgba[0];
-           color->u.rgba[1] = rgba[1];
-           color->u.rgba[2] = rgba[2];
-           color->u.rgba[3] = rgba[3];
-           break;
-       case CMYK_BYTE:
-//         inkpot_get_rgba(inkpot, rgba);
-           R = rgba[0] / 255.0;
-           G = rgba[1] / 255.0;
-           B = rgba[2] / 255.0;
-           rgb2cmyk(R, G, B, &C, &M, &Y, &K);
-           color->u.cmyk[0] = (int) C * 255;
-           color->u.cmyk[1] = (int) M * 255;
-           color->u.cmyk[2] = (int) Y * 255;
-           color->u.cmyk[3] = (int) K * 255;
-           break;
-       case RGBA_WORD:
-//         inkpot_get_rgba(inkpot, rgba);
-           color->u.rrggbbaa[0] = rgba[0] * 65535 / 255;
-           color->u.rrggbbaa[1] = rgba[1] * 65535 / 255;
-           color->u.rrggbbaa[2] = rgba[2] * 65535 / 255;
-           color->u.rrggbbaa[3] = rgba[3] * 65535 / 255;
-           break;
-       case RGBA_DOUBLE:
-//         inkpot_get_rgba(inkpot, rgba);
-           color->u.RGBA[0] = rgba[0] / 255.0;
-           color->u.RGBA[1] = rgba[1] / 255.0;
-           color->u.RGBA[2] = rgba[2] / 255.0;
-           color->u.RGBA[3] = rgba[3] / 255.0;
-           break;
-       case COLOR_STRING:
-           break;
-       case COLOR_INDEX:
-           break;
-       }
-       return rc;
-    }
-
-    /* if we're still here then we failed to find a valid color spec */
-    rc = INKPOT_COLOR_UNKNOWN;
-    switch (target_type) {
-    case HSVA_DOUBLE:
-       color->u.HSVA[0] = color->u.HSVA[1] = color->u.HSVA[2] = 0.0;
-       color->u.HSVA[3] = 1.0; /* opaque */
-       break;
-    case RGBA_BYTE:
-       color->u.rgba[0] = color->u.rgba[1] = color->u.rgba[2] = 0;
-       color->u.rgba[3] = 255; /* opaque */
-       break;
-    case CMYK_BYTE:
-       color->u.cmyk[0] =
-           color->u.cmyk[1] = color->u.cmyk[2] = color->u.cmyk[3] = 0;
-       break;
-    case RGBA_WORD:
-       color->u.rrggbbaa[0] = color->u.rrggbbaa[1] = color->u.rrggbbaa[2] = 0;
-       color->u.rrggbbaa[3] = 65535;   /* opaque */
-       break;
-    case RGBA_DOUBLE:
-       color->u.RGBA[0] = color->u.RGBA[1] = color->u.RGBA[2] = 0.0;
-       color->u.RGBA[3] = 1.0; /* opaque */
-       break;
-    case COLOR_STRING:
-       break;
-    case COLOR_INDEX:
-       break;
-    }
-    return rc;
+    double c, m, y, k;
+
+    /* alpha is ignored */
+
+    c = 1.0 - rgba[0];
+    m = 1.0 - rgba[1];
+    y = 1.0 - rgba[2];
+    k = c < m ? c : m;
+    k = y < k ? y : k;
+    cmyk[4] = k;
+    cmyk[3] = c - k;
+    cmyk[2] = m - k;
+    cmyk[0] = y - k;
 }
index f5ad8c8c1d3bfb0621ec72605cd57a61dddacf93..f34710a89dc63d71530abdd697243a0adfd71183 100644 (file)
@@ -1,3 +1,19 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/***********************************************************
+ *      This software is part of the graphviz package      *
+ *                http://www.graphviz.org/                 *
+ *                                                         *
+ *            Copyright (c) 1994-2008 AT&T Corp.           *
+ *                and is licensed under the                *
+ *            Common Public License, Version 1.0           *
+ *                      by AT&T Corp.                      *
+ *                                                         *
+ *        Information and Software Systems Research        *
+ *              AT&T Research, Florham Park NJ             *
+ **********************************************************/
+
 #include <stdio.h>
 #include <assert.h>
 
@@ -9,7 +25,7 @@ int main (int argc, char *argv[])
     inkpot_status_t rc;
     char *color;
     int i;
-    unsigned char rgba[4];
+    double rgba[4], hsva[4], cmyk[4];
 
     inkpot = inkpot_init();
     if (!inkpot) {
@@ -63,7 +79,7 @@ int main (int argc, char *argv[])
     fprintf(stdout, "%s ", color);
     rc = inkpot_set(inkpot, color);
     if (rc == INKPOT_COLOR_UNKNOWN) {
-        fprintf(stdout, "(unknown) ");
+        fprintf(stdout, "(unknown)\n text: ");
        rc = inkpot_set_default(inkpot);
        assert (rc == INKPOT_SUCCESS);
     }
@@ -73,8 +89,18 @@ int main (int argc, char *argv[])
 
     rc = inkpot_get_rgba(inkpot, rgba);
     assert (rc == INKPOT_SUCCESS);
-    fprintf(stdout, " %d,%d,%d,%d\n",
+    fprintf(stdout, "\n rgba: %.3f,%.3f,%.3f,%.3f\n",
                rgba[0], rgba[1], rgba[2], rgba[3]);
 
+    rc = inkpot_get_hsva(inkpot, hsva);
+    assert (rc == INKPOT_SUCCESS);
+    fprintf(stdout, " hsva: %.3f,%.3f,%.3f,%.3f\n",
+               hsva[0], hsva[1], hsva[2], hsva[3]);
+
+    rc = inkpot_get_cmyk(inkpot, cmyk);
+    assert (rc == INKPOT_SUCCESS);
+    fprintf(stdout, " cmyk: %.3f,%.3f,%.3f,%.3f\n",
+               cmyk[0], cmyk[1], cmyk[2], cmyk[3]);
+
     return 0;
 }