INKPOT_FAIL
} inkpot_status_t;
-/* opaque inkpot struct */
typedef struct inkpot_s inkpot_t;
-/* writer discipline */
typedef struct inkpot_disc_s {
size_t (*out_writer) (void *out_closure, const char *data, size_t length);
size_t (*err_writer) (void *err_closure, const char *data, size_t length);
} inkpot_disc_t;
-/* malloc an inkpot. */
-extern inkpot_t *inkpot_init ( void );
-/* Discplines default to stdout, stderr. Use this to provide other writers */
+
+extern inkpot_t * inkpot_init ( void );
+extern void inkpot_destroy ( inkpot_t *inkpot );
+
extern inkpot_status_t inkpot_disciplines ( inkpot_t *inkpot, inkpot_disc_t disc, void *out_closure, void *err_closure );
-/* The list of schemes for color input interpretation, NULL scheme terminates */
extern inkpot_status_t inkpot_schemes ( inkpot_t *inkpot, const char *scheme, ... );
-/* The scheme for color output representation, */
extern inkpot_status_t inkpot_translate ( inkpot_t *inkpot, const char *scheme );
-/* set inkpot color by name as interpeted by the current schemes */
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, double rgba[4] );
extern inkpot_status_t inkpot_set_hsva ( inkpot_t *inkpot, double hsva[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_i ( inkpot_t *inkpot, unsigned int rgba[4] );
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) */
-/* returns INKPOT_COLOR_NONAME if it converted the color to a hex numeric string value */
extern inkpot_status_t inkpot_write ( inkpot_t *inkpot );
-/* debugging and error functions that oput to the err_writer (default stderr) */
extern inkpot_status_t inkpot_debug_schemes ( inkpot_t *inkpot );
extern inkpot_status_t inkpot_debug_names ( inkpot_t *inkpot );
-extern inkpot_status_t inkpot_debug_names_out ( inkpot_t *inkpot );
+extern inkpot_status_t inkpot_debug_out_names ( inkpot_t *inkpot );
extern inkpot_status_t inkpot_debug_values ( inkpot_t *inkpot );
-/* write the most recent inkpot status to the err writer */
extern inkpot_status_t inkpot_error ( inkpot_t *inkpot );
#ifdef __cplusplus
inkpot = malloc(sizeof(inkpot_t));
if (inkpot) {
+ inkpot->canon = NULL;
+ inkpot->canon_alloc = 0;
+
inkpot->disc = inkpot_default_disc;
inkpot->out_closure = stdout;
inkpot->err_closure = stderr;
+
rc = inkpot_clear ( inkpot );
assert ( rc == INKPOT_SUCCESS );
}
return inkpot;
}
+void inkpot_destroy ( inkpot_t *inkpot )
+{
+ free(inkpot->canon);
+ free(inkpot);
+}
+
inkpot_status_t inkpot_disciplines ( inkpot_t *inkpot, inkpot_disc_t disc, void *out_closure, void *err_closure )
{
inkpot->disc = disc;
return ((inkpot->status = INKPOT_SUCCESS));
}
+/* FIXME - this needs to work with UTF-8 strings */
static int string_cmpf (const char *k, const char *b)
{
for ( ; *k && *b; k++, b++) {
inkpot_status_t inkpot_set( inkpot_t *inkpot, const char *color )
{
- static char *canon;
- static int allocated;
- char *q, c;
+ char *q;
const char *p;
int len, index;
- unsigned int rgba;
+ unsigned int rgba, c;
double hsva[4];
inkpot_status_t rc = INKPOT_COLOR_UNKNOWN;
if (!color)
return ((inkpot->status = INKPOT_COLOR_UNKNOWN));
- if (*color == '#') {
- if (sscanf(color, "#%8x", &rgba))
+ len = strlen(color);
+ if (len >= inkpot->canon_alloc) {
+ inkpot->canon_alloc = len + 1 + 20;
+ inkpot->canon = realloc(inkpot->canon, inkpot->canon_alloc);
+ if (! inkpot->canon)
+ return ((inkpot->status = INKPOT_MALLOC_FAIL));
+ }
+
+ /* canonicalize input string */
+ for (p = color, q = inkpot->canon;
+ (c = *p) && ( c == ' ' || c == '\t' );
+ p++) { }; /* remove leading ws */
+
+ /* change ',' to ' ' */
+ /* FIXME - is this UTF-8 safe ? */
+ while ((c = *p++)) {
+ if (c == ',')
+ c = ' ';
+ *q++ = c;
+ }
+ *q = '\0';
+
+ if (*inkpot->canon == '#') {
+ if (sscanf(inkpot->canon, "#%8x", &rgba))
rc = inkpot_set_RGBA(inkpot, &rgba);
if (rc != INKPOT_SUCCESS) {
- if (sscanf(color, "#%6x", &rgba)) {
+ if (sscanf(inkpot->canon, "#%6x", &rgba)) {
rgba = (rgba << SZB_RED) | MAX_RED;
rc = inkpot_set_RGBA(inkpot, &rgba);
}
}
}
- if ((rc != INKPOT_SUCCESS) || ((c = *color) == '.') || isdigit(c)) {
- len = strlen(color);
- if (len >= allocated) {
- allocated = len + 1 + 10;
- canon = realloc(canon, allocated);
- if (! canon)
- return ((inkpot->status = INKPOT_MALLOC_FAIL));
- }
- p = color;
- q = canon;
- while ((c = *p++)) {
- if (c == ',')
- c = ' ';
- *q++ = c;
- }
- *q = '\0';
+ if ((rc != INKPOT_SUCCESS) || ((c = *inkpot->canon) == '.') || isdigit(c)) {
hsva[3] = 1.0;
- if (sscanf(canon, "%lf%lf%lf%lf", &hsva[0], &hsva[1], &hsva[2], &hsva[3]) >= 3)
+ if (sscanf(inkpot->canon, "%lf%lf%lf%lf", &hsva[0], &hsva[1], &hsva[2], &hsva[3]) >= 3)
rc = inkpot_set_hsva(inkpot, hsva);
}
if (rc != INKPOT_SUCCESS)
- if (sscanf(color, "%d", &index) == 1)
+ if (sscanf(inkpot->canon, "%d", &index) == 1)
rc = inkpot_set_index(inkpot, index);
- if (rc != INKPOT_SUCCESS)
- rc = inkpot_set_name(inkpot, color);
+ if (rc != INKPOT_SUCCESS) {
+ /* remove embedded ws and convert to lower case*/
+ for (p = q = inkpot->canon;
+ (c = *p) && ! ( c == ' ' || c == '\t' ); p++) {
+ *q++ = tolower(c);
+ };
+ *q = '\0';
+ rc = inkpot_set_name(inkpot, inkpot->canon);
+ }
return rc;
}
return ((inkpot->status = INKPOT_SUCCESS));
}
+inkpot_status_t inkpot_get_rgba_i ( inkpot_t *inkpot, unsigned int rgba[4] )
+{
+ inkpot_status_t rc;
+ RGBA myrgba;
+
+ rc = inkpot_get_RGBA( inkpot, &myrgba );
+ if (rc == INKPOT_SUCCESS) {
+ rgba[3] = myrgba & MSK_RED; myrgba >>= SZB_RED;
+ rgba[2] = myrgba & MSK_RED; myrgba >>= SZB_RED;
+ rgba[1] = myrgba & MSK_RED; myrgba >>= SZB_RED;
+ rgba[0] = myrgba & MSK_RED;
+ }
+ return rc;
+}
+
inkpot_status_t inkpot_get_rgba ( inkpot_t *inkpot, double rgba[4] )
{
inkpot_status_t rc;
}
return rc;
}
+
inkpot_status_t inkpot_get_hsva ( inkpot_t *inkpot, double hsva[4] )
{
inkpot_status_t rc;
return inkpot_debug_names_schemes(inkpot, scheme_bits, scheme_index);
}
-inkpot_status_t inkpot_debug_names_out( inkpot_t *inkpot )
+inkpot_status_t inkpot_debug_out_names( inkpot_t *inkpot )
{
MSK_SCHEMES_NAME scheme_bits = inkpot->out_scheme_bit;
inkpot_scheme_index_t *scheme_index = inkpot->out_scheme_index;
}
}
-/* ------------- */
+#if 0
inkpot_debug_schemes(inkpot);
inkpot_debug_names(inkpot);
- inkpot_debug_names_out(inkpot);
+ inkpot_debug_out_names(inkpot);
inkpot_debug_values(inkpot);
-/* ------------- */
+#endif
- fprintf(stdout, "%s ", color);
+ fprintf(stdout, "%s ", color); /* ' ' after %s so it doesn't crash on NULL */
rc = inkpot_set(inkpot, color);
if (rc == INKPOT_COLOR_UNKNOWN) {
- fprintf(stdout, "(unknown)\n text: ");
+ fprintf(stdout, "(unknown)");
rc = inkpot_set_default(inkpot);
assert (rc == INKPOT_SUCCESS);
}
+ fprintf(stdout, "\n text: ");
rc = inkpot_write(inkpot);
assert (rc == INKPOT_SUCCESS || rc == INKPOT_COLOR_NONAME);
fprintf(stdout, " cmyk: %.3f,%.3f,%.3f,%.3f\n",
cmyk[0], cmyk[1], cmyk[2], cmyk[3]);
+ inkpot_destroy(inkpot);
return 0;
}