diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Color.c | 173 |
1 files changed, 105 insertions, 68 deletions
diff --git a/generic/Color.c b/generic/Color.c index 430033e..f23dc49 100644 --- a/generic/Color.c +++ b/generic/Color.c @@ -1000,7 +1000,7 @@ ZnGetReliefGradient(Tcl_Interp *interp, light_color.blue = MAX(tmp1, tmp2); buffer[0] = 0; - sprintf(color_name, "#%02x%02x%02x:%d|", + sprintf(color_name, "#%02x%02x%02x;%d|", dark_color.red/256, dark_color.green/256, dark_color.blue/256, alpha); red_range = (int) base->red - (int) dark_color.red; green_range = (int) base->green - (int) dark_color.green; @@ -1010,11 +1010,11 @@ ZnGetReliefGradient(Tcl_Interp *interp, color.red =(int) dark_color.red + red_range * j/RELIEF_STEPS; color.green = (int) dark_color.green + green_range * j/RELIEF_STEPS; color.blue = (int) dark_color.blue + blue_range * j/RELIEF_STEPS; - sprintf(color_name, "#%02x%02x%02x:%d %d|", + sprintf(color_name, "#%02x%02x%02x;%d %d|", color.red/256, color.green/256, color.blue/256, alpha, 50/RELIEF_STEPS*j); strcat(buffer, color_name); } - sprintf(color_name, "#%02x%02x%02x:%d 50|", + sprintf(color_name, "#%02x%02x%02x;%d 50|", base->red/256, base->green/256, base->blue/256, alpha); strcat(buffer, color_name); red_range = (int) light_color.red - (int) base->red; @@ -1024,11 +1024,11 @@ ZnGetReliefGradient(Tcl_Interp *interp, color.red = (int) base->red + red_range * j/RELIEF_STEPS; color.green = (int) base->green + green_range * j/RELIEF_STEPS; color.blue = (int) base->blue + blue_range * j/RELIEF_STEPS; - sprintf(color_name, "#%02x%02x%02x:%d %d|", + sprintf(color_name, "#%02x%02x%02x;%d %d|", color.red/256, color.green/256, color.blue/256, alpha, 50+50/RELIEF_STEPS*j); strcat(buffer, color_name); } - sprintf(color_name, "#%02x%02x%02x:%d", + sprintf(color_name, "#%02x%02x%02x;%d", light_color.red/256, light_color.green/256, light_color.blue/256, alpha); strcat(buffer, color_name); @@ -1123,6 +1123,24 @@ ZnDeleteGradientName(char *name) * Create a data structure containing a range of colors * used to display a gradient. * + * The gradient should have the following syntax: + * + * gradient := [graddesc|]color[|....|color] + * where the | are real characters not meta-syntax. + * + * graddesc := @type args + * where type := axial | radial | path + * args := angle if type = axial; angle in (0..360) + * args := x y if type = (radial| path); x and + * y being real valued. + * + * color := colorvalue | colorvalue position | + * colorvalue control position + * where position and control are in (0..100) + * + * colorvalue := (colorname | #rgb | cievalue)[;alpha] + * where alpha is in (0..100) + * * Results: * The return value is a token for a data structure * describing a gradient. This token may be passed @@ -1154,15 +1172,16 @@ ZnGetGradient(Tcl_Interp *interp, Tcl_HashEntry *hash; ZnGradient *grad; int i, j, new, num_colors; - char type, *scan_ptr; + char type; + char const *scan_ptr; int num_tok, angle, position, control; double x, y; char *color_ptr, color_name[COLOR_NAME_SIZE]; - char *buffer = NULL; ZnGradientColor *first, *last; XColor color; int red_range, green_range, blue_range; + /* printf("ZnGetGradient : %s\n", desc);*/ if (!desc || !*desc) { return NULL; } @@ -1185,56 +1204,77 @@ ZnGetGradient(Tcl_Interp *interp, /* * No satisfactory gradient exists yet. Initialize a new one. */ - if ((desc[0] == '/') || (desc[0] == '(') || (desc[0] == '[')) { - goto grad_err2; + type = ZN_AXIAL_GRADIENT; + angle = 0; + /* + * Skip the trailing spaces. + */ + while (*desc == ' ') { + desc++; + } + /* + * Count the sections in the description. It should give + * the number of colors plus may be the gradient description. + */ + scan_ptr = desc; + /* + * If the first section is the gradient description, start color + * counts up from zero. + */ + num_colors = (*scan_ptr == '@') ? 0 : 1; + while ((scan_ptr = strchr(scan_ptr, '|'))) { + num_colors++; + scan_ptr++; + } + if (num_colors == 0) { + Tcl_AppendResult(interp, "gradient should have at least one color \"", + desc, "\",", NULL); + grad_err1: + Tcl_DeleteHashEntry(hash); + /*printf("ZnGetGradient error : %s\n", desc);*/ + return NULL; } - - buffer = ZnMalloc(strlen(desc) + 1); - strcpy(buffer, desc); /* * Then look at the gradient type. */ - type = ZN_AXIAL_GRADIENT; - angle = 0; - if ((scan_ptr = strchr(buffer, '/'))) { - num_tok = sscanf(scan_ptr, "/%d", &angle); - if (num_tok != 1) { - grad_err2: - ZnFree(buffer); - Tcl_DeleteHashEntry(hash); - Tcl_AppendResult(interp, "incorrect gradient format \"", - desc, "\",", NULL); - return NULL; + scan_ptr = desc; + if (*scan_ptr == '@') { + scan_ptr++; + if ((*scan_ptr == 'a') && (strncmp(scan_ptr, "axial", 5) == 0)) { + scan_ptr += 5; + num_tok = sscanf(scan_ptr, "%d", &angle); + if (num_tok != 1) { + Tcl_AppendResult(interp, "invalid axial gradient parameter \"", + desc, "\",", NULL); + goto grad_err1; + } } - *scan_ptr = '\0'; - } - else if ((scan_ptr = strchr(buffer, '('))) { - num_tok = sscanf(scan_ptr, "(%lf %lf", (double *) &x, (double *) &y); - if (num_tok == 2) { + else if ((*scan_ptr == 'r') && (strncmp(scan_ptr, "radial", 6) == 0)) { + scan_ptr += 6; + num_tok = sscanf(scan_ptr, "%lf %lf", (double *) &x, (double *) &y); + if (num_tok != 2) { + Tcl_AppendResult(interp, "invalid radial gradient parameter \"", + desc, "\",", NULL); + goto grad_err1; + } type = ZN_RADIAL_GRADIENT; } - else { - goto grad_err2; - } - *scan_ptr = '\0'; - } - else if ((scan_ptr = strchr(buffer, '['))) { - num_tok = sscanf(scan_ptr, "[%lf %lf", (double *) &x, (double *) &y); - if (num_tok == 2) { + else if ((*scan_ptr == 'p') && (strncmp(scan_ptr, "path", 4) == 0)) { + scan_ptr += 4; + num_tok = sscanf(scan_ptr, "%lf %lf", (double *) &x, (double *) &y); + if (num_tok == 2) { + Tcl_AppendResult(interp, "invalid path gradient parameter \"", + desc, "\",", NULL); + goto grad_err1; + } type = ZN_PATH_GRADIENT; } else { - goto grad_err2; + Tcl_AppendResult(interp, "invalid gradient type \"", + desc, "\",", NULL); + goto grad_err1; } - *scan_ptr = '\0'; - } - /* - * Next count the colors. - */ - scan_ptr = buffer; - num_colors = 1; - while ((scan_ptr = strchr(scan_ptr, '|'))) { - num_colors++; + scan_ptr = strchr(scan_ptr, '|'); scan_ptr++; } /* @@ -1255,44 +1295,40 @@ ZnGetGradient(Tcl_Interp *interp, grad->hash = hash; Tcl_SetHashValue(hash, grad); - scan_ptr = strtok(buffer, "|"); for (i = 0; i < num_colors; i++) { grad->colors[i].position = 0; grad->colors[i].control = 50; grad->colors[i].alpha = 100; num_tok = sscanf(scan_ptr, "%s %d %d", color_name, &position, &control); - if (num_tok > 1) { - grad->colors[i].position = position; - } - if (num_tok > 2) { - grad->colors[i].control = control; - } if (num_tok == 0) { - Tcl_AppendResult(interp, "incorrect gradient format \"", + Tcl_AppendResult(interp, "incorrect color description in gradient \"", desc, "\",", NULL); - grad_err: - ZnFree(buffer); - Tcl_DeleteHashEntry(hash); + grad_err2: for (j = 0; j < i; j++) { ZnFreeColor(grad->colors[j].rgb); } ZnFree(grad); - return NULL; + goto grad_err1; + } + if (num_tok > 1) { + grad->colors[i].position = position; + } + if (num_tok > 2) { + grad->colors[i].control = control; } - color_ptr = strchr(color_name, ':'); + color_ptr = strchr(color_name, ';'); if (color_ptr) { *color_ptr = 0; } grad->colors[i].rgb = ZnGetColor(interp, tkwin, Tk_GetUid(color_name)); - if (color_ptr) { - *color_ptr = ':'; - } if (grad->colors[i].rgb == NULL) { - Tcl_AppendResult(interp, " in gradient,", NULL); - goto grad_err; + Tcl_AppendResult(interp, "incorrect color value in gradient \"", + desc, "\",", NULL); + goto grad_err2; } if (color_ptr) { - grad->colors[i].alpha = atoi(color_ptr+1); + color_ptr++; + grad->colors[i].alpha = atoi(color_ptr); } if (i == 0) { grad->colors[i].position = 0; @@ -1305,7 +1341,7 @@ ZnGetGradient(Tcl_Interp *interp, (grad->colors[i].position < grad->colors[i-1].position)) { Tcl_AppendResult(interp, "incorrect color position in gradient \"", desc, "\",", NULL); - goto grad_err; + goto grad_err2; } } if (grad->colors[i].control > 100) { @@ -1314,9 +1350,9 @@ ZnGetGradient(Tcl_Interp *interp, if (grad->colors[i].alpha > 100) { grad->colors[i].alpha = 100; } - scan_ptr = strtok(NULL, "|"); + scan_ptr = strchr(scan_ptr, '|'); + scan_ptr++; } - ZnFree(buffer); } /* @@ -1338,6 +1374,7 @@ ZnGetGradient(Tcl_Interp *interp, } grad->colors[grad->num_colors-1].mid_rgb = NULL; + /* printf("ZnGetGradient end : %s\n", desc);*/ return grad; } |