aboutsummaryrefslogtreecommitdiff
path: root/generic/Color.c
diff options
context:
space:
mode:
authorlecoanet2003-05-16 14:10:06 +0000
committerlecoanet2003-05-16 14:10:06 +0000
commit8516442be4b957b4b3b03da857a6a1ea16263236 (patch)
tree012c8fb0ccce425f326ecec17cb5d1b1a5561547 /generic/Color.c
parent6506afb73161886d1e912f193ed42d3040a174de (diff)
downloadtkzinc-8516442be4b957b4b3b03da857a6a1ea16263236.zip
tkzinc-8516442be4b957b4b3b03da857a6a1ea16263236.tar.gz
tkzinc-8516442be4b957b4b3b03da857a6a1ea16263236.tar.bz2
tkzinc-8516442be4b957b4b3b03da857a6a1ea16263236.tar.xz
Modification of gradient syntax to support vector style specification
Diffstat (limited to 'generic/Color.c')
-rw-r--r--generic/Color.c93
1 files changed, 73 insertions, 20 deletions
diff --git a/generic/Color.c b/generic/Color.c
index d0c3a81..c83631d 100644
--- a/generic/Color.c
+++ b/generic/Color.c
@@ -375,9 +375,30 @@ ZnDeleteGradientName(char *name)
*
* 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.
+ *
+ * If type = axial
+ * args := angle (0..360) | xs ys xe ye (reals)
+ *
+ * The first form define the axial gradiant by its slope.
+ * With this syntax the gradient fits the whole shape.
+ * This is a backward compatible syntax.
+ * The second form specifies a vector which will be used
+ * to draw the gradient. The vector defines both the angle
+ * and the gradient area. Parts of the shape that lie before
+ * the vector origin are filled with the first color and
+ * parts that lie after the vector end are filled with the
+ * last color.
+ *
+ * If type = radial or path
+ * args := xs ys [xe ye] (reals)
+ *
+ * The vector specified by the 4 coordinates defines the
+ * gradient area. Parts of the shape that lie before
+ * the vector origin are filled with the first color and
+ * parts that lie after the vector end are filled with the
+ * last color. The vector end may be omitted, in such case
+ * the gradient fits exactly the whole shape to be filled,
+ * this is backward compatible with older gradients.
*
* color := colorvalue | colorvalue position |
* colorvalue control position
@@ -388,7 +409,7 @@ ZnDeleteGradientName(char *name)
*
* Results:
* The return value is a token for a data structure
- * describing a gradient. This token may be passed
+ * describing a gradient. This token may be passed
* to the drawing routines.
* If an error prevented the gradient from being created
* then NULL is returned and an error message will be
@@ -409,6 +430,30 @@ ZnGetGradientByValue(ZnGradient *grad)
}
+static int
+ParseRealList(const char *str,
+ const char *stop,
+ ZnReal *list,
+ int max)
+{
+ int num;
+ char *end;
+
+ num = 0;
+ while ((num < max) && (str != stop)) {
+ list[num] = strtod(str, &end);
+ if (end == str) {
+ /* A syntax error occured, return a 0 count
+ * as a hint for the caller.
+ */
+ return 0;
+ }
+ num++;
+ str = end+strspn(end, " \t");
+ }
+ return num;
+}
+
ZnGradient *
ZnGetGradient(Tcl_Interp *interp,
Tk_Window tkwin,
@@ -418,11 +463,11 @@ ZnGetGradient(Tcl_Interp *interp,
Tcl_HashEntry *hash;
ZnGradient *grad;
unsigned int i, j, nspace, num_colors;
- unsigned int size;
+ unsigned int size, num_coords;
char type;
char const *scan_ptr, *next_ptr, *str_ptr;
int angle, position, control;
- double x=0, y=0;
+ ZnReal coords[4];
char *color_ptr, *end, segment[SEGMENT_SIZE];
ZnGradientColor *first, *last;
XColor color;
@@ -495,14 +540,13 @@ ZnGetGradient(Tcl_Interp *interp,
scan_ptr++;
if ((*scan_ptr == 'a') && (strncmp(scan_ptr, "axial", 5) == 0)) {
scan_ptr += 5;
- angle = strtol(scan_ptr, &end, 10);
- nspace = strspn(end, " \t");
- if ((end+nspace) != next_ptr) {
+ if (ParseRealList(scan_ptr, next_ptr, coords, 1) != 1) {
grad_err3:
Tcl_AppendResult(interp, "invalid gradient parameter \"",
desc, "\",", NULL);
goto grad_err1;
}
+ angle = (int) coords[0];
}
else if (((*scan_ptr == 'r') && (strncmp(scan_ptr, "radial", 6) == 0)) ||
((*scan_ptr == 'p') && (strncmp(scan_ptr, "path", 4) == 0))) {
@@ -514,14 +558,8 @@ ZnGetGradient(Tcl_Interp *interp,
type = ZN_PATH_GRADIENT;
scan_ptr += 4;
}
- x = strtod(scan_ptr, &end);
- if (end == scan_ptr) {
- goto grad_err3;
- }
- scan_ptr = end;
- y = strtod(scan_ptr, &end);
- nspace = strspn(end, " \t");
- if ((end+nspace) != next_ptr) {
+ num_coords = ParseRealList(scan_ptr, next_ptr, coords, 4);
+ if ((num_coords != 2) && (num_coords != 4)) {
goto grad_err3;
}
}
@@ -539,14 +577,29 @@ ZnGetGradient(Tcl_Interp *interp,
grad = (ZnGradient *) ZnMalloc(sizeof(ZnGradient) +
sizeof(ZnGradientColor)*(num_colors-1));
grad->ref_count = 1;
+ grad->simple = True;
grad->num_colors = num_colors;
grad->type = type;
if (type == ZN_AXIAL_GRADIENT) {
- grad->g.angle = angle;
+ if (num_coords == 4) {
+ grad->simple = False;
+ grad->g.p.x = coords[0];
+ grad->g.p.y = coords[1];
+ grad->e.x = coords[2];
+ grad->e.y = coords[3];
+ }
+ else {
+ grad->g.angle = angle;
+ }
}
else {
- grad->g.p.x = x;
- grad->g.p.y = y;
+ grad->g.p.x = coords[0];
+ grad->g.p.y = coords[1];
+ if (num_coords == 4) {
+ grad->simple = False;
+ grad->e.x = coords[2];
+ grad->e.y = coords[3];
+ }
}
grad->hash = hash;
Tcl_SetHashValue(hash, grad);