static int LinTransitionSet( ClientData clientData, Tcl_Interp *interp, /* Current interp; may be used for errors. */ Tk_Window tkwin, /* Window for which option is being set. */ Tcl_Obj **value, /* Pointer to the pointer to the value object. * We use a pointer to the pointer because * we may need to return a value (NULL). */ char *recordPtr, /* Pointer to storage for the widget record. */ int internalOffset, /* Offset within *recordPtr at which the * internal value is to be stored. */ char *oldInternalPtr, /* Pointer to storage for the old value. */ int flags) /* Flags for the option, set Tk_SetOptions. */ { char *internalPtr; int objEmpty = 0; Tcl_Obj *valuePtr; double z[4] = {0.0, 0.0, 1.0, 0.0}; /* Defaults according to SVG. */ PathRect *newrc = NULL; valuePtr = *value; internalPtr = ComputeSlotAddress(recordPtr, internalOffset); objEmpty = ObjectIsEmpty(valuePtr); /* * Important: the new value for the transition is not yet * stored into the style! transObj may be NULL! * The new value is stored in style *after* we return TCL_OK. */ if ((flags & TK_OPTION_NULL_OK) && objEmpty) { valuePtr = NULL; } else { int i, len; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, valuePtr, &len, &objv) != TCL_OK) { return TCL_ERROR; } if (len != 4) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-lineartransition must have four elements", -1)); return TCL_ERROR; } for (i = 0; i < 4; i++) { if (Tcl_GetDoubleFromObj(interp, objv[i], z+i) != TCL_OK) { return TCL_ERROR; } } newrc = (PathRect *) ckalloc(sizeof(PathRect)); newrc->x1 = z[0]; newrc->y1 = z[1]; newrc->x2 = z[2]; newrc->y2 = z[3]; } if (internalPtr != NULL) { *((PathRect **) oldInternalPtr) = *((PathRect **) internalPtr); *((PathRect **) internalPtr) = newrc; } return TCL_OK; }
static int RadTransitionSet( ClientData clientData, Tcl_Interp *interp, /* Current interp; may be used for errors. */ Tk_Window tkwin, /* Window for which option is being set. */ Tcl_Obj **value, /* Pointer to the pointer to the value object. * We use a pointer to the pointer because * we may need to return a value (NULL). */ char *recordPtr, /* Pointer to storage for the widget record. */ int internalOffset, /* Offset within *recordPtr at which the internal value is to be stored. */ char *oldInternalPtr, /* Pointer to storage for the old value. */ int flags) /* Flags for the option, set Tk_SetOptions. */ { char *internalPtr; int objEmpty = 0; Tcl_Obj *valuePtr; double z[5] = {0.5, 0.5, 0.5, 0.5, 0.5}; RadialTransition *newrc = NULL; valuePtr = *value; internalPtr = ComputeSlotAddress(recordPtr, internalOffset); objEmpty = ObjectIsEmpty(valuePtr); if ((flags & TK_OPTION_NULL_OK) && objEmpty) { valuePtr = NULL; } else { int i, len; Tcl_Obj **objv; if (Tcl_ListObjGetElements(interp, valuePtr, &len, &objv) != TCL_OK) { return TCL_ERROR; } if ((len == 1) || (len == 4) || (len > 5)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-radialtransition must be a list {cx cy ?r? ?fx fy?}", -1)); return TCL_ERROR; } for (i = 0; i < len; i++) { if (Tcl_GetDoubleFromObj(interp, objv[i], z+i) != TCL_OK) { return TCL_ERROR; } } newrc = (RadialTransition *) ckalloc(sizeof(RadialTransition)); newrc->centerX = z[0]; newrc->centerY = z[1]; newrc->radius = z[2]; newrc->focalX = z[3]; newrc->focalY = z[4]; } if (internalPtr != NULL) { *((RadialTransition **) oldInternalPtr) = *((RadialTransition **) internalPtr); *((RadialTransition **) internalPtr) = newrc; } return TCL_OK; }
void PathGradientPaint(TkPathContext ctx, PathRect *bbox, TkPathGradientMaster *gradientPtr, int fillRule) { if (!ObjectIsEmpty(gradientPtr->stopsObj)) { if (gradientPtr->type == kPathGradientTypeLinear) { TkPathPaintLinearGradient(ctx, bbox, &gradientPtr->linearFill, fillRule, gradientPtr->matrixPtr); } else { TkPathPaintRadialGradient(ctx, bbox, &gradientPtr->radialFill, fillRule, gradientPtr->matrixPtr); } } }
int MatrixSetOption( ClientData clientData, Tcl_Interp *interp, /* Current interp; may be used for errors. */ Tk_Window tkwin, /* Window for which option is being set. */ Tcl_Obj **value, /* Pointer to the pointer to the value object. * We use a pointer to the pointer because * we may need to return a value (NULL). */ char *recordPtr, /* Pointer to storage for the widget record. */ int internalOffset, /* Offset within *recordPtr at which the internal value is to be stored. */ char *oldInternalPtr, /* Pointer to storage for the old value. */ int flags) /* Flags for the option, set Tk_SetOptions. */ { char *internalPtr; /* Points to location in record where * internal representation of value should * be stored, or NULL. */ char *list; int length; Tcl_Obj *valuePtr; TMatrix *newPtr; valuePtr = *value; if (internalOffset >= 0) { internalPtr = recordPtr + internalOffset; } else { internalPtr = NULL; } if ((flags & TK_OPTION_NULL_OK) && ObjectIsEmpty(valuePtr)) { valuePtr = NULL; } if (internalPtr != NULL) { if (valuePtr != NULL) { list = Tcl_GetStringFromObj(valuePtr, &length); newPtr = (TMatrix *) ckalloc(sizeof(TMatrix)); if (PathGetTMatrix(interp, list, newPtr) != TCL_OK) { ckfree((char *) newPtr); return TCL_ERROR; } } else { newPtr = NULL; } *((TMatrix **) oldInternalPtr) = *((TMatrix **) internalPtr); *((TMatrix **) internalPtr) = newPtr; } return TCL_OK; }
int PathColorSetOption( ClientData clientData, Tcl_Interp *interp, /* Current interp; may be used for errors. */ Tk_Window tkwin, /* Window for which option is being set. */ Tcl_Obj **value, /* Pointer to the pointer to the value object. * We use a pointer to the pointer because * we may need to return a value (NULL). */ char *recordPtr, /* Pointer to storage for the widget record. */ int internalOffset, /* Offset within *recordPtr at which the internal value is to be stored. */ char *oldInternalPtr, /* Pointer to storage for the old value. */ int flags) /* Flags for the option, set Tk_SetOptions. */ { char *internalPtr; /* Points to location in record where * internal representation of value should * be stored, or NULL. */ Tcl_Obj *valuePtr; TkPathColor *newPtr = NULL; valuePtr = *value; if (internalOffset >= 0) { internalPtr = recordPtr + internalOffset; } else { internalPtr = NULL; } if ((flags & TK_OPTION_NULL_OK) && ObjectIsEmpty(valuePtr)) { valuePtr = NULL; } if (internalPtr != NULL) { if (valuePtr != NULL) { newPtr = TkPathNewPathColor(interp, tkwin, valuePtr); if (newPtr == NULL) { return TCL_ERROR; } } else { newPtr = NULL; } *((TkPathColor **) oldInternalPtr) = *((TkPathColor **) internalPtr); *((TkPathColor **) internalPtr) = newPtr; } return TCL_OK; }
/* * The stops are a list of stop lists where each stop list is: * {offset color ?opacity?} */ static int StopsSet( ClientData clientData, Tcl_Interp *interp, /* Current interp; may be used for errors. */ Tk_Window tkwin, /* Window for which option is being set. */ Tcl_Obj **value, /* Pointer to the pointer to the value object. * We use a pointer to the pointer because * we may need to return a value (NULL). */ char *recordPtr, /* Pointer to storage for the widget record. */ int internalOffset, /* Offset within *recordPtr at which the internal value is to be stored. */ char *oldInternalPtr, /* Pointer to storage for the old value. */ int flags) /* Flags for the option, set Tk_SetOptions. */ { char *internalPtr; int i, nstops, stopLen; int objEmpty = 0; Tcl_Obj *valuePtr; double offset, lastOffset, opacity; Tcl_Obj **objv; Tcl_Obj *stopObj; Tcl_Obj *obj; XColor *color; GradientStopArray *newrc = NULL; valuePtr = *value; internalPtr = ComputeSlotAddress(recordPtr, internalOffset); objEmpty = ObjectIsEmpty(valuePtr); if ((flags & TK_OPTION_NULL_OK) && objEmpty) { valuePtr = NULL; } else { /* Deal with each stop list in turn. */ if (Tcl_ListObjGetElements(interp, valuePtr, &nstops, &objv) != TCL_OK) { return TCL_ERROR; } newrc = NewGradientStopArray(nstops); lastOffset = 0.0; for (i = 0; i < nstops; i++) { stopObj = objv[i]; if (Tcl_ListObjLength(interp, stopObj, &stopLen) != TCL_OK) { goto error; } if ((stopLen == 2) || (stopLen == 3)) { Tcl_ListObjIndex(interp, stopObj, 0, &obj); if (Tcl_GetDoubleFromObj(interp, obj, &offset) != TCL_OK) { goto error; } if ((offset < 0.0) || (offset > 1.0)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "stop offsets must be in the range 0.0 to 1.0", -1)); goto error; } if (offset < lastOffset) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "stop offsets must be ordered", -1)); goto error; } Tcl_ListObjIndex(interp, stopObj, 1, &obj); color = Tk_AllocColorFromObj(interp, Tk_MainWindow(interp), obj); if (color == NULL) { Tcl_AppendResult(interp, "color \"", Tcl_GetStringFromObj(obj, NULL), "\" doesn't exist", NULL); goto error; } if (stopLen == 3) { Tcl_ListObjIndex(interp, stopObj, 2, &obj); if (Tcl_GetDoubleFromObj(interp, obj, &opacity) != TCL_OK) { goto error; } } else { opacity = 1.0; } /* Make new stop. */ newrc->stops[i] = NewGradientStop(offset, color, opacity); lastOffset = offset; } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( "stop list not {offset color ?opacity?}", -1)); goto error; } } } if (internalPtr != NULL) { *((GradientStopArray **) oldInternalPtr) = *((GradientStopArray **) internalPtr); *((GradientStopArray **) internalPtr) = newrc; } return TCL_OK; error: if (newrc != NULL) { FreeStopArray(newrc); } return TCL_ERROR; }