diff options
author | joye <joye> | 2014-02-25 17:47:52 (GMT) |
---|---|---|
committer | joye <joye> | 2014-02-25 17:47:52 (GMT) |
commit | b9f3b60fe28abc94aff915ae1ab934f20af8fe80 (patch) | |
tree | c89b0ab83909f2c123fa663ca73564171652f54b /src | |
parent | d7efe260d3ccad6deca25e7baf71f5befc4e44f2 (diff) | |
download | blt-b9f3b60fe28abc94aff915ae1ab934f20af8fe80.zip blt-b9f3b60fe28abc94aff915ae1ab934f20af8fe80.tar.gz blt-b9f3b60fe28abc94aff915ae1ab934f20af8fe80.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r-- | src/bltGrAxis.C | 6653 | ||||
-rw-r--r-- | src/bltGrElemBar.C | 10 | ||||
-rw-r--r-- | src/bltGrElemLine.C | 125 | ||||
-rw-r--r-- | src/bltGrElemOp.C | 16 | ||||
-rw-r--r-- | src/bltGrElemOp.h | 161 |
5 files changed, 3489 insertions, 3476 deletions
diff --git a/src/bltGrAxis.C b/src/bltGrAxis.C index b44c31b..9bc1f1e 100644 --- a/src/bltGrAxis.C +++ b/src/bltGrAxis.C @@ -58,7 +58,7 @@ * accuracy used when outputting axis * tick labels. */ enum TickRange { - AXIS_TIGHT, AXIS_LOOSE, AXIS_ALWAYS_LOOSE + AXIS_TIGHT, AXIS_LOOSE, AXIS_ALWAYS_LOOSE }; #define AXIS_PAD_TITLE 2 /* Padding for axis title. */ @@ -79,69 +79,126 @@ enum TickRange { #define HORIZMARGIN(m) (!((m)->site & 0x1)) /* Even sites are horizontal */ typedef struct { - int axis; /* Length of the axis. */ - int t1; /* Length of a major tick (in + int axis; /* Length of the axis. */ + int t1; /* Length of a major tick (in * pixels). */ - int t2; /* Length of a minor tick (in + int t2; /* Length of a minor tick (in * pixels). */ - int label; /* Distance from axis to tick label. */ + int label; /* Distance from axis to tick label. */ } AxisInfo; typedef struct { - const char *name; - ClassId classId; - int margin, invertMargin; + const char *name; + ClassId classId; + int margin, invertMargin; } AxisName; static AxisName axisNames[] = { - { "x", CID_AXIS_X, MARGIN_BOTTOM, MARGIN_LEFT }, - { "y", CID_AXIS_Y, MARGIN_LEFT, MARGIN_BOTTOM }, - { "x2", CID_AXIS_X, MARGIN_TOP, MARGIN_RIGHT }, - { "y2", CID_AXIS_Y, MARGIN_RIGHT, MARGIN_TOP } + { "x", CID_AXIS_X, MARGIN_BOTTOM, MARGIN_LEFT }, + { "y", CID_AXIS_Y, MARGIN_LEFT, MARGIN_BOTTOM }, + { "x2", CID_AXIS_X, MARGIN_TOP, MARGIN_RIGHT }, + { "y2", CID_AXIS_Y, MARGIN_RIGHT, MARGIN_TOP } } ; static int nAxisNames = sizeof(axisNames) / sizeof(AxisName); +static void ReleaseAxis(Axis *axisPtr); +static int GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, + ClassId classId, Axis **axisPtrPtr); + +//*** + +static Tk_CustomOptionSetProc AxisSetProc; +static Tk_CustomOptionGetProc AxisGetProc; +Tk_ObjCustomOption xAxisObjOption = + { + "xaxis", AxisSetProc, AxisGetProc, NULL, NULL, (ClientData)CID_AXIS_X + }; +Tk_ObjCustomOption yAxisObjOption = + { + "yaxis", AxisSetProc, AxisGetProc, NULL, NULL, (ClientData)CID_AXIS_Y + }; + +static int AxisSetProc(ClientData clientData, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec, + int offset, char* save, int flags) +{ + Axis** axisPtrPtr = (Axis**)(widgRec + offset); + + if (flags & BLT_CONFIG_NULL_OK) { + const char* string; + + string = Tcl_GetString(*objPtr); + if (string[0] == '\0') { + ReleaseAxis(*axisPtrPtr); + *axisPtrPtr = NULL; + return TCL_OK; + } + } + + Graph* graphPtr = Blt_GetGraphFromWindowData(tkwin); + ClassId classId = (ClassId)clientData; + Axis* axisPtr; + if (GetAxisByClass(interp, graphPtr, *objPtr, classId, &axisPtr) != TCL_OK) + return TCL_ERROR; + + ReleaseAxis(*axisPtrPtr); + *axisPtrPtr = axisPtr; + + return TCL_OK; +}; + +static Tcl_Obj* AxisGetProc(ClientData clientData, Tk_Window tkwin, + char *widgRec, int offset) +{ + Axis*axisPtr = *(Axis**)(widgRec + offset); + const char *name = (axisPtr == NULL) ? "" : axisPtr->obj.name; + + return Tcl_NewStringObj(name, -1); +}; + +//*** + static Blt_OptionParseProc ObjToLimitProc; static Blt_OptionPrintProc LimitToObjProc; static Blt_CustomOption limitOption = { - ObjToLimitProc, LimitToObjProc, NULL, (ClientData)0 + ObjToLimitProc, LimitToObjProc, NULL, (ClientData)0 }; static Blt_OptionFreeProc FreeTicksProc; static Blt_OptionParseProc ObjToTicksProc; static Blt_OptionPrintProc TicksToObjProc; static Blt_CustomOption majorTicksOption = { - ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MAJOR, + ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MAJOR, }; static Blt_CustomOption minorTicksOption = { - ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MINOR, + ObjToTicksProc, TicksToObjProc, FreeTicksProc, (ClientData)AXIS_AUTO_MINOR, }; static Blt_OptionFreeProc FreeAxisProc; static Blt_OptionPrintProc AxisToObjProc; static Blt_OptionParseProc ObjToAxisProc; Blt_CustomOption bltXAxisOption = { - ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_X + ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_X }; Blt_CustomOption bltYAxisOption = { - ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_Y + ObjToAxisProc, AxisToObjProc, FreeAxisProc, (ClientData)CID_AXIS_Y }; static Blt_OptionFreeProc FreeFormatProc; static Blt_OptionParseProc ObjToFormatProc; static Blt_OptionPrintProc FormatToObjProc; static Blt_CustomOption formatOption = { - ObjToFormatProc, FormatToObjProc, FreeFormatProc, (ClientData)0, + ObjToFormatProc, FormatToObjProc, FreeFormatProc, (ClientData)0, }; static Blt_OptionParseProc ObjToLooseProc; static Blt_OptionPrintProc LooseToObjProc; static Blt_CustomOption looseOption = { - ObjToLooseProc, LooseToObjProc, NULL, (ClientData)0, + ObjToLooseProc, LooseToObjProc, NULL, (ClientData)0, }; static Blt_OptionParseProc ObjToUseProc; static Blt_OptionPrintProc UseToObjProc; static Blt_CustomOption useOption = { - ObjToUseProc, UseToObjProc, NULL, (ClientData)0 + ObjToUseProc, UseToObjProc, NULL, (ClientData)0 }; #define DEF_AXIS_ACTIVEBACKGROUND STD_ACTIVE_BACKGROUND @@ -189,6 +246,7 @@ static Blt_CustomOption useOption = { #define DEF_AXIS_X_STEP_BARCHART "1.0" #define DEF_AXIS_X_SUBDIVISIONS_BARCHART "0" +/* static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", @@ -298,38 +356,38 @@ static Tk_OptionSpec optionSpecs[] = { -1, Tk_Offset(Axis, titleFont), 0, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; - +*/ // *** Blt_CustomOption bitmaskGrAxisCheckLimitsOption = -{ - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_CHECK_LIMITS -}; + { + ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_CHECK_LIMITS + }; Blt_CustomOption bitmaskGrAxisExteriorOption = -{ - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_EXTERIOR -}; + { + ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_EXTERIOR + }; Blt_CustomOption bitmaskGrAxisGridOption = -{ - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_GRID -}; + { + ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_GRID + }; Blt_CustomOption bitmaskGrAxisGridMinorOption = -{ - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_GRIDMINOR -}; + { + ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_GRIDMINOR + }; Blt_CustomOption bitmaskGrAxisHideOption = -{ - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)HIDE -}; + { + ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)HIDE + }; Blt_CustomOption bitmaskGrAxisShowTicksOption = -{ - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_SHOWTICKS -}; + { + ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)AXIS_SHOWTICKS + }; static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_COLOR, "-activeforeground", "activeForeground", @@ -442,7 +500,7 @@ static Blt_ConfigSpec configSpecs[] = { {BLT_CONFIG_CUSTOM, "-scrollcommand", "scrollCommand", "ScrollCommand", (char *)NULL, Tk_Offset(Axis, scrollCmdObjPtr), ALL_GRAPHS | BLT_CONFIG_NULL_OK, - &objectOption}, + &objectOption}, {BLT_CONFIG_PIXELS, "-scrollincrement", "scrollIncrement", "ScrollIncrement", DEF_AXIS_SCROLL_INCREMENT, Tk_Offset(Axis, scrollUnits), ALL_GRAPHS|BLT_CONFIG_DONT_SET_DEFAULT}, @@ -494,38 +552,36 @@ static Blt_ConfigSpec configSpecs[] = { /* Forward declarations */ static void DestroyAxis(Axis *axisPtr); static Tcl_FreeProc FreeAxis; -static int GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, - ClassId classId, Axis **axisPtrPtr); static void TimeScaleAxis(Axis *axisPtr, double min, double max); static int lastMargin; typedef int (GraphAxisProc)(Tcl_Interp *interp, Axis *axisPtr, int objc, - Tcl_Obj *const *objv); + Tcl_Obj *const *objv); typedef int (GraphVirtualAxisProc)(Tcl_Interp *interp, Graph *graphPtr, - int objc, Tcl_Obj *const *objv); + int objc, Tcl_Obj *const *objv); INLINE static double Clamp(double x) { - return (x < 0.0) ? 0.0 : (x > 1.0) ? 1.0 : x; + return (x < 0.0) ? 0.0 : (x > 1.0) ? 1.0 : x; } INLINE static int Round(double x) { - return (int) (x + ((x < 0.0) ? -0.5 : 0.5)); + return (int) (x + ((x < 0.0) ? -0.5 : 0.5)); } static void SetAxisRange(AxisRange *rangePtr, double min, double max) { - rangePtr->min = min; - rangePtr->max = max; - rangePtr->range = max - min; - if (fabs(rangePtr->range) < DBL_EPSILON) { - rangePtr->range = 1.0; - } - rangePtr->scale = 1.0 / rangePtr->range; + rangePtr->min = min; + rangePtr->max = max; + rangePtr->range = max - min; + if (fabs(rangePtr->range) < DBL_EPSILON) { + rangePtr->range = 1.0; + } + rangePtr->scale = 1.0 / rangePtr->range; } /* @@ -551,155 +607,103 @@ SetAxisRange(AxisRange *rangePtr, double min, double max) INLINE static int InRange(double x, AxisRange *rangePtr) { - if (rangePtr->range < DBL_EPSILON) { - return (fabs(rangePtr->max - x) >= DBL_EPSILON); - } else { - double norm; - - norm = (x - rangePtr->min) * rangePtr->scale; - return ((norm >= -DBL_EPSILON) && ((norm - 1.0) < DBL_EPSILON)); - } + if (rangePtr->range < DBL_EPSILON) { + return (fabs(rangePtr->max - x) >= DBL_EPSILON); + } else { + double norm; + + norm = (x - rangePtr->min) * rangePtr->scale; + return ((norm >= -DBL_EPSILON) && ((norm - 1.0) < DBL_EPSILON)); + } } INLINE static int AxisIsHorizontal(Axis *axisPtr) { - Graph *graphPtr = axisPtr->obj.graphPtr; + Graph *graphPtr = axisPtr->obj.graphPtr; - return ((axisPtr->obj.classId == CID_AXIS_Y) == graphPtr->inverted); + return ((axisPtr->obj.classId == CID_AXIS_Y) == graphPtr->inverted); } - -static void -ReleaseAxis(Axis *axisPtr) +static void ReleaseAxis(Axis *axisPtr) { - if (axisPtr != NULL) { - axisPtr->refCount--; - assert(axisPtr->refCount >= 0); - if (axisPtr->refCount == 0) { - axisPtr->flags |= DELETE_PENDING; - Tcl_EventuallyFree(axisPtr, FreeAxis); - } + if (axisPtr != NULL) { + axisPtr->refCount--; + assert(axisPtr->refCount >= 0); + if (axisPtr->refCount == 0) { + axisPtr->flags |= DELETE_PENDING; + Tcl_EventuallyFree(axisPtr, FreeAxis); } + } } -/* - *----------------------------------------------------------------------------- - * Custom option parse and print procedures - *----------------------------------------------------------------------------- - */ - -/*ARGSUSED*/ -static void -FreeAxisProc( - ClientData clientData, /* Not used. */ - Display *display, /* Not used. */ - char *widgRec, - int offset) +static void FreeAxisProc(ClientData clientData, Display *display, + char *widgRec, int offset) { - Axis **axisPtrPtr = (Axis **)(widgRec + offset); + Axis **axisPtrPtr = (Axis **)(widgRec + offset); - if (*axisPtrPtr != NULL) { - ReleaseAxis(*axisPtrPtr); - *axisPtrPtr = NULL; - } + if (*axisPtrPtr != NULL) { + ReleaseAxis(*axisPtrPtr); + *axisPtrPtr = NULL; + } } -/* - *--------------------------------------------------------------------------- - * - * ObjToAxisProc -- - * - * Converts the name of an axis to a pointer to its axis structure. - * - * Results: - * The return value is a standard TCL result. The axis flags are written - * into the widget record. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static int -ObjToAxisProc( - ClientData clientData, /* Class identifier of the type of - * axis we are looking for. */ - Tcl_Interp *interp, /* Interpreter to report results. */ - Tk_Window tkwin, /* Used to look up pointer to graph. */ - Tcl_Obj *objPtr, /* String representing new value. */ - char *widgRec, /* Pointer to structure record. */ - int offset, /* Offset to field in structure */ - int flags) +static int ObjToAxisProc(ClientData clientData, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *objPtr, + char *widgRec, int offset, int flags) { - ClassId classId = (ClassId)clientData; - Axis **axisPtrPtr = (Axis **)(widgRec + offset); - Axis *axisPtr; - Graph *graphPtr; + ClassId classId = (ClassId)clientData; + Axis **axisPtrPtr = (Axis **)(widgRec + offset); + Axis *axisPtr; + Graph *graphPtr; - if (flags & BLT_CONFIG_NULL_OK) { - const char *string; + if (flags & BLT_CONFIG_NULL_OK) { + const char *string; - string = Tcl_GetString(objPtr); - if (string[0] == '\0') { - ReleaseAxis(*axisPtrPtr); - *axisPtrPtr = NULL; - return TCL_OK; - } - } - graphPtr = Blt_GetGraphFromWindowData(tkwin); - assert(graphPtr); - if (GetAxisByClass(interp, graphPtr, objPtr, classId, &axisPtr) - != TCL_OK) { - return TCL_ERROR; - } - ReleaseAxis(*axisPtrPtr); - *axisPtrPtr = axisPtr; - return TCL_OK; + string = Tcl_GetString(objPtr); + if (string[0] == '\0') { + ReleaseAxis(*axisPtrPtr); + *axisPtrPtr = NULL; + return TCL_OK; + } + } + graphPtr = Blt_GetGraphFromWindowData(tkwin); + assert(graphPtr); + if (GetAxisByClass(interp, graphPtr, objPtr, classId, &axisPtr) + != TCL_OK) { + return TCL_ERROR; + } + ReleaseAxis(*axisPtrPtr); + *axisPtrPtr = axisPtr; + return TCL_OK; } -/* - *--------------------------------------------------------------------------- - * - * AxisToObjProc -- - * - * Convert the window coordinates into a string. - * - * Results: - * The string representing the coordinate position is returned. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static Tcl_Obj * -AxisToObjProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Not used. */ - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* Pointer to structure record .*/ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ +static Tcl_Obj *AxisToObjProc(ClientData clientData, Tcl_Interp *interp, + Tk_Window tkwin, char *widgRec, + int offset, int flags) { - Axis *axisPtr = *(Axis **)(widgRec + offset); - const char *name; + Axis *axisPtr = *(Axis **)(widgRec + offset); + const char *name; - name = (axisPtr == NULL) ? "" : axisPtr->obj.name; - return Tcl_NewStringObj(name, -1); + name = (axisPtr == NULL) ? "" : axisPtr->obj.name; + return Tcl_NewStringObj(name, -1); } /*ARGSUSED*/ static void FreeFormatProc( - ClientData clientData, /* Not used. */ - Display *display, /* Not used. */ - char *widgRec, - int offset) /* Not used. */ + ClientData clientData, /* Not used. */ + Display *display, /* Not used. */ + char *widgRec, + int offset) /* Not used. */ { - Axis *axisPtr = (Axis *)(widgRec); + Axis *axisPtr = (Axis *)(widgRec); - if (axisPtr->limitsFormats != NULL) { - free(axisPtr->limitsFormats); - axisPtr->limitsFormats = NULL; - } - axisPtr->nFormats = 0; + if (axisPtr->limitsFormats != NULL) { + free(axisPtr->limitsFormats); + axisPtr->limitsFormats = NULL; + } + axisPtr->nFormats = 0; } @@ -719,33 +723,33 @@ FreeFormatProc( /*ARGSUSED*/ static int ObjToFormatProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interpreter to report results. */ - Tk_Window tkwin, /* Not used. */ - Tcl_Obj *objPtr, /* String representing new value. */ - char *widgRec, /* Pointer to structure record. */ - int offset, /* Not used. */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Interpreter to report results. */ + Tk_Window tkwin, /* Not used. */ + Tcl_Obj *objPtr, /* String representing new value. */ + char *widgRec, /* Pointer to structure record. */ + int offset, /* Not used. */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)(widgRec); - const char **argv; - int argc; + Axis *axisPtr = (Axis *)(widgRec); + const char **argv; + int argc; - if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, &argv) != TCL_OK) { - return TCL_ERROR; - } - if (argc > 2) { - Tcl_AppendResult(interp, "too many elements in limits format list \"", - Tcl_GetString(objPtr), "\"", (char *)NULL); - free(argv); - return TCL_ERROR; - } - if (axisPtr->limitsFormats != NULL) { - free(axisPtr->limitsFormats); - } - axisPtr->limitsFormats = argv; - axisPtr->nFormats = argc; - return TCL_OK; + if (Tcl_SplitList(interp, Tcl_GetString(objPtr), &argc, &argv) != TCL_OK) { + return TCL_ERROR; + } + if (argc > 2) { + Tcl_AppendResult(interp, "too many elements in limits format list \"", + Tcl_GetString(objPtr), "\"", (char *)NULL); + free(argv); + return TCL_ERROR; + } + if (axisPtr->limitsFormats != NULL) { + free(axisPtr->limitsFormats); + } + axisPtr->limitsFormats = argv; + axisPtr->nFormats = argc; + return TCL_OK; } /* @@ -763,26 +767,26 @@ ObjToFormatProc( /*ARGSUSED*/ static Tcl_Obj * FormatToObjProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Not used. */ - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* Widget record */ - int offset, /* Not used. */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Not used. */ + Tk_Window tkwin, /* Not used. */ + char *widgRec, /* Widget record */ + int offset, /* Not used. */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)(widgRec); - Tcl_Obj *objPtr; - - if (axisPtr->nFormats == 0) { - objPtr = Tcl_NewStringObj("", -1); - } else { - char *string; - - string = Tcl_Merge(axisPtr->nFormats, axisPtr->limitsFormats); - objPtr = Tcl_NewStringObj(string, -1); - free(string); - } - return objPtr; + Axis *axisPtr = (Axis *)(widgRec); + Tcl_Obj *objPtr; + + if (axisPtr->nFormats == 0) { + objPtr = Tcl_NewStringObj("", -1); + } else { + char *string; + + string = Tcl_Merge(axisPtr->nFormats, axisPtr->limitsFormats); + objPtr = Tcl_NewStringObj(string, -1); + free(string); + } + return objPtr; } /* @@ -802,25 +806,25 @@ FormatToObjProc( /*ARGSUSED*/ static int ObjToLimitProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interpreter to send results back - * to */ - Tk_Window tkwin, /* Not used. */ - Tcl_Obj *objPtr, /* String representing new value. */ - char *widgRec, /* Pointer to structure record. */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Interpreter to send results back + * to */ + Tk_Window tkwin, /* Not used. */ + Tcl_Obj *objPtr, /* String representing new value. */ + char *widgRec, /* Pointer to structure record. */ + int offset, /* Offset to field in structure */ + int flags) /* Not used. */ { - double *limitPtr = (double *)(widgRec + offset); - const char *string; + double *limitPtr = (double *)(widgRec + offset); + const char *string; - string = Tcl_GetString(objPtr); - if (string[0] == '\0') { - *limitPtr = NAN; - } else if (Blt_ExprDoubleFromObj(interp, objPtr, limitPtr) != TCL_OK) { - return TCL_ERROR; - } - return TCL_OK; + string = Tcl_GetString(objPtr); + if (string[0] == '\0') { + *limitPtr = NAN; + } else if (Blt_ExprDoubleFromObj(interp, objPtr, limitPtr) != TCL_OK) { + return TCL_ERROR; + } + return TCL_OK; } /* @@ -838,22 +842,22 @@ ObjToLimitProc( /*ARGSUSED*/ static Tcl_Obj * LimitToObjProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Not used. */ - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Not used. */ + Tk_Window tkwin, /* Not used. */ + char *widgRec, /* */ + int offset, /* Offset to field in structure */ + int flags) /* Not used. */ { - double limit = *(double *)(widgRec + offset); - Tcl_Obj *objPtr; - - if (!isnan(limit)) { - objPtr = Tcl_NewDoubleObj(limit); - } else { - objPtr = Tcl_NewStringObj("", -1); - } - return objPtr; + double limit = *(double *)(widgRec + offset); + Tcl_Obj *objPtr; + + if (!isnan(limit)) { + objPtr = Tcl_NewDoubleObj(limit); + } else { + objPtr = Tcl_NewStringObj("", -1); + } + return objPtr; } /* @@ -873,72 +877,72 @@ LimitToObjProc( /*ARGSUSED*/ static int ObjToUseProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interpreter to send results. */ - Tk_Window tkwin, /* Not used. */ - Tcl_Obj *objPtr, /* String representing new value. */ - char *widgRec, /* Pointer to structure record. */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Interpreter to send results. */ + Tk_Window tkwin, /* Not used. */ + Tcl_Obj *objPtr, /* String representing new value. */ + char *widgRec, /* Pointer to structure record. */ + int offset, /* Offset to field in structure */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)(widgRec); - AxisName *p, *pend; - Blt_Chain chain; - Graph *graphPtr; - const char *string; - int margin; - - graphPtr = axisPtr->obj.graphPtr; - if (axisPtr->refCount == 0) { - /* Clear the axis class if it's not currently used by an element.*/ - Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); - } - /* Remove the axis from the margin's use list and clear its use flag. */ - if (axisPtr->link != NULL) { - Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link); - } - axisPtr->flags &= ~AXIS_USE; - string = Tcl_GetString(objPtr); - if ((string == NULL) || (string[0] == '\0')) { - goto done; - } - for (p = axisNames, pend = axisNames + nAxisNames; p < pend; p++) { - if (strcmp(p->name, string) == 0) { - break; /* Found the axis name. */ - } - } - if (p == pend) { - Tcl_AppendResult(interp, "unknown axis type \"", string, "\": " - "should be x, y, x1, y2, or \"\".", (char *)NULL); - return TCL_ERROR; - } - /* Check the axis class. Can't use the axis if it's already being used as - * another type. */ - if (axisPtr->obj.classId == CID_NONE) { - Blt_GraphSetObjectClass(&axisPtr->obj, p->classId); - } else if (axisPtr->obj.classId != p->classId) { - Tcl_AppendResult(interp, "wrong type for axis \"", - axisPtr->obj.name, "\": can't use ", - axisPtr->obj.className, " type axis.", (char *)NULL); - return TCL_ERROR; - } - margin = (graphPtr->inverted) ? p->invertMargin : p->margin; - chain = graphPtr->margins[margin].axes; - if (axisPtr->link != NULL) { - /* Move the axis from the old margin's "use" list to the new. */ - Blt_Chain_AppendLink(chain, axisPtr->link); - } else { - axisPtr->link = Blt_Chain_Append(chain, axisPtr); - } - axisPtr->chain = chain; - axisPtr->flags |= AXIS_USE; - axisPtr->margin = margin; + Axis *axisPtr = (Axis *)(widgRec); + AxisName *p, *pend; + Blt_Chain chain; + Graph *graphPtr; + const char *string; + int margin; + + graphPtr = axisPtr->obj.graphPtr; + if (axisPtr->refCount == 0) { + /* Clear the axis class if it's not currently used by an element.*/ + Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); + } + /* Remove the axis from the margin's use list and clear its use flag. */ + if (axisPtr->link != NULL) { + Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link); + } + axisPtr->flags &= ~AXIS_USE; + string = Tcl_GetString(objPtr); + if ((string == NULL) || (string[0] == '\0')) { + goto done; + } + for (p = axisNames, pend = axisNames + nAxisNames; p < pend; p++) { + if (strcmp(p->name, string) == 0) { + break; /* Found the axis name. */ + } + } + if (p == pend) { + Tcl_AppendResult(interp, "unknown axis type \"", string, "\": " + "should be x, y, x1, y2, or \"\".", (char *)NULL); + return TCL_ERROR; + } + /* Check the axis class. Can't use the axis if it's already being used as + * another type. */ + if (axisPtr->obj.classId == CID_NONE) { + Blt_GraphSetObjectClass(&axisPtr->obj, p->classId); + } else if (axisPtr->obj.classId != p->classId) { + Tcl_AppendResult(interp, "wrong type for axis \"", + axisPtr->obj.name, "\": can't use ", + axisPtr->obj.className, " type axis.", (char *)NULL); + return TCL_ERROR; + } + margin = (graphPtr->inverted) ? p->invertMargin : p->margin; + chain = graphPtr->margins[margin].axes; + if (axisPtr->link != NULL) { + /* Move the axis from the old margin's "use" list to the new. */ + Blt_Chain_AppendLink(chain, axisPtr->link); + } else { + axisPtr->link = Blt_Chain_Append(chain, axisPtr); + } + axisPtr->chain = chain; + axisPtr->flags |= AXIS_USE; + axisPtr->margin = margin; done: - graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); - /* When any axis changes, we need to layout the entire graph. */ - graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; + graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); + /* When any axis changes, we need to layout the entire graph. */ + graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); + Blt_EventuallyRedrawGraph(graphPtr); + return TCL_OK; } /* @@ -956,39 +960,39 @@ ObjToUseProc( /*ARGSUSED*/ static Tcl_Obj * UseToObjProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Not used. */ - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Not used. */ + Tk_Window tkwin, /* Not used. */ + char *widgRec, /* */ + int offset, /* Offset to field in structure */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)(widgRec); + Axis *axisPtr = (Axis *)(widgRec); - if (axisPtr->margin == MARGIN_NONE) { - return Tcl_NewStringObj("", -1); - } - return Tcl_NewStringObj(axisNames[axisPtr->margin].name, -1); + if (axisPtr->margin == MARGIN_NONE) { + return Tcl_NewStringObj("", -1); + } + return Tcl_NewStringObj(axisNames[axisPtr->margin].name, -1); } /*ARGSUSED*/ static void FreeTicksProc( - ClientData clientData, /* Either AXIS_AUTO_MAJOR or - * AXIS_AUTO_MINOR. */ - Display *display, /* Not used. */ - char *widgRec, - int offset) + ClientData clientData, /* Either AXIS_AUTO_MAJOR or + * AXIS_AUTO_MINOR. */ + Display *display, /* Not used. */ + char *widgRec, + int offset) { - Axis *axisPtr = (Axis *)widgRec; - Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset); - unsigned long mask = (unsigned long)clientData; - - axisPtr->flags |= mask; - if (*ticksPtrPtr != NULL) { - free(*ticksPtrPtr); - } - *ticksPtrPtr = NULL; + Axis *axisPtr = (Axis *)widgRec; + Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset); + unsigned long mask = (unsigned long)clientData; + + axisPtr->flags |= mask; + if (*ticksPtrPtr != NULL) { + free(*ticksPtrPtr); + } + *ticksPtrPtr = NULL; } /* @@ -1004,46 +1008,46 @@ FreeTicksProc( /*ARGSUSED*/ static int ObjToTicksProc( - ClientData clientData, /* Either AXIS_AUTO_MAJOR or - * AXIS_AUTO_MINOR. */ - Tcl_Interp *interp, /* Interpreter to send results. */ - Tk_Window tkwin, /* Not used. */ - Tcl_Obj *objPtr, /* String representing new value. */ - char *widgRec, /* Pointer to structure record. */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ + ClientData clientData, /* Either AXIS_AUTO_MAJOR or + * AXIS_AUTO_MINOR. */ + Tcl_Interp *interp, /* Interpreter to send results. */ + Tk_Window tkwin, /* Not used. */ + Tcl_Obj *objPtr, /* String representing new value. */ + char *widgRec, /* Pointer to structure record. */ + int offset, /* Offset to field in structure */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)widgRec; - Tcl_Obj **objv; - Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset); - Ticks *ticksPtr; - int objc; - unsigned long mask = (unsigned long)clientData; - - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - return TCL_ERROR; - } - axisPtr->flags |= mask; - ticksPtr = NULL; - if (objc > 0) { - int i; + Axis *axisPtr = (Axis *)widgRec; + Tcl_Obj **objv; + Ticks **ticksPtrPtr = (Ticks **) (widgRec + offset); + Ticks *ticksPtr; + int objc; + unsigned long mask = (unsigned long)clientData; + + if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { + return TCL_ERROR; + } + axisPtr->flags |= mask; + ticksPtr = NULL; + if (objc > 0) { + int i; - ticksPtr = malloc(sizeof(Ticks) + (objc*sizeof(double))); - for (i = 0; i < objc; i++) { - double value; + ticksPtr = malloc(sizeof(Ticks) + (objc*sizeof(double))); + for (i = 0; i < objc; i++) { + double value; - if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) { - free(ticksPtr); - return TCL_ERROR; - } - ticksPtr->values[i] = value; - } - ticksPtr->nTicks = objc; - axisPtr->flags &= ~mask; - } - FreeTicksProc(clientData, Tk_Display(tkwin), widgRec, offset); - *ticksPtrPtr = ticksPtr; - return TCL_OK; + if (Blt_ExprDoubleFromObj(interp, objv[i], &value) != TCL_OK) { + free(ticksPtr); + return TCL_ERROR; + } + ticksPtr->values[i] = value; + } + ticksPtr->nTicks = objc; + axisPtr->flags &= ~mask; + } + FreeTicksProc(clientData, Tk_Display(tkwin), widgRec, offset); + *ticksPtrPtr = ticksPtr; + return TCL_OK; } /* @@ -1060,34 +1064,34 @@ ObjToTicksProc( /*ARGSUSED*/ static Tcl_Obj * TicksToObjProc( - ClientData clientData, /* Either AXIS_AUTO_MAJOR or - * AXIS_AUTO_MINOR. */ - Tcl_Interp *interp, - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ + ClientData clientData, /* Either AXIS_AUTO_MAJOR or + * AXIS_AUTO_MINOR. */ + Tcl_Interp *interp, + Tk_Window tkwin, /* Not used. */ + char *widgRec, /* */ + int offset, /* Offset to field in structure */ + int flags) /* Not used. */ { - Axis *axisPtr; - Tcl_Obj *listObjPtr; - Ticks *ticksPtr; - unsigned long mask; - - axisPtr = (Axis *)widgRec; - ticksPtr = *(Ticks **) (widgRec + offset); - mask = (unsigned long)clientData; - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - if ((ticksPtr != NULL) && ((axisPtr->flags & mask) == 0)) { - unsigned int i; - - for (i = 0; i < ticksPtr->nTicks; i++) { - Tcl_Obj *objPtr; - - objPtr = Tcl_NewDoubleObj(ticksPtr->values[i]); - Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); - } - } - return listObjPtr; + Axis *axisPtr; + Tcl_Obj *listObjPtr; + Ticks *ticksPtr; + unsigned long mask; + + axisPtr = (Axis *)widgRec; + ticksPtr = *(Ticks **) (widgRec + offset); + mask = (unsigned long)clientData; + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + if ((ticksPtr != NULL) && ((axisPtr->flags & mask) == 0)) { + unsigned int i; + + for (i = 0; i < ticksPtr->nTicks; i++) { + Tcl_Obj *objPtr; + + objPtr = Tcl_NewDoubleObj(ticksPtr->values[i]); + Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); + } + } + return listObjPtr; } /* @@ -1109,48 +1113,48 @@ TicksToObjProc( /*ARGSUSED*/ static int ObjToLooseProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interpreter to send results. */ - Tk_Window tkwin, /* Not used. */ - Tcl_Obj *objPtr, /* String representing new value. */ - char *widgRec, /* Pointer to structure record. */ - int offset, /* Not used. */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Interpreter to send results. */ + Tk_Window tkwin, /* Not used. */ + Tcl_Obj *objPtr, /* String representing new value. */ + char *widgRec, /* Pointer to structure record. */ + int offset, /* Not used. */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)(widgRec); - Tcl_Obj **objv; - int i; - int objc; - int values[2]; + Axis *axisPtr = (Axis *)(widgRec); + Tcl_Obj **objv; + int i; + int objc; + int values[2]; - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - return TCL_ERROR; - } - if ((objc < 1) || (objc > 2)) { - Tcl_AppendResult(interp, "wrong # elements in loose value \"", - Tcl_GetString(objPtr), "\"", (char *)NULL); - return TCL_ERROR; - } - for (i = 0; i < objc; i++) { - const char *string; + if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { + return TCL_ERROR; + } + if ((objc < 1) || (objc > 2)) { + Tcl_AppendResult(interp, "wrong # elements in loose value \"", + Tcl_GetString(objPtr), "\"", (char *)NULL); + return TCL_ERROR; + } + for (i = 0; i < objc; i++) { + const char *string; - string = Tcl_GetString(objv[i]); - if ((string[0] == 'a') && (strcmp(string, "always") == 0)) { - values[i] = AXIS_ALWAYS_LOOSE; - } else { - int bool; + string = Tcl_GetString(objv[i]); + if ((string[0] == 'a') && (strcmp(string, "always") == 0)) { + values[i] = AXIS_ALWAYS_LOOSE; + } else { + int bool; - if (Tcl_GetBooleanFromObj(interp, objv[i], &bool) != TCL_OK) { - return TCL_ERROR; - } - values[i] = bool; - } - } - axisPtr->looseMin = axisPtr->looseMax = values[0]; - if (objc > 1) { - axisPtr->looseMax = values[1]; - } - return TCL_OK; + if (Tcl_GetBooleanFromObj(interp, objv[i], &bool) != TCL_OK) { + return TCL_ERROR; + } + values[i] = bool; + } + } + axisPtr->looseMin = axisPtr->looseMax = values[0]; + if (objc > 1) { + axisPtr->looseMax = values[1]; + } + return TCL_OK; } /* @@ -1166,53 +1170,53 @@ ObjToLooseProc( /*ARGSUSED*/ static Tcl_Obj * LooseToObjProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* Widget record */ - int offset, /* Not used. */ - int flags) /* Not used. */ + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, + Tk_Window tkwin, /* Not used. */ + char *widgRec, /* Widget record */ + int offset, /* Not used. */ + int flags) /* Not used. */ { - Axis *axisPtr = (Axis *)widgRec; - Tcl_Obj *listObjPtr; - - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - if (axisPtr->looseMin == AXIS_TIGHT) { - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(FALSE)); - } else if (axisPtr->looseMin == AXIS_LOOSE) { - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(TRUE)); - } else if (axisPtr->looseMin == AXIS_ALWAYS_LOOSE) { - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj("always", 6)); - } - if (axisPtr->looseMin != axisPtr->looseMax) { - if (axisPtr->looseMax == AXIS_TIGHT) { - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewBooleanObj(FALSE)); - } else if (axisPtr->looseMax == AXIS_LOOSE) { - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewBooleanObj(TRUE)); - } else if (axisPtr->looseMax == AXIS_ALWAYS_LOOSE) { - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj("always", 6)); - } - } - return listObjPtr; + Axis *axisPtr = (Axis *)widgRec; + Tcl_Obj *listObjPtr; + + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + if (axisPtr->looseMin == AXIS_TIGHT) { + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(FALSE)); + } else if (axisPtr->looseMin == AXIS_LOOSE) { + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewBooleanObj(TRUE)); + } else if (axisPtr->looseMin == AXIS_ALWAYS_LOOSE) { + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj("always", 6)); + } + if (axisPtr->looseMin != axisPtr->looseMax) { + if (axisPtr->looseMax == AXIS_TIGHT) { + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewBooleanObj(FALSE)); + } else if (axisPtr->looseMax == AXIS_LOOSE) { + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewBooleanObj(TRUE)); + } else if (axisPtr->looseMax == AXIS_ALWAYS_LOOSE) { + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj("always", 6)); + } + } + return listObjPtr; } static void FreeTickLabels(Blt_Chain chain) { - Blt_ChainLink link; + Blt_ChainLink link; - for (link = Blt_Chain_FirstLink(chain); link != NULL; - link = Blt_Chain_NextLink(link)) { - TickLabel *labelPtr; + for (link = Blt_Chain_FirstLink(chain); link != NULL; + link = Blt_Chain_NextLink(link)) { + TickLabel *labelPtr; - labelPtr = Blt_Chain_GetValue(link); - free(labelPtr); - } - Blt_Chain_Reset(chain); + labelPtr = Blt_Chain_GetValue(link); + free(labelPtr); + } + Blt_Chain_Reset(chain); } /* @@ -1236,48 +1240,48 @@ static TickLabel * MakeLabel(Axis *axisPtr, double value) { #define TICK_LABEL_SIZE 200 - char string[TICK_LABEL_SIZE + 1]; - TickLabel *labelPtr; + char string[TICK_LABEL_SIZE + 1]; + TickLabel *labelPtr; - /* Generate a default tick label based upon the tick value. */ - if (axisPtr->logScale) { - sprintf_s(string, TICK_LABEL_SIZE, "1E%d", ROUND(value)); - } else { - sprintf_s(string, TICK_LABEL_SIZE, "%.*G", NUMDIGITS, value); - } + /* Generate a default tick label based upon the tick value. */ + if (axisPtr->logScale) { + sprintf_s(string, TICK_LABEL_SIZE, "1E%d", ROUND(value)); + } else { + sprintf_s(string, TICK_LABEL_SIZE, "%.*G", NUMDIGITS, value); + } - if (axisPtr->formatCmd != NULL) { - Graph *graphPtr; - Tcl_Interp *interp; - Tk_Window tkwin; + if (axisPtr->formatCmd != NULL) { + Graph *graphPtr; + Tcl_Interp *interp; + Tk_Window tkwin; - graphPtr = axisPtr->obj.graphPtr; - interp = graphPtr->interp; - tkwin = graphPtr->tkwin; - /* - * A TCL proc was designated to format tick labels. Append the path - * name of the widget and the default tick label as arguments when - * invoking it. Copy and save the new label from interp->result. - */ - Tcl_ResetResult(interp); - if (Tcl_VarEval(interp, axisPtr->formatCmd, " ", Tk_PathName(tkwin), - " ", string, (char *)NULL) != TCL_OK) { - Tcl_BackgroundError(interp); - } else { - /* - * The proc could return a string of any length, so arbitrarily - * limit it to what will fit in the return string. - */ - strncpy(string, Tcl_GetStringResult(interp), TICK_LABEL_SIZE); - string[TICK_LABEL_SIZE] = '\0'; + graphPtr = axisPtr->obj.graphPtr; + interp = graphPtr->interp; + tkwin = graphPtr->tkwin; + /* + * A TCL proc was designated to format tick labels. Append the path + * name of the widget and the default tick label as arguments when + * invoking it. Copy and save the new label from interp->result. + */ + Tcl_ResetResult(interp); + if (Tcl_VarEval(interp, axisPtr->formatCmd, " ", Tk_PathName(tkwin), + " ", string, (char *)NULL) != TCL_OK) { + Tcl_BackgroundError(interp); + } else { + /* + * The proc could return a string of any length, so arbitrarily + * limit it to what will fit in the return string. + */ + strncpy(string, Tcl_GetStringResult(interp), TICK_LABEL_SIZE); + string[TICK_LABEL_SIZE] = '\0'; - Tcl_ResetResult(interp); /* Clear the interpreter's result. */ - } + Tcl_ResetResult(interp); /* Clear the interpreter's result. */ } - labelPtr = malloc(sizeof(TickLabel) + strlen(string)); - strcpy(labelPtr->string, string); - labelPtr->anchorPos.x = labelPtr->anchorPos.y = DBL_MAX; - return labelPtr; + } + labelPtr = malloc(sizeof(TickLabel) + strlen(string)); + strcpy(labelPtr->string, string); + labelPtr->anchorPos.x = labelPtr->anchorPos.y = DBL_MAX; + return labelPtr; } /* @@ -1297,17 +1301,17 @@ MakeLabel(Axis *axisPtr, double value) double Blt_InvHMap(Axis *axisPtr, double x) { - double value; - - x = (double)(x - axisPtr->screenMin) * axisPtr->screenScale; - if (axisPtr->descending) { - x = 1.0 - x; - } - value = (x * axisPtr->axisRange.range) + axisPtr->axisRange.min; - if (axisPtr->logScale) { - value = EXP10(value); - } - return value; + double value; + + x = (double)(x - axisPtr->screenMin) * axisPtr->screenScale; + if (axisPtr->descending) { + x = 1.0 - x; + } + value = (x * axisPtr->axisRange.range) + axisPtr->axisRange.min; + if (axisPtr->logScale) { + value = EXP10(value); + } + return value; } /* @@ -1327,17 +1331,17 @@ Blt_InvHMap(Axis *axisPtr, double x) double Blt_InvVMap(Axis *axisPtr, double y) /* Screen coordinate */ { - double value; - - y = (double)(y - axisPtr->screenMin) * axisPtr->screenScale; - if (axisPtr->descending) { - y = 1.0 - y; - } - value = ((1.0 - y) * axisPtr->axisRange.range) + axisPtr->axisRange.min; - if (axisPtr->logScale) { - value = EXP10(value); - } - return value; + double value; + + y = (double)(y - axisPtr->screenMin) * axisPtr->screenScale; + if (axisPtr->descending) { + y = 1.0 - y; + } + value = ((1.0 - y) * axisPtr->axisRange.range) + axisPtr->axisRange.min; + if (axisPtr->logScale) { + value = EXP10(value); + } + return value; } /* @@ -1357,15 +1361,15 @@ Blt_InvVMap(Axis *axisPtr, double y) /* Screen coordinate */ double Blt_HMap(Axis *axisPtr, double x) { - if ((axisPtr->logScale) && (x != 0.0)) { - x = log10(fabs(x)); - } - /* Map graph coordinate to normalized coordinates [0..1] */ - x = (x - axisPtr->axisRange.min) * axisPtr->axisRange.scale; - if (axisPtr->descending) { - x = 1.0 - x; - } - return (x * axisPtr->screenRange + axisPtr->screenMin); + if ((axisPtr->logScale) && (x != 0.0)) { + x = log10(fabs(x)); + } + /* Map graph coordinate to normalized coordinates [0..1] */ + x = (x - axisPtr->axisRange.min) * axisPtr->axisRange.scale; + if (axisPtr->descending) { + x = 1.0 - x; + } + return (x * axisPtr->screenRange + axisPtr->screenMin); } /* @@ -1385,15 +1389,15 @@ Blt_HMap(Axis *axisPtr, double x) double Blt_VMap(Axis *axisPtr, double y) { - if ((axisPtr->logScale) && (y != 0.0)) { - y = log10(fabs(y)); - } - /* Map graph coordinate to normalized coordinates [0..1] */ - y = (y - axisPtr->axisRange.min) * axisPtr->axisRange.scale; - if (axisPtr->descending) { - y = 1.0 - y; - } - return ((1.0 - y) * axisPtr->screenRange + axisPtr->screenMin); + if ((axisPtr->logScale) && (y != 0.0)) { + y = log10(fabs(y)); + } + /* Map graph coordinate to normalized coordinates [0..1] */ + y = (y - axisPtr->axisRange.min) * axisPtr->axisRange.scale; + if (axisPtr->descending) { + y = 1.0 - y; + } + return ((1.0 - y) * axisPtr->screenRange + axisPtr->screenMin); } /* @@ -1411,20 +1415,20 @@ Blt_VMap(Axis *axisPtr, double y) */ Point2d Blt_Map2D( - Graph *graphPtr, - double x, double y, /* Graph x and y coordinates */ - Axis2d *axesPtr) /* Specifies which axes to use */ + Graph *graphPtr, + double x, double y, /* Graph x and y coordinates */ + Axis2d *axesPtr) /* Specifies which axes to use */ { - Point2d point; - - if (graphPtr->inverted) { - point.x = Blt_HMap(axesPtr->y, y); - point.y = Blt_VMap(axesPtr->x, x); - } else { - point.x = Blt_HMap(axesPtr->x, x); - point.y = Blt_VMap(axesPtr->y, y); - } - return point; + Point2d point; + + if (graphPtr->inverted) { + point.x = Blt_HMap(axesPtr->y, y); + point.y = Blt_VMap(axesPtr->x, x); + } else { + point.x = Blt_HMap(axesPtr->x, x); + point.y = Blt_VMap(axesPtr->y, y); + } + return point; } /* @@ -1442,140 +1446,140 @@ Blt_Map2D( */ Point2d Blt_InvMap2D( - Graph *graphPtr, - double x, double y, /* Window x and y coordinates */ - Axis2d *axesPtr) /* Specifies which axes to use */ + Graph *graphPtr, + double x, double y, /* Window x and y coordinates */ + Axis2d *axesPtr) /* Specifies which axes to use */ { - Point2d point; - - if (graphPtr->inverted) { - point.x = Blt_InvVMap(axesPtr->x, y); - point.y = Blt_InvHMap(axesPtr->y, x); - } else { - point.x = Blt_InvHMap(axesPtr->x, x); - point.y = Blt_InvVMap(axesPtr->y, y); - } - return point; + Point2d point; + + if (graphPtr->inverted) { + point.x = Blt_InvVMap(axesPtr->x, y); + point.y = Blt_InvHMap(axesPtr->y, x); + } else { + point.x = Blt_InvHMap(axesPtr->x, x); + point.y = Blt_InvVMap(axesPtr->y, y); + } + return point; } static void GetDataLimits(Axis *axisPtr, double min, double max) { - if (axisPtr->valueRange.min > min) { - axisPtr->valueRange.min = min; - } - if (axisPtr->valueRange.max < max) { - axisPtr->valueRange.max = max; - } + if (axisPtr->valueRange.min > min) { + axisPtr->valueRange.min = min; + } + if (axisPtr->valueRange.max < max) { + axisPtr->valueRange.max = max; + } } static void FixAxisRange(Axis *axisPtr) { - double min, max; - - /* - * When auto-scaling, the axis limits are the bounds of the element data. - * If no data exists, set arbitrary limits (wrt to log/linear scale). - */ - min = axisPtr->valueRange.min; - max = axisPtr->valueRange.max; - - /* Check the requested axis limits. Can't allow -min to be greater - * than -max, or have undefined log scale limits. */ - if (((!isnan(axisPtr->reqMin)) && (!isnan(axisPtr->reqMax))) && - (axisPtr->reqMin >= axisPtr->reqMax)) { - axisPtr->reqMin = axisPtr->reqMax = NAN; - } - if (axisPtr->logScale) { - if ((!isnan(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) { - axisPtr->reqMin = NAN; - } - if ((!isnan(axisPtr->reqMax)) && (axisPtr->reqMax <= 0.0)) { - axisPtr->reqMax = NAN; - } - } - - if (min == DBL_MAX) { - if (!isnan(axisPtr->reqMin)) { - min = axisPtr->reqMin; - } else { - min = (axisPtr->logScale) ? 0.001 : 0.0; - } - } - if (max == -DBL_MAX) { - if (!isnan(axisPtr->reqMax)) { - max = axisPtr->reqMax; - } else { - max = 1.0; - } + double min, max; + + /* + * When auto-scaling, the axis limits are the bounds of the element data. + * If no data exists, set arbitrary limits (wrt to log/linear scale). + */ + min = axisPtr->valueRange.min; + max = axisPtr->valueRange.max; + + /* Check the requested axis limits. Can't allow -min to be greater + * than -max, or have undefined log scale limits. */ + if (((!isnan(axisPtr->reqMin)) && (!isnan(axisPtr->reqMax))) && + (axisPtr->reqMin >= axisPtr->reqMax)) { + axisPtr->reqMin = axisPtr->reqMax = NAN; + } + if (axisPtr->logScale) { + if ((!isnan(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) { + axisPtr->reqMin = NAN; + } + if ((!isnan(axisPtr->reqMax)) && (axisPtr->reqMax <= 0.0)) { + axisPtr->reqMax = NAN; + } + } + + if (min == DBL_MAX) { + if (!isnan(axisPtr->reqMin)) { + min = axisPtr->reqMin; + } else { + min = (axisPtr->logScale) ? 0.001 : 0.0; } - if (min >= max) { - /* - * There is no range of data (i.e. min is not less than max), so - * manufacture one. - */ - if (min == 0.0) { - min = 0.0, max = 1.0; - } else { - max = min + (fabs(min) * 0.1); - } + } + if (max == -DBL_MAX) { + if (!isnan(axisPtr->reqMax)) { + max = axisPtr->reqMax; + } else { + max = 1.0; } - SetAxisRange(&axisPtr->valueRange, min, max); - - /* - * The axis limits are either the current data range or overridden by the - * values selected by the user with the -min or -max options. + } + if (min >= max) { + /* + * There is no range of data (i.e. min is not less than max), so + * manufacture one. */ - axisPtr->min = min; - axisPtr->max = max; - if (!isnan(axisPtr->reqMin)) { - axisPtr->min = axisPtr->reqMin; - } - if (!isnan(axisPtr->reqMax)) { - axisPtr->max = axisPtr->reqMax; - } - if (axisPtr->max < axisPtr->min) { - /* - * If the limits still don't make sense, it's because one limit - * configuration option (-min or -max) was set and the other default - * (based upon the data) is too small or large. Remedy this by making - * up a new min or max from the user-defined limit. - */ - if (isnan(axisPtr->reqMin)) { - axisPtr->min = axisPtr->max - (fabs(axisPtr->max) * 0.1); - } - if (isnan(axisPtr->reqMax)) { - axisPtr->max = axisPtr->min + (fabs(axisPtr->max) * 0.1); - } - } - /* - * If a window size is defined, handle auto ranging by shifting the axis - * limits. + if (min == 0.0) { + min = 0.0, max = 1.0; + } else { + max = min + (fabs(min) * 0.1); + } + } + SetAxisRange(&axisPtr->valueRange, min, max); + + /* + * The axis limits are either the current data range or overridden by the + * values selected by the user with the -min or -max options. + */ + axisPtr->min = min; + axisPtr->max = max; + if (!isnan(axisPtr->reqMin)) { + axisPtr->min = axisPtr->reqMin; + } + if (!isnan(axisPtr->reqMax)) { + axisPtr->max = axisPtr->reqMax; + } + if (axisPtr->max < axisPtr->min) { + /* + * If the limits still don't make sense, it's because one limit + * configuration option (-min or -max) was set and the other default + * (based upon the data) is too small or large. Remedy this by making + * up a new min or max from the user-defined limit. */ - if ((axisPtr->windowSize > 0.0) && - (isnan(axisPtr->reqMin)) && (isnan(axisPtr->reqMax))) { - if (axisPtr->shiftBy < 0.0) { - axisPtr->shiftBy = 0.0; - } - max = axisPtr->min + axisPtr->windowSize; - if (axisPtr->max >= max) { - if (axisPtr->shiftBy > 0.0) { - max = UCEIL(axisPtr->max, axisPtr->shiftBy); - } - axisPtr->min = max - axisPtr->windowSize; - } - axisPtr->max = max; - } - if ((axisPtr->max != axisPtr->prevMax) || - (axisPtr->min != axisPtr->prevMin)) { - /* Indicate if the axis limits have changed */ - axisPtr->flags |= DIRTY; - /* and save the previous minimum and maximum values */ - axisPtr->prevMin = axisPtr->min; - axisPtr->prevMax = axisPtr->max; + if (isnan(axisPtr->reqMin)) { + axisPtr->min = axisPtr->max - (fabs(axisPtr->max) * 0.1); + } + if (isnan(axisPtr->reqMax)) { + axisPtr->max = axisPtr->min + (fabs(axisPtr->max) * 0.1); + } + } + /* + * If a window size is defined, handle auto ranging by shifting the axis + * limits. + */ + if ((axisPtr->windowSize > 0.0) && + (isnan(axisPtr->reqMin)) && (isnan(axisPtr->reqMax))) { + if (axisPtr->shiftBy < 0.0) { + axisPtr->shiftBy = 0.0; + } + max = axisPtr->min + axisPtr->windowSize; + if (axisPtr->max >= max) { + if (axisPtr->shiftBy > 0.0) { + max = UCEIL(axisPtr->max, axisPtr->shiftBy); + } + axisPtr->min = max - axisPtr->windowSize; } + axisPtr->max = max; + } + if ((axisPtr->max != axisPtr->prevMax) || + (axisPtr->min != axisPtr->prevMin)) { + /* Indicate if the axis limits have changed */ + axisPtr->flags |= DIRTY; + /* and save the previous minimum and maximum values */ + axisPtr->prevMin = axisPtr->min; + axisPtr->prevMax = axisPtr->max; + } } /* @@ -1594,77 +1598,77 @@ static double NiceNum(double x, int round) /* If non-zero, round. Otherwise take * ceiling of value. */ { - double expt; /* Exponent of x */ - double frac; /* Fractional part of x */ - double nice; /* Nice, rounded fraction */ - - expt = floor(log10(x)); - frac = x / EXP10(expt); /* between 1 and 10 */ - if (round) { - if (frac < 1.5) { - nice = 1.0; - } else if (frac < 3.0) { - nice = 2.0; - } else if (frac < 7.0) { - nice = 5.0; - } else { - nice = 10.0; - } + double expt; /* Exponent of x */ + double frac; /* Fractional part of x */ + double nice; /* Nice, rounded fraction */ + + expt = floor(log10(x)); + frac = x / EXP10(expt); /* between 1 and 10 */ + if (round) { + if (frac < 1.5) { + nice = 1.0; + } else if (frac < 3.0) { + nice = 2.0; + } else if (frac < 7.0) { + nice = 5.0; } else { - if (frac <= 1.0) { - nice = 1.0; - } else if (frac <= 2.0) { - nice = 2.0; - } else if (frac <= 5.0) { - nice = 5.0; - } else { - nice = 10.0; - } + nice = 10.0; + } + } else { + if (frac <= 1.0) { + nice = 1.0; + } else if (frac <= 2.0) { + nice = 2.0; + } else if (frac <= 5.0) { + nice = 5.0; + } else { + nice = 10.0; } - return nice * EXP10(expt); + } + return nice * EXP10(expt); } static Ticks * GenerateTicks(TickSweep *sweepPtr) { - Ticks *ticksPtr; - - ticksPtr = malloc(sizeof(Ticks) + - (sweepPtr->nSteps * sizeof(double))); - ticksPtr->nTicks = 0; - - if (sweepPtr->step == 0.0) { - /* Hack: A zero step indicates to use log values. */ - int i; - /* Precomputed log10 values [1..10] */ - static double logTable[] = { - 0.0, - 0.301029995663981, - 0.477121254719662, - 0.602059991327962, - 0.698970004336019, - 0.778151250383644, - 0.845098040014257, - 0.903089986991944, - 0.954242509439325, - 1.0 - }; - for (i = 0; i < sweepPtr->nSteps; i++) { - ticksPtr->values[i] = logTable[i]; - } - } else { - double value; - int i; + Ticks *ticksPtr; + + ticksPtr = malloc(sizeof(Ticks) + + (sweepPtr->nSteps * sizeof(double))); + ticksPtr->nTicks = 0; + + if (sweepPtr->step == 0.0) { + /* Hack: A zero step indicates to use log values. */ + int i; + /* Precomputed log10 values [1..10] */ + static double logTable[] = { + 0.0, + 0.301029995663981, + 0.477121254719662, + 0.602059991327962, + 0.698970004336019, + 0.778151250383644, + 0.845098040014257, + 0.903089986991944, + 0.954242509439325, + 1.0 + }; + for (i = 0; i < sweepPtr->nSteps; i++) { + ticksPtr->values[i] = logTable[i]; + } + } else { + double value; + int i; - value = sweepPtr->initial; /* Start from smallest axis tick */ - for (i = 0; i < sweepPtr->nSteps; i++) { - value = UROUND(value, sweepPtr->step); - ticksPtr->values[i] = value; - value += sweepPtr->step; - } - } - ticksPtr->nTicks = sweepPtr->nSteps; - return ticksPtr; + value = sweepPtr->initial; /* Start from smallest axis tick */ + for (i = 0; i < sweepPtr->nSteps; i++) { + value = UROUND(value, sweepPtr->step); + ticksPtr->values[i] = value; + value += sweepPtr->step; + } + } + ticksPtr->nTicks = sweepPtr->nSteps; + return ticksPtr; } /* @@ -1743,70 +1747,70 @@ GenerateTicks(TickSweep *sweepPtr) static void LogScaleAxis(Axis *axisPtr, double min, double max) { - double range; - double tickMin, tickMax; - double majorStep, minorStep; - int nMajor, nMinor; - - nMajor = nMinor = 0; - /* Suppress compiler warnings. */ - majorStep = minorStep = 0.0; - tickMin = tickMax = NAN; - if (min < max) { - min = (min != 0.0) ? log10(fabs(min)) : 0.0; - max = (max != 0.0) ? log10(fabs(max)) : 1.0; - - tickMin = floor(min); - tickMax = ceil(max); - range = tickMax - tickMin; + double range; + double tickMin, tickMax; + double majorStep, minorStep; + int nMajor, nMinor; + + nMajor = nMinor = 0; + /* Suppress compiler warnings. */ + majorStep = minorStep = 0.0; + tickMin = tickMax = NAN; + if (min < max) { + min = (min != 0.0) ? log10(fabs(min)) : 0.0; + max = (max != 0.0) ? log10(fabs(max)) : 1.0; + + tickMin = floor(min); + tickMax = ceil(max); + range = tickMax - tickMin; - if (range > 10) { - /* There are too many decades to display a major tick at every - * decade. Instead, treat the axis as a linear scale. */ - range = NiceNum(range, 0); - majorStep = NiceNum(range / axisPtr->reqNumMajorTicks, 1); - tickMin = UFLOOR(tickMin, majorStep); - tickMax = UCEIL(tickMax, majorStep); - nMajor = (int)((tickMax - tickMin) / majorStep) + 1; - minorStep = EXP10(floor(log10(majorStep))); - if (minorStep == majorStep) { - nMinor = 4, minorStep = 0.2; - } else { - nMinor = Round(majorStep / minorStep) - 1; - } - } else { - if (tickMin == tickMax) { - tickMax++; - } - majorStep = 1.0; - nMajor = (int)(tickMax - tickMin + 1); /* FIXME: Check this. */ + if (range > 10) { + /* There are too many decades to display a major tick at every + * decade. Instead, treat the axis as a linear scale. */ + range = NiceNum(range, 0); + majorStep = NiceNum(range / axisPtr->reqNumMajorTicks, 1); + tickMin = UFLOOR(tickMin, majorStep); + tickMax = UCEIL(tickMax, majorStep); + nMajor = (int)((tickMax - tickMin) / majorStep) + 1; + minorStep = EXP10(floor(log10(majorStep))); + if (minorStep == majorStep) { + nMinor = 4, minorStep = 0.2; + } else { + nMinor = Round(majorStep / minorStep) - 1; + } + } else { + if (tickMin == tickMax) { + tickMax++; + } + majorStep = 1.0; + nMajor = (int)(tickMax - tickMin + 1); /* FIXME: Check this. */ - minorStep = 0.0; /* This is a special hack to pass - * information to the GenerateTicks - * routine. An interval of 0.0 tells 1) - * this is a minor sweep and 2) the axis - * is log scale. */ - nMinor = 10; - } - if ((axisPtr->looseMin == AXIS_TIGHT) || - ((axisPtr->looseMin == AXIS_LOOSE) && - (!isnan(axisPtr->reqMin)))) { - tickMin = min; - nMajor++; - } - if ((axisPtr->looseMax == AXIS_TIGHT) || - ((axisPtr->looseMax == AXIS_LOOSE) && - (!isnan(axisPtr->reqMax)))) { - tickMax = max; - } + minorStep = 0.0; /* This is a special hack to pass + * information to the GenerateTicks + * routine. An interval of 0.0 tells 1) + * this is a minor sweep and 2) the axis + * is log scale. */ + nMinor = 10; } - axisPtr->majorSweep.step = majorStep; - axisPtr->majorSweep.initial = floor(tickMin); - axisPtr->majorSweep.nSteps = nMajor; - axisPtr->minorSweep.initial = axisPtr->minorSweep.step = minorStep; - axisPtr->minorSweep.nSteps = nMinor; + if ((axisPtr->looseMin == AXIS_TIGHT) || + ((axisPtr->looseMin == AXIS_LOOSE) && + (!isnan(axisPtr->reqMin)))) { + tickMin = min; + nMajor++; + } + if ((axisPtr->looseMax == AXIS_TIGHT) || + ((axisPtr->looseMax == AXIS_LOOSE) && + (!isnan(axisPtr->reqMax)))) { + tickMax = max; + } + } + axisPtr->majorSweep.step = majorStep; + axisPtr->majorSweep.initial = floor(tickMin); + axisPtr->majorSweep.nSteps = nMajor; + axisPtr->minorSweep.initial = axisPtr->minorSweep.step = minorStep; + axisPtr->minorSweep.nSteps = nMinor; - SetAxisRange(&axisPtr->axisRange, tickMin, tickMax); + SetAxisRange(&axisPtr->axisRange, tickMin, tickMax); } /* @@ -1873,94 +1877,94 @@ LogScaleAxis(Axis *axisPtr, double min, double max) static void LinearScaleAxis(Axis *axisPtr, double min, double max) { - double step; - double tickMin, tickMax; - double axisMin, axisMax; - unsigned int nTicks; + double step; + double tickMin, tickMax; + double axisMin, axisMax; + unsigned int nTicks; + + nTicks = 0; + step = 1.0; + /* Suppress compiler warning. */ + axisMin = axisMax = tickMin = tickMax = NAN; + if (min < max) { + double range; - nTicks = 0; - step = 1.0; - /* Suppress compiler warning. */ - axisMin = axisMax = tickMin = tickMax = NAN; - if (min < max) { - double range; - - range = max - min; - /* Calculate the major tick stepping. */ - if (axisPtr->reqStep > 0.0) { - /* An interval was designated by the user. Keep scaling it until - * it fits comfortably within the current range of the axis. */ - step = axisPtr->reqStep; - while ((2 * step) >= range) { - step *= 0.5; - } - } else { - range = NiceNum(range, 0); - step = NiceNum(range / axisPtr->reqNumMajorTicks, 1); - } + range = max - min; + /* Calculate the major tick stepping. */ + if (axisPtr->reqStep > 0.0) { + /* An interval was designated by the user. Keep scaling it until + * it fits comfortably within the current range of the axis. */ + step = axisPtr->reqStep; + while ((2 * step) >= range) { + step *= 0.5; + } + } else { + range = NiceNum(range, 0); + step = NiceNum(range / axisPtr->reqNumMajorTicks, 1); + } - /* Find the outer tick values. Add 0.0 to prevent getting -0.0. */ - axisMin = tickMin = floor(min / step) * step + 0.0; - axisMax = tickMax = ceil(max / step) * step + 0.0; + /* Find the outer tick values. Add 0.0 to prevent getting -0.0. */ + axisMin = tickMin = floor(min / step) * step + 0.0; + axisMax = tickMax = ceil(max / step) * step + 0.0; - nTicks = Round((tickMax - tickMin) / step) + 1; - } - axisPtr->majorSweep.step = step; - axisPtr->majorSweep.initial = tickMin; - axisPtr->majorSweep.nSteps = nTicks; - - /* - * The limits of the axis are either the range of the data ("tight") or at - * the next outer tick interval ("loose"). The looseness or tightness has - * to do with how the axis fits the range of data values. This option is - * overridden when the user sets an axis limit (by either -min or -max - * option). The axis limit is always at the selected limit (otherwise we - * assume that user would have picked a different number). - */ - if ((axisPtr->looseMin == AXIS_TIGHT) || - ((axisPtr->looseMin == AXIS_LOOSE) && - (!isnan(axisPtr->reqMin)))) { - axisMin = min; - } - if ((axisPtr->looseMax == AXIS_TIGHT) || - ((axisPtr->looseMax == AXIS_LOOSE) && - (!isnan(axisPtr->reqMax)))) { - axisMax = max; - } - SetAxisRange(&axisPtr->axisRange, axisMin, axisMax); - - /* Now calculate the minor tick step and number. */ - - if ((axisPtr->reqNumMinorTicks > 0) && (axisPtr->flags & AXIS_AUTO_MAJOR)) { - nTicks = axisPtr->reqNumMinorTicks - 1; - step = 1.0 / (nTicks + 1); - } else { - nTicks = 0; /* No minor ticks. */ - step = 0.5; /* Don't set the minor tick interval to - * 0.0. It makes the GenerateTicks - * routine * create minor log-scale tick - * marks. */ - } - axisPtr->minorSweep.initial = axisPtr->minorSweep.step = step; - axisPtr->minorSweep.nSteps = nTicks; + nTicks = Round((tickMax - tickMin) / step) + 1; + } + axisPtr->majorSweep.step = step; + axisPtr->majorSweep.initial = tickMin; + axisPtr->majorSweep.nSteps = nTicks; + + /* + * The limits of the axis are either the range of the data ("tight") or at + * the next outer tick interval ("loose"). The looseness or tightness has + * to do with how the axis fits the range of data values. This option is + * overridden when the user sets an axis limit (by either -min or -max + * option). The axis limit is always at the selected limit (otherwise we + * assume that user would have picked a different number). + */ + if ((axisPtr->looseMin == AXIS_TIGHT) || + ((axisPtr->looseMin == AXIS_LOOSE) && + (!isnan(axisPtr->reqMin)))) { + axisMin = min; + } + if ((axisPtr->looseMax == AXIS_TIGHT) || + ((axisPtr->looseMax == AXIS_LOOSE) && + (!isnan(axisPtr->reqMax)))) { + axisMax = max; + } + SetAxisRange(&axisPtr->axisRange, axisMin, axisMax); + + /* Now calculate the minor tick step and number. */ + + if ((axisPtr->reqNumMinorTicks > 0) && (axisPtr->flags & AXIS_AUTO_MAJOR)) { + nTicks = axisPtr->reqNumMinorTicks - 1; + step = 1.0 / (nTicks + 1); + } else { + nTicks = 0; /* No minor ticks. */ + step = 0.5; /* Don't set the minor tick interval to + * 0.0. It makes the GenerateTicks + * routine * create minor log-scale tick + * marks. */ + } + axisPtr->minorSweep.initial = axisPtr->minorSweep.step = step; + axisPtr->minorSweep.nSteps = nTicks; } static void SweepTicks(Axis *axisPtr) { - if (axisPtr->flags & AXIS_AUTO_MAJOR) { - if (axisPtr->t1Ptr != NULL) { - free(axisPtr->t1Ptr); - } - axisPtr->t1Ptr = GenerateTicks(&axisPtr->majorSweep); + if (axisPtr->flags & AXIS_AUTO_MAJOR) { + if (axisPtr->t1Ptr != NULL) { + free(axisPtr->t1Ptr); } - if (axisPtr->flags & AXIS_AUTO_MINOR) { - if (axisPtr->t2Ptr != NULL) { - free(axisPtr->t2Ptr); - } - axisPtr->t2Ptr = GenerateTicks(&axisPtr->minorSweep); + axisPtr->t1Ptr = GenerateTicks(&axisPtr->majorSweep); + } + if (axisPtr->flags & AXIS_AUTO_MINOR) { + if (axisPtr->t2Ptr != NULL) { + free(axisPtr->t2Ptr); } + axisPtr->t2Ptr = GenerateTicks(&axisPtr->minorSweep); + } } /* @@ -1976,89 +1980,89 @@ SweepTicks(Axis *axisPtr) void Blt_ResetAxes(Graph *graphPtr) { - Blt_ChainLink link; - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - - /* FIXME: This should be called whenever the display list of - * elements change. Maybe yet another flag INIT_STACKS to - * indicate that the element display list has changed. - * Needs to be done before the axis limits are set. - */ - Blt_InitBarSetTable(graphPtr); - if ((graphPtr->mode == BARS_STACKED) && (graphPtr->nBarGroups > 0)) { - Blt_ComputeBarStacks(graphPtr); - } - /* - * Step 1: Reset all axes. Initialize the data limits of the axis to - * impossible values. - */ - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; + Blt_ChainLink link; + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + + /* FIXME: This should be called whenever the display list of + * elements change. Maybe yet another flag INIT_STACKS to + * indicate that the element display list has changed. + * Needs to be done before the axis limits are set. + */ + Blt_InitBarSetTable(graphPtr); + if ((graphPtr->mode == BARS_STACKED) && (graphPtr->nBarGroups > 0)) { + Blt_ComputeBarStacks(graphPtr); + } + /* + * Step 1: Reset all axes. Initialize the data limits of the axis to + * impossible values. + */ + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; - axisPtr = Tcl_GetHashValue(hPtr); - axisPtr->min = axisPtr->valueRange.min = DBL_MAX; - axisPtr->max = axisPtr->valueRange.max = -DBL_MAX; - } + axisPtr = Tcl_GetHashValue(hPtr); + axisPtr->min = axisPtr->valueRange.min = DBL_MAX; + axisPtr->max = axisPtr->valueRange.max = -DBL_MAX; + } + + /* + * Step 2: For each element that's to be displayed, get the smallest + * and largest data values mapped to each X and Y-axis. This + * will be the axis limits if the user doesn't override them + * with -min and -max options. + */ + for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); + link != NULL; link = Blt_Chain_NextLink(link)) { + Element *elemPtr; + Region2d exts; + + elemPtr = Blt_Chain_GetValue(link); + (*elemPtr->procsPtr->extentsProc) (elemPtr, &exts); + GetDataLimits(elemPtr->axes.x, exts.left, exts.right); + GetDataLimits(elemPtr->axes.y, exts.top, exts.bottom); + } + /* + * Step 3: Now that we know the range of data values for each axis, + * set axis limits and compute a sweep to generate tick values. + */ + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; + double min, max; - /* - * Step 2: For each element that's to be displayed, get the smallest - * and largest data values mapped to each X and Y-axis. This - * will be the axis limits if the user doesn't override them - * with -min and -max options. - */ - for (link = Blt_Chain_FirstLink(graphPtr->elements.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { - Element *elemPtr; - Region2d exts; + axisPtr = Tcl_GetHashValue(hPtr); + FixAxisRange(axisPtr); - elemPtr = Blt_Chain_GetValue(link); - (*elemPtr->procsPtr->extentsProc) (elemPtr, &exts); - GetDataLimits(elemPtr->axes.x, exts.left, exts.right); - GetDataLimits(elemPtr->axes.y, exts.top, exts.bottom); + /* Calculate min/max tick (major/minor) layouts */ + min = axisPtr->min; + max = axisPtr->max; + if ((!isnan(axisPtr->scrollMin)) && (min < axisPtr->scrollMin)) { + min = axisPtr->scrollMin; + } + if ((!isnan(axisPtr->scrollMax)) && (max > axisPtr->scrollMax)) { + max = axisPtr->scrollMax; + } + if (axisPtr->logScale) { + LogScaleAxis(axisPtr, min, max); + } else if (axisPtr->timeScale) { + TimeScaleAxis(axisPtr, min, max); + } else { + LinearScaleAxis(axisPtr, min, max); } - /* - * Step 3: Now that we know the range of data values for each axis, - * set axis limits and compute a sweep to generate tick values. - */ - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; - double min, max; - - axisPtr = Tcl_GetHashValue(hPtr); - FixAxisRange(axisPtr); - - /* Calculate min/max tick (major/minor) layouts */ - min = axisPtr->min; - max = axisPtr->max; - if ((!isnan(axisPtr->scrollMin)) && (min < axisPtr->scrollMin)) { - min = axisPtr->scrollMin; - } - if ((!isnan(axisPtr->scrollMax)) && (max > axisPtr->scrollMax)) { - max = axisPtr->scrollMax; - } - if (axisPtr->logScale) { - LogScaleAxis(axisPtr, min, max); - } else if (axisPtr->timeScale) { - TimeScaleAxis(axisPtr, min, max); - } else { - LinearScaleAxis(axisPtr, min, max); - } - if ((axisPtr->flags & (DIRTY|AXIS_USE)) == (DIRTY|AXIS_USE)) { - graphPtr->flags |= CACHE_DIRTY; - } + if ((axisPtr->flags & (DIRTY|AXIS_USE)) == (DIRTY|AXIS_USE)) { + graphPtr->flags |= CACHE_DIRTY; } + } - graphPtr->flags &= ~RESET_AXES; + graphPtr->flags &= ~RESET_AXES; - /* - * When any axis changes, we need to layout the entire graph. - */ - graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | MAP_ALL | - REDRAW_WORLD); + /* + * When any axis changes, we need to layout the entire graph. + */ + graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | MAP_ALL | + REDRAW_WORLD); } /* @@ -2083,64 +2087,64 @@ Blt_ResetAxes(Graph *graphPtr) static void ResetTextStyles(Axis *axisPtr) { - Graph *graphPtr = axisPtr->obj.graphPtr; - GC newGC; - XGCValues gcValues; - unsigned long gcMask; - - Blt_Ts_ResetStyle(graphPtr->tkwin, &axisPtr->limitsTextStyle); - - gcMask = (GCForeground | GCLineWidth | GCCapStyle); - gcValues.foreground = axisPtr->tickColor->pixel; - gcValues.font = Tk_FontId(axisPtr->tickFont); - gcValues.line_width = LineWidth(axisPtr->lineWidth); - gcValues.cap_style = CapProjecting; - - newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); - if (axisPtr->tickGC != NULL) { - Tk_FreeGC(graphPtr->display, axisPtr->tickGC); - } - axisPtr->tickGC = newGC; - - /* Assuming settings from above GC */ - gcValues.foreground = axisPtr->activeFgColor->pixel; - newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); - if (axisPtr->activeTickGC != NULL) { - Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC); - } - axisPtr->activeTickGC = newGC; - - gcValues.background = gcValues.foreground = axisPtr->major.color->pixel; - gcValues.line_width = LineWidth(axisPtr->major.lineWidth); - gcMask = (GCForeground | GCBackground | GCLineWidth); - if (LineIsDashed(axisPtr->major.dashes)) { - gcValues.line_style = LineOnOffDash; - gcMask |= GCLineStyle; - } - newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); - if (LineIsDashed(axisPtr->major.dashes)) { - Blt_SetDashes(graphPtr->display, newGC, &axisPtr->major.dashes); - } - if (axisPtr->major.gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc); - } - axisPtr->major.gc = newGC; - - gcValues.background = gcValues.foreground = axisPtr->minor.color->pixel; - gcValues.line_width = LineWidth(axisPtr->minor.lineWidth); - gcMask = (GCForeground | GCBackground | GCLineWidth); - if (LineIsDashed(axisPtr->minor.dashes)) { - gcValues.line_style = LineOnOffDash; - gcMask |= GCLineStyle; - } - newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); - if (LineIsDashed(axisPtr->minor.dashes)) { - Blt_SetDashes(graphPtr->display, newGC, &axisPtr->minor.dashes); - } - if (axisPtr->minor.gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc); - } - axisPtr->minor.gc = newGC; + Graph *graphPtr = axisPtr->obj.graphPtr; + GC newGC; + XGCValues gcValues; + unsigned long gcMask; + + Blt_Ts_ResetStyle(graphPtr->tkwin, &axisPtr->limitsTextStyle); + + gcMask = (GCForeground | GCLineWidth | GCCapStyle); + gcValues.foreground = axisPtr->tickColor->pixel; + gcValues.font = Tk_FontId(axisPtr->tickFont); + gcValues.line_width = LineWidth(axisPtr->lineWidth); + gcValues.cap_style = CapProjecting; + + newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); + if (axisPtr->tickGC != NULL) { + Tk_FreeGC(graphPtr->display, axisPtr->tickGC); + } + axisPtr->tickGC = newGC; + + /* Assuming settings from above GC */ + gcValues.foreground = axisPtr->activeFgColor->pixel; + newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); + if (axisPtr->activeTickGC != NULL) { + Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC); + } + axisPtr->activeTickGC = newGC; + + gcValues.background = gcValues.foreground = axisPtr->major.color->pixel; + gcValues.line_width = LineWidth(axisPtr->major.lineWidth); + gcMask = (GCForeground | GCBackground | GCLineWidth); + if (LineIsDashed(axisPtr->major.dashes)) { + gcValues.line_style = LineOnOffDash; + gcMask |= GCLineStyle; + } + newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); + if (LineIsDashed(axisPtr->major.dashes)) { + Blt_SetDashes(graphPtr->display, newGC, &axisPtr->major.dashes); + } + if (axisPtr->major.gc != NULL) { + Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc); + } + axisPtr->major.gc = newGC; + + gcValues.background = gcValues.foreground = axisPtr->minor.color->pixel; + gcValues.line_width = LineWidth(axisPtr->minor.lineWidth); + gcMask = (GCForeground | GCBackground | GCLineWidth); + if (LineIsDashed(axisPtr->minor.dashes)) { + gcValues.line_style = LineOnOffDash; + gcMask |= GCLineStyle; + } + newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); + if (LineIsDashed(axisPtr->minor.dashes)) { + Blt_SetDashes(graphPtr->display, newGC, &axisPtr->minor.dashes); + } + if (axisPtr->minor.gc != NULL) { + Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc); + } + axisPtr->minor.gc = newGC; } /* @@ -2160,56 +2164,56 @@ ResetTextStyles(Axis *axisPtr) static void DestroyAxis(Axis *axisPtr) { - Graph *graphPtr = axisPtr->obj.graphPtr; - int flags; - - flags = Blt_GraphType(graphPtr); - Blt_FreeOptions(configSpecs, (char *)axisPtr, graphPtr->display, flags); - if (graphPtr->bindTable != NULL) { - Blt_DeleteBindings(graphPtr->bindTable, axisPtr); - } - if (axisPtr->link != NULL) { - Blt_Chain_DeleteLink(axisPtr->chain, axisPtr->link); - } - if (axisPtr->obj.name != NULL) { - free((void*)(axisPtr->obj.name)); - } - if (axisPtr->hashPtr != NULL) { - Tcl_DeleteHashEntry(axisPtr->hashPtr); - } - Blt_Ts_FreeStyle(graphPtr->display, &axisPtr->limitsTextStyle); - - if (axisPtr->tickGC != NULL) { - Tk_FreeGC(graphPtr->display, axisPtr->tickGC); - } - if (axisPtr->activeTickGC != NULL) { - Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC); - } - if (axisPtr->major.gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc); - } - if (axisPtr->minor.gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc); - } - FreeTickLabels(axisPtr->tickLabels); - Blt_Chain_Destroy(axisPtr->tickLabels); - if (axisPtr->segments != NULL) { - free(axisPtr->segments); - } - free(axisPtr); - axisPtr = NULL; + Graph *graphPtr = axisPtr->obj.graphPtr; + int flags; + + flags = Blt_GraphType(graphPtr); + Blt_FreeOptions(configSpecs, (char *)axisPtr, graphPtr->display, flags); + if (graphPtr->bindTable != NULL) { + Blt_DeleteBindings(graphPtr->bindTable, axisPtr); + } + if (axisPtr->link != NULL) { + Blt_Chain_DeleteLink(axisPtr->chain, axisPtr->link); + } + if (axisPtr->obj.name != NULL) { + free((void*)(axisPtr->obj.name)); + } + if (axisPtr->hashPtr != NULL) { + Tcl_DeleteHashEntry(axisPtr->hashPtr); + } + Blt_Ts_FreeStyle(graphPtr->display, &axisPtr->limitsTextStyle); + + if (axisPtr->tickGC != NULL) { + Tk_FreeGC(graphPtr->display, axisPtr->tickGC); + } + if (axisPtr->activeTickGC != NULL) { + Tk_FreeGC(graphPtr->display, axisPtr->activeTickGC); + } + if (axisPtr->major.gc != NULL) { + Blt_FreePrivateGC(graphPtr->display, axisPtr->major.gc); + } + if (axisPtr->minor.gc != NULL) { + Blt_FreePrivateGC(graphPtr->display, axisPtr->minor.gc); + } + FreeTickLabels(axisPtr->tickLabels); + Blt_Chain_Destroy(axisPtr->tickLabels); + if (axisPtr->segments != NULL) { + free(axisPtr->segments); + } + free(axisPtr); + axisPtr = NULL; } static void FreeAxis(char* data) { - Axis *axisPtr = (Axis *)data; - DestroyAxis(axisPtr); + Axis *axisPtr = (Axis *)data; + DestroyAxis(axisPtr); } static float titleAngle[4] = /* Rotation for each axis title */ -{ + { 0.0, 90.0, 0.0, 270.0 -}; + }; /* *--------------------------------------------------------------------------- @@ -2226,435 +2230,435 @@ static float titleAngle[4] = /* Rotation for each axis title */ */ static void AxisOffsets( - Axis *axisPtr, - int margin, - int offset, - AxisInfo *infoPtr) + Axis *axisPtr, + int margin, + int offset, + AxisInfo *infoPtr) { - Graph *graphPtr = axisPtr->obj.graphPtr; - Margin *marginPtr; - int pad; /* Offset of axis from interior + Graph *graphPtr = axisPtr->obj.graphPtr; + Margin *marginPtr; + int pad; /* Offset of axis from interior * region. This includes a possible * border and the axis line width. */ - int axisLine; - int t1, t2, labelOffset; - int tickLabel, axisPad; - int inset, mark; - int x, y; - float fangle; - - axisPtr->titleAngle = titleAngle[margin]; - marginPtr = graphPtr->margins + margin; - - tickLabel = axisLine = t1 = t2 = 0; - labelOffset = AXIS_PAD_TITLE; - if (axisPtr->lineWidth > 0) { - if (axisPtr->flags & AXIS_SHOWTICKS) { - t1 = axisPtr->tickLength; - t2 = (t1 * 10) / 15; - } - labelOffset = t1 + AXIS_PAD_TITLE; - if (axisPtr->flags & AXIS_EXTERIOR) { - labelOffset += axisPtr->lineWidth; - } + int axisLine; + int t1, t2, labelOffset; + int tickLabel, axisPad; + int inset, mark; + int x, y; + float fangle; + + axisPtr->titleAngle = titleAngle[margin]; + marginPtr = graphPtr->margins + margin; + + tickLabel = axisLine = t1 = t2 = 0; + labelOffset = AXIS_PAD_TITLE; + if (axisPtr->lineWidth > 0) { + if (axisPtr->flags & AXIS_SHOWTICKS) { + t1 = axisPtr->tickLength; + t2 = (t1 * 10) / 15; } + labelOffset = t1 + AXIS_PAD_TITLE; + if (axisPtr->flags & AXIS_EXTERIOR) { + labelOffset += axisPtr->lineWidth; + } + } + axisPad = 0; + if (graphPtr->plotRelief != TK_RELIEF_SOLID) { axisPad = 0; - if (graphPtr->plotRelief != TK_RELIEF_SOLID) { - axisPad = 0; + } + /* Adjust offset for the interior border width and the line width */ + pad = 1; + if (graphPtr->plotBW > 0) { + pad += graphPtr->plotBW + 1; + } + pad = 0; /* FIXME: test */ + /* + * Pre-calculate the x-coordinate positions of the axis, tick labels, and + * the individual major and minor ticks. + */ + inset = pad + axisPtr->lineWidth / 2; + switch (margin) { + case MARGIN_TOP: + axisLine = graphPtr->top; + if (axisPtr->flags & AXIS_EXTERIOR) { + axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; + tickLabel = axisLine - 2; + if (axisPtr->lineWidth > 0) { + tickLabel -= axisPtr->tickLength; + } + } else { + if (graphPtr->plotRelief == TK_RELIEF_SOLID) { + axisLine--; + } + axisLine -= axisPad + axisPtr->lineWidth / 2; + tickLabel = graphPtr->top - graphPtr->plotBW - 2; + } + mark = graphPtr->top - offset - pad; + axisPtr->tickAnchor = TK_ANCHOR_S; + axisPtr->left = axisPtr->screenMin - inset - 2; + axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1; + if (graphPtr->stackAxes) { + axisPtr->top = mark - marginPtr->axesOffset; + } else { + axisPtr->top = mark - axisPtr->height; } - /* Adjust offset for the interior border width and the line width */ - pad = 1; - if (graphPtr->plotBW > 0) { - pad += graphPtr->plotBW + 1; + axisPtr->bottom = mark; + if (axisPtr->titleAlternate) { + x = graphPtr->right + AXIS_PAD_TITLE; + y = mark - (axisPtr->height / 2); + axisPtr->titleAnchor = TK_ANCHOR_W; + } else { + x = (axisPtr->right + axisPtr->left) / 2; + if (graphPtr->stackAxes) { + y = mark - marginPtr->axesOffset + AXIS_PAD_TITLE; + } else { + y = mark - axisPtr->height + AXIS_PAD_TITLE; + } + axisPtr->titleAnchor = TK_ANCHOR_N; + } + axisPtr->titlePos.x = x; + axisPtr->titlePos.y = y; + break; + + case MARGIN_BOTTOM: + /* + * ----------- bottom + plot borderwidth + * mark -------------------------------------------- + * ===================== axisLine (linewidth) + * tick + * title + * + * ===================== axisLine (linewidth) + * ----------- bottom + plot borderwidth + * mark -------------------------------------------- + * tick + * title + */ + axisLine = graphPtr->bottom; + if (graphPtr->plotRelief == TK_RELIEF_SOLID) { + axisLine++; + } + if (axisPtr->flags & AXIS_EXTERIOR) { + axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; + tickLabel = axisLine + 2; + if (axisPtr->lineWidth > 0) { + tickLabel += axisPtr->tickLength; + } + } else { + axisLine -= axisPad + axisPtr->lineWidth / 2; + tickLabel = graphPtr->bottom + graphPtr->plotBW + 2; + } + mark = graphPtr->bottom + offset; + fangle = fmod(axisPtr->tickAngle, 90.0); + if (fangle == 0.0) { + axisPtr->tickAnchor = TK_ANCHOR_N; + } else { + int quadrant; + + quadrant = (int)(axisPtr->tickAngle / 90.0); + if ((quadrant == 0) || (quadrant == 2)) { + axisPtr->tickAnchor = TK_ANCHOR_NE; + } else { + axisPtr->tickAnchor = TK_ANCHOR_NW; + } + } + axisPtr->left = axisPtr->screenMin - inset - 2; + axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1; + axisPtr->top = graphPtr->bottom + labelOffset - t1; + if (graphPtr->stackAxes) { + axisPtr->bottom = mark + marginPtr->axesOffset - 1; + } else { + axisPtr->bottom = mark + axisPtr->height - 1; } - pad = 0; /* FIXME: test */ + if (axisPtr->titleAlternate) { + x = graphPtr->right + AXIS_PAD_TITLE; + y = mark + (axisPtr->height / 2); + axisPtr->titleAnchor = TK_ANCHOR_W; + } else { + x = (axisPtr->right + axisPtr->left) / 2; + if (graphPtr->stackAxes) { + y = mark + marginPtr->axesOffset - AXIS_PAD_TITLE; + } else { + y = mark + axisPtr->height - AXIS_PAD_TITLE; + } + axisPtr->titleAnchor = TK_ANCHOR_S; + } + axisPtr->titlePos.x = x; + axisPtr->titlePos.y = y; + break; + + case MARGIN_LEFT: /* - * Pre-calculate the x-coordinate positions of the axis, tick labels, and - * the individual major and minor ticks. + * mark + * | : + * | : + * | : + * | : + * | : + * axisLine */ - inset = pad + axisPtr->lineWidth / 2; - switch (margin) { - case MARGIN_TOP: - axisLine = graphPtr->top; - if (axisPtr->flags & AXIS_EXTERIOR) { - axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; - tickLabel = axisLine - 2; - if (axisPtr->lineWidth > 0) { - tickLabel -= axisPtr->tickLength; - } - } else { - if (graphPtr->plotRelief == TK_RELIEF_SOLID) { - axisLine--; - } - axisLine -= axisPad + axisPtr->lineWidth / 2; - tickLabel = graphPtr->top - graphPtr->plotBW - 2; - } - mark = graphPtr->top - offset - pad; - axisPtr->tickAnchor = TK_ANCHOR_S; - axisPtr->left = axisPtr->screenMin - inset - 2; - axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1; - if (graphPtr->stackAxes) { - axisPtr->top = mark - marginPtr->axesOffset; - } else { - axisPtr->top = mark - axisPtr->height; - } - axisPtr->bottom = mark; - if (axisPtr->titleAlternate) { - x = graphPtr->right + AXIS_PAD_TITLE; - y = mark - (axisPtr->height / 2); - axisPtr->titleAnchor = TK_ANCHOR_W; - } else { - x = (axisPtr->right + axisPtr->left) / 2; - if (graphPtr->stackAxes) { - y = mark - marginPtr->axesOffset + AXIS_PAD_TITLE; - } else { - y = mark - axisPtr->height + AXIS_PAD_TITLE; - } - axisPtr->titleAnchor = TK_ANCHOR_N; - } - axisPtr->titlePos.x = x; - axisPtr->titlePos.y = y; - break; - - case MARGIN_BOTTOM: - /* - * ----------- bottom + plot borderwidth - * mark -------------------------------------------- - * ===================== axisLine (linewidth) - * tick - * title - * - * ===================== axisLine (linewidth) - * ----------- bottom + plot borderwidth - * mark -------------------------------------------- - * tick - * title - */ - axisLine = graphPtr->bottom; - if (graphPtr->plotRelief == TK_RELIEF_SOLID) { - axisLine++; - } - if (axisPtr->flags & AXIS_EXTERIOR) { - axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; - tickLabel = axisLine + 2; - if (axisPtr->lineWidth > 0) { - tickLabel += axisPtr->tickLength; - } - } else { - axisLine -= axisPad + axisPtr->lineWidth / 2; - tickLabel = graphPtr->bottom + graphPtr->plotBW + 2; - } - mark = graphPtr->bottom + offset; - fangle = fmod(axisPtr->tickAngle, 90.0); - if (fangle == 0.0) { - axisPtr->tickAnchor = TK_ANCHOR_N; - } else { - int quadrant; - - quadrant = (int)(axisPtr->tickAngle / 90.0); - if ((quadrant == 0) || (quadrant == 2)) { - axisPtr->tickAnchor = TK_ANCHOR_NE; - } else { - axisPtr->tickAnchor = TK_ANCHOR_NW; - } - } - axisPtr->left = axisPtr->screenMin - inset - 2; - axisPtr->right = axisPtr->screenMin + axisPtr->screenRange + inset - 1; - axisPtr->top = graphPtr->bottom + labelOffset - t1; - if (graphPtr->stackAxes) { - axisPtr->bottom = mark + marginPtr->axesOffset - 1; - } else { - axisPtr->bottom = mark + axisPtr->height - 1; - } - if (axisPtr->titleAlternate) { - x = graphPtr->right + AXIS_PAD_TITLE; - y = mark + (axisPtr->height / 2); - axisPtr->titleAnchor = TK_ANCHOR_W; - } else { - x = (axisPtr->right + axisPtr->left) / 2; - if (graphPtr->stackAxes) { - y = mark + marginPtr->axesOffset - AXIS_PAD_TITLE; - } else { - y = mark + axisPtr->height - AXIS_PAD_TITLE; - } - axisPtr->titleAnchor = TK_ANCHOR_S; - } - axisPtr->titlePos.x = x; - axisPtr->titlePos.y = y; - break; - - case MARGIN_LEFT: - /* - * mark - * | : - * | : - * | : - * | : - * | : - * axisLine - */ - /* - * Exterior axis - * + plotarea right - * |A|B|C|D|E|F|G|H - * |right - * A = plot pad - * B = plot border width - * C = axis pad - * D = axis line - * E = tick length - * F = tick label - * G = graph border width - * H = highlight thickness - */ - /* - * Interior axis - * + plotarea right - * |A|B|C|D|E|F|G|H - * |right - * A = plot pad - * B = tick length - * C = axis line width - * D = axis pad - * E = plot border width - * F = tick label - * G = graph border width - * H = highlight thickness - */ - axisLine = graphPtr->left; - if (axisPtr->flags & AXIS_EXTERIOR) { - axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; - tickLabel = axisLine - 2; - if (axisPtr->lineWidth > 0) { - tickLabel -= axisPtr->tickLength; - } - } else { - if (graphPtr->plotRelief == TK_RELIEF_SOLID) { - axisLine--; - } - axisLine += axisPad + axisPtr->lineWidth / 2; - tickLabel = graphPtr->left - graphPtr->plotBW - 2; - } - mark = graphPtr->left - offset; - axisPtr->tickAnchor = TK_ANCHOR_E; - if (graphPtr->stackAxes) { - axisPtr->left = mark - marginPtr->axesOffset; - } else { - axisPtr->left = mark - axisPtr->width; - } - axisPtr->right = mark - 3; - axisPtr->top = axisPtr->screenMin - inset - 2; - axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset - 1; - if (axisPtr->titleAlternate) { - x = mark - (axisPtr->width / 2); - y = graphPtr->top - AXIS_PAD_TITLE; - axisPtr->titleAnchor = TK_ANCHOR_SW; - } else { - if (graphPtr->stackAxes) { - x = mark - marginPtr->axesOffset; - } else { - x = mark - axisPtr->width + AXIS_PAD_TITLE; - } - y = (axisPtr->bottom + axisPtr->top) / 2; - axisPtr->titleAnchor = TK_ANCHOR_W; - } - axisPtr->titlePos.x = x; - axisPtr->titlePos.y = y; - break; - - case MARGIN_RIGHT: - axisLine = graphPtr->right; - if (graphPtr->plotRelief == TK_RELIEF_SOLID) { - axisLine++; /* Draw axis line within solid plot + /* + * Exterior axis + * + plotarea right + * |A|B|C|D|E|F|G|H + * |right + * A = plot pad + * B = plot border width + * C = axis pad + * D = axis line + * E = tick length + * F = tick label + * G = graph border width + * H = highlight thickness + */ + /* + * Interior axis + * + plotarea right + * |A|B|C|D|E|F|G|H + * |right + * A = plot pad + * B = tick length + * C = axis line width + * D = axis pad + * E = plot border width + * F = tick label + * G = graph border width + * H = highlight thickness + */ + axisLine = graphPtr->left; + if (axisPtr->flags & AXIS_EXTERIOR) { + axisLine -= graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; + tickLabel = axisLine - 2; + if (axisPtr->lineWidth > 0) { + tickLabel -= axisPtr->tickLength; + } + } else { + if (graphPtr->plotRelief == TK_RELIEF_SOLID) { + axisLine--; + } + axisLine += axisPad + axisPtr->lineWidth / 2; + tickLabel = graphPtr->left - graphPtr->plotBW - 2; + } + mark = graphPtr->left - offset; + axisPtr->tickAnchor = TK_ANCHOR_E; + if (graphPtr->stackAxes) { + axisPtr->left = mark - marginPtr->axesOffset; + } else { + axisPtr->left = mark - axisPtr->width; + } + axisPtr->right = mark - 3; + axisPtr->top = axisPtr->screenMin - inset - 2; + axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset - 1; + if (axisPtr->titleAlternate) { + x = mark - (axisPtr->width / 2); + y = graphPtr->top - AXIS_PAD_TITLE; + axisPtr->titleAnchor = TK_ANCHOR_SW; + } else { + if (graphPtr->stackAxes) { + x = mark - marginPtr->axesOffset; + } else { + x = mark - axisPtr->width + AXIS_PAD_TITLE; + } + y = (axisPtr->bottom + axisPtr->top) / 2; + axisPtr->titleAnchor = TK_ANCHOR_W; + } + axisPtr->titlePos.x = x; + axisPtr->titlePos.y = y; + break; + + case MARGIN_RIGHT: + axisLine = graphPtr->right; + if (graphPtr->plotRelief == TK_RELIEF_SOLID) { + axisLine++; /* Draw axis line within solid plot * border. */ - } - if (axisPtr->flags & AXIS_EXTERIOR) { - axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; - tickLabel = axisLine + 2; - if (axisPtr->lineWidth > 0) { - tickLabel += axisPtr->tickLength; - } - } else { - axisLine -= axisPad + axisPtr->lineWidth / 2; - tickLabel = graphPtr->right + graphPtr->plotBW + 2; - } - mark = graphPtr->right + offset + pad; - axisPtr->tickAnchor = TK_ANCHOR_W; - axisPtr->left = mark; - if (graphPtr->stackAxes) { - axisPtr->right = mark + marginPtr->axesOffset - 1; - } else { - axisPtr->right = mark + axisPtr->width - 1; - } - axisPtr->top = axisPtr->screenMin - inset - 2; - axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset -1; - if (axisPtr->titleAlternate) { - x = mark + (axisPtr->width / 2); - y = graphPtr->top - AXIS_PAD_TITLE; - axisPtr->titleAnchor = TK_ANCHOR_SE; - } else { - if (graphPtr->stackAxes) { - x = mark + marginPtr->axesOffset - AXIS_PAD_TITLE; - } else { - x = mark + axisPtr->width - AXIS_PAD_TITLE; - } - y = (axisPtr->bottom + axisPtr->top) / 2; - axisPtr->titleAnchor = TK_ANCHOR_E; - } - axisPtr->titlePos.x = x; - axisPtr->titlePos.y = y; - break; - - case MARGIN_NONE: - axisLine = 0; - break; - } - if ((margin == MARGIN_LEFT) || (margin == MARGIN_TOP)) { - t1 = -t1, t2 = -t2; - labelOffset = -labelOffset; - } - infoPtr->axis = axisLine; - infoPtr->t1 = axisLine + t1; - infoPtr->t2 = axisLine + t2; - if (tickLabel > 0) { - infoPtr->label = tickLabel; + } + if (axisPtr->flags & AXIS_EXTERIOR) { + axisLine += graphPtr->plotBW + axisPad + axisPtr->lineWidth / 2; + tickLabel = axisLine + 2; + if (axisPtr->lineWidth > 0) { + tickLabel += axisPtr->tickLength; + } } else { - infoPtr->label = axisLine + labelOffset; + axisLine -= axisPad + axisPtr->lineWidth / 2; + tickLabel = graphPtr->right + graphPtr->plotBW + 2; } - if ((axisPtr->flags & AXIS_EXTERIOR) == 0) { - /*infoPtr->label = axisLine + labelOffset - t1; */ - infoPtr->t1 = axisLine - t1; - infoPtr->t2 = axisLine - t2; - } + mark = graphPtr->right + offset + pad; + axisPtr->tickAnchor = TK_ANCHOR_W; + axisPtr->left = mark; + if (graphPtr->stackAxes) { + axisPtr->right = mark + marginPtr->axesOffset - 1; + } else { + axisPtr->right = mark + axisPtr->width - 1; + } + axisPtr->top = axisPtr->screenMin - inset - 2; + axisPtr->bottom = axisPtr->screenMin + axisPtr->screenRange + inset -1; + if (axisPtr->titleAlternate) { + x = mark + (axisPtr->width / 2); + y = graphPtr->top - AXIS_PAD_TITLE; + axisPtr->titleAnchor = TK_ANCHOR_SE; + } else { + if (graphPtr->stackAxes) { + x = mark + marginPtr->axesOffset - AXIS_PAD_TITLE; + } else { + x = mark + axisPtr->width - AXIS_PAD_TITLE; + } + y = (axisPtr->bottom + axisPtr->top) / 2; + axisPtr->titleAnchor = TK_ANCHOR_E; + } + axisPtr->titlePos.x = x; + axisPtr->titlePos.y = y; + break; + + case MARGIN_NONE: + axisLine = 0; + break; + } + if ((margin == MARGIN_LEFT) || (margin == MARGIN_TOP)) { + t1 = -t1, t2 = -t2; + labelOffset = -labelOffset; + } + infoPtr->axis = axisLine; + infoPtr->t1 = axisLine + t1; + infoPtr->t2 = axisLine + t2; + if (tickLabel > 0) { + infoPtr->label = tickLabel; + } else { + infoPtr->label = axisLine + labelOffset; + } + if ((axisPtr->flags & AXIS_EXTERIOR) == 0) { + /*infoPtr->label = axisLine + labelOffset - t1; */ + infoPtr->t1 = axisLine - t1; + infoPtr->t2 = axisLine - t2; + } } static void MakeAxisLine(Axis *axisPtr, int line, Segment2d *sp) { - double min, max; - - min = axisPtr->axisRange.min; - max = axisPtr->axisRange.max; - if (axisPtr->logScale) { - min = EXP10(min); - max = EXP10(max); - } - if (AxisIsHorizontal(axisPtr)) { - sp->p.x = Blt_HMap(axisPtr, min); - sp->q.x = Blt_HMap(axisPtr, max); - sp->p.y = sp->q.y = line; - } else { - sp->q.x = sp->p.x = line; - sp->p.y = Blt_VMap(axisPtr, min); - sp->q.y = Blt_VMap(axisPtr, max); - } + double min, max; + + min = axisPtr->axisRange.min; + max = axisPtr->axisRange.max; + if (axisPtr->logScale) { + min = EXP10(min); + max = EXP10(max); + } + if (AxisIsHorizontal(axisPtr)) { + sp->p.x = Blt_HMap(axisPtr, min); + sp->q.x = Blt_HMap(axisPtr, max); + sp->p.y = sp->q.y = line; + } else { + sp->q.x = sp->p.x = line; + sp->p.y = Blt_VMap(axisPtr, min); + sp->q.y = Blt_VMap(axisPtr, max); + } } static void MakeTick(Axis *axisPtr, double value, int tick, int line, Segment2d *sp) { - if (axisPtr->logScale) { - value = EXP10(value); - } - if (AxisIsHorizontal(axisPtr)) { - sp->p.x = sp->q.x = Blt_HMap(axisPtr, value); - sp->p.y = line; - sp->q.y = tick; - } else { - sp->p.x = line; - sp->p.y = sp->q.y = Blt_VMap(axisPtr, value); - sp->q.x = tick; - } + if (axisPtr->logScale) { + value = EXP10(value); + } + if (AxisIsHorizontal(axisPtr)) { + sp->p.x = sp->q.x = Blt_HMap(axisPtr, value); + sp->p.y = line; + sp->q.y = tick; + } else { + sp->p.x = line; + sp->p.y = sp->q.y = Blt_VMap(axisPtr, value); + sp->q.x = tick; + } } static void MakeSegments(Axis *axisPtr, AxisInfo *infoPtr) { - int arraySize; - int nMajorTicks, nMinorTicks; - Segment2d *segments; - Segment2d *sp; - - if (axisPtr->segments != NULL) { - free(axisPtr->segments); - axisPtr->segments = NULL; - } - nMajorTicks = nMinorTicks = 0; - if (axisPtr->t1Ptr != NULL) { - nMajorTicks = axisPtr->t1Ptr->nTicks; - } - if (axisPtr->t2Ptr != NULL) { - nMinorTicks = axisPtr->t2Ptr->nTicks; - } - arraySize = 1 + (nMajorTicks * (nMinorTicks + 1)); - segments = malloc(arraySize * sizeof(Segment2d)); - sp = segments; - if (axisPtr->lineWidth > 0) { - /* Axis baseline */ - MakeAxisLine(axisPtr, infoPtr->axis, sp); - sp++; - } - if (axisPtr->flags & AXIS_SHOWTICKS) { - Blt_ChainLink link; - double labelPos; - int i; - int isHoriz; - - isHoriz = AxisIsHorizontal(axisPtr); - for (i = 0; i < nMajorTicks; i++) { - double t1, t2; - int j; - - t1 = axisPtr->t1Ptr->values[i]; - /* Minor ticks */ - for (j = 0; j < nMinorTicks; j++) { - t2 = t1 + (axisPtr->majorSweep.step * - axisPtr->t2Ptr->values[j]); - if (InRange(t2, &axisPtr->axisRange)) { - MakeTick(axisPtr, t2, infoPtr->t2, infoPtr->axis, sp); - sp++; - } - } - if (!InRange(t1, &axisPtr->axisRange)) { - continue; - } - /* Major tick */ - MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, sp); - sp++; - } + int arraySize; + int nMajorTicks, nMinorTicks; + Segment2d *segments; + Segment2d *sp; + + if (axisPtr->segments != NULL) { + free(axisPtr->segments); + axisPtr->segments = NULL; + } + nMajorTicks = nMinorTicks = 0; + if (axisPtr->t1Ptr != NULL) { + nMajorTicks = axisPtr->t1Ptr->nTicks; + } + if (axisPtr->t2Ptr != NULL) { + nMinorTicks = axisPtr->t2Ptr->nTicks; + } + arraySize = 1 + (nMajorTicks * (nMinorTicks + 1)); + segments = malloc(arraySize * sizeof(Segment2d)); + sp = segments; + if (axisPtr->lineWidth > 0) { + /* Axis baseline */ + MakeAxisLine(axisPtr, infoPtr->axis, sp); + sp++; + } + if (axisPtr->flags & AXIS_SHOWTICKS) { + Blt_ChainLink link; + double labelPos; + int i; + int isHoriz; - link = Blt_Chain_FirstLink(axisPtr->tickLabels); - labelPos = (double)infoPtr->label; - - for (i = 0; i < nMajorTicks; i++) { - double t1; - TickLabel *labelPtr; - Segment2d seg; - - t1 = axisPtr->t1Ptr->values[i]; - if (axisPtr->labelOffset) { - t1 += axisPtr->majorSweep.step * 0.5; - } - if (!InRange(t1, &axisPtr->axisRange)) { - continue; - } - labelPtr = Blt_Chain_GetValue(link); - link = Blt_Chain_NextLink(link); - MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, &seg); - /* Save tick label X-Y position. */ - if (isHoriz) { - labelPtr->anchorPos.x = seg.p.x; - labelPtr->anchorPos.y = labelPos; - } else { - labelPtr->anchorPos.x = labelPos; - labelPtr->anchorPos.y = seg.p.y; - } - } - } - axisPtr->segments = segments; - axisPtr->nSegments = sp - segments; - assert(axisPtr->nSegments <= arraySize); + isHoriz = AxisIsHorizontal(axisPtr); + for (i = 0; i < nMajorTicks; i++) { + double t1, t2; + int j; + + t1 = axisPtr->t1Ptr->values[i]; + /* Minor ticks */ + for (j = 0; j < nMinorTicks; j++) { + t2 = t1 + (axisPtr->majorSweep.step * + axisPtr->t2Ptr->values[j]); + if (InRange(t2, &axisPtr->axisRange)) { + MakeTick(axisPtr, t2, infoPtr->t2, infoPtr->axis, sp); + sp++; + } + } + if (!InRange(t1, &axisPtr->axisRange)) { + continue; + } + /* Major tick */ + MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, sp); + sp++; + } + + link = Blt_Chain_FirstLink(axisPtr->tickLabels); + labelPos = (double)infoPtr->label; + + for (i = 0; i < nMajorTicks; i++) { + double t1; + TickLabel *labelPtr; + Segment2d seg; + + t1 = axisPtr->t1Ptr->values[i]; + if (axisPtr->labelOffset) { + t1 += axisPtr->majorSweep.step * 0.5; + } + if (!InRange(t1, &axisPtr->axisRange)) { + continue; + } + labelPtr = Blt_Chain_GetValue(link); + link = Blt_Chain_NextLink(link); + MakeTick(axisPtr, t1, infoPtr->t1, infoPtr->axis, &seg); + /* Save tick label X-Y position. */ + if (isHoriz) { + labelPtr->anchorPos.x = seg.p.x; + labelPtr->anchorPos.y = labelPos; + } else { + labelPtr->anchorPos.x = labelPos; + labelPtr->anchorPos.y = seg.p.y; + } + } + } + axisPtr->segments = segments; + axisPtr->nSegments = sp - segments; + assert(axisPtr->nSegments <= arraySize); } /* @@ -2683,21 +2687,21 @@ MakeSegments(Axis *axisPtr, AxisInfo *infoPtr) static void MapAxis(Axis *axisPtr, int offset, int margin) { - AxisInfo info; - Graph *graphPtr = axisPtr->obj.graphPtr; - - if (AxisIsHorizontal(axisPtr)) { - axisPtr->screenMin = graphPtr->hOffset; - axisPtr->width = graphPtr->right - graphPtr->left; - axisPtr->screenRange = graphPtr->hRange; - } else { - axisPtr->screenMin = graphPtr->vOffset; - axisPtr->height = graphPtr->bottom - graphPtr->top; - axisPtr->screenRange = graphPtr->vRange; - } - axisPtr->screenScale = 1.0 / axisPtr->screenRange; - AxisOffsets(axisPtr, margin, offset, &info); - MakeSegments(axisPtr, &info); + AxisInfo info; + Graph *graphPtr = axisPtr->obj.graphPtr; + + if (AxisIsHorizontal(axisPtr)) { + axisPtr->screenMin = graphPtr->hOffset; + axisPtr->width = graphPtr->right - graphPtr->left; + axisPtr->screenRange = graphPtr->hRange; + } else { + axisPtr->screenMin = graphPtr->vOffset; + axisPtr->height = graphPtr->bottom - graphPtr->top; + axisPtr->screenRange = graphPtr->vRange; + } + axisPtr->screenScale = 1.0 / axisPtr->screenRange; + AxisOffsets(axisPtr, margin, offset, &info); + MakeSegments(axisPtr, &info); } /* @@ -2726,30 +2730,30 @@ MapAxis(Axis *axisPtr, int offset, int margin) static void MapStackedAxis(Axis *axisPtr, int count, int margin) { - AxisInfo info; - Graph *graphPtr = axisPtr->obj.graphPtr; - unsigned int slice, w, h; - - if ((graphPtr->margins[axisPtr->margin].axes->nLinks > 1) || - (axisPtr->reqNumMajorTicks <= 0)) { - axisPtr->reqNumMajorTicks = 4; - } - if (AxisIsHorizontal(axisPtr)) { - slice = graphPtr->hRange / graphPtr->margins[margin].axes->nLinks; - axisPtr->screenMin = graphPtr->hOffset; - axisPtr->width = slice; - } else { - slice = graphPtr->vRange / graphPtr->margins[margin].axes->nLinks; - axisPtr->screenMin = graphPtr->vOffset; - axisPtr->height = slice; - } + AxisInfo info; + Graph *graphPtr = axisPtr->obj.graphPtr; + unsigned int slice, w, h; + + if ((graphPtr->margins[axisPtr->margin].axes->nLinks > 1) || + (axisPtr->reqNumMajorTicks <= 0)) { + axisPtr->reqNumMajorTicks = 4; + } + if (AxisIsHorizontal(axisPtr)) { + slice = graphPtr->hRange / graphPtr->margins[margin].axes->nLinks; + axisPtr->screenMin = graphPtr->hOffset; + axisPtr->width = slice; + } else { + slice = graphPtr->vRange / graphPtr->margins[margin].axes->nLinks; + axisPtr->screenMin = graphPtr->vOffset; + axisPtr->height = slice; + } #define AXIS_PAD 2 - Blt_GetTextExtents(axisPtr->tickFont, 0, "0", 1, &w, &h); - axisPtr->screenMin += (slice * count) + AXIS_PAD + h / 2; - axisPtr->screenRange = slice - 2 * AXIS_PAD - h; - axisPtr->screenScale = 1.0f / axisPtr->screenRange; - AxisOffsets(axisPtr, margin, 0, &info); - MakeSegments(axisPtr, &info); + Blt_GetTextExtents(axisPtr->tickFont, 0, "0", 1, &w, &h); + axisPtr->screenMin += (slice * count) + AXIS_PAD + h / 2; + axisPtr->screenRange = slice - 2 * AXIS_PAD - h; + axisPtr->screenScale = 1.0f / axisPtr->screenRange; + AxisOffsets(axisPtr, margin, 0, &info); + MakeSegments(axisPtr, &info); } /* @@ -2781,93 +2785,93 @@ MapStackedAxis(Axis *axisPtr, int count, int margin) static double AdjustViewport(double offset, double windowSize) { - /* - * Canvas-style scrolling allows the world to be scrolled within the window. - */ - if (windowSize > 1.0) { - if (windowSize < (1.0 - offset)) { - offset = 1.0 - windowSize; - } - if (offset > 0.0) { - offset = 0.0; - } - } else { - if ((offset + windowSize) > 1.0) { - offset = 1.0 - windowSize; - } - if (offset < 0.0) { - offset = 0.0; - } + /* + * Canvas-style scrolling allows the world to be scrolled within the window. + */ + if (windowSize > 1.0) { + if (windowSize < (1.0 - offset)) { + offset = 1.0 - windowSize; + } + if (offset > 0.0) { + offset = 0.0; } - return offset; + } else { + if ((offset + windowSize) > 1.0) { + offset = 1.0 - windowSize; + } + if (offset < 0.0) { + offset = 0.0; + } + } + return offset; } static int GetAxisScrollInfo( - Tcl_Interp *interp, - int objc, - Tcl_Obj *const *objv, - double *offsetPtr, - double windowSize, - double scrollUnits, - double scale) + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv, + double *offsetPtr, + double windowSize, + double scrollUnits, + double scale) { - const char *string; - char c; - double offset; - int length; + const char *string; + char c; + double offset; + int length; + + offset = *offsetPtr; + string = Tcl_GetStringFromObj(objv[0], &length); + c = string[0]; + scrollUnits *= scale; + if ((c == 's') && (strncmp(string, "scroll", length) == 0)) { + int count; + double fract; - offset = *offsetPtr; - string = Tcl_GetStringFromObj(objv[0], &length); + assert(objc == 3); + /* Scroll number unit/page */ + if (Tcl_GetIntFromObj(interp, objv[1], &count) != TCL_OK) { + return TCL_ERROR; + } + string = Tcl_GetStringFromObj(objv[2], &length); c = string[0]; - scrollUnits *= scale; - if ((c == 's') && (strncmp(string, "scroll", length) == 0)) { - int count; - double fract; - - assert(objc == 3); - /* Scroll number unit/page */ - if (Tcl_GetIntFromObj(interp, objv[1], &count) != TCL_OK) { - return TCL_ERROR; - } - string = Tcl_GetStringFromObj(objv[2], &length); - c = string[0]; - if ((c == 'u') && (strncmp(string, "units", length) == 0)) { - fract = count * scrollUnits; - } else if ((c == 'p') && (strncmp(string, "pages", length) == 0)) { - /* A page is 90% of the view-able window. */ - fract = (int)(count * windowSize * 0.9 + 0.5); - } else if ((c == 'p') && (strncmp(string, "pixels", length) == 0)) { - fract = count * scale; - } else { - Tcl_AppendResult(interp, "unknown \"scroll\" units \"", string, - "\"", (char *)NULL); - return TCL_ERROR; - } - offset += fract; - } else if ((c == 'm') && (strncmp(string, "moveto", length) == 0)) { - double fract; - - assert(objc == 2); - /* moveto fraction */ - if (Tcl_GetDoubleFromObj(interp, objv[1], &fract) != TCL_OK) { - return TCL_ERROR; - } - offset = fract; + if ((c == 'u') && (strncmp(string, "units", length) == 0)) { + fract = count * scrollUnits; + } else if ((c == 'p') && (strncmp(string, "pages", length) == 0)) { + /* A page is 90% of the view-able window. */ + fract = (int)(count * windowSize * 0.9 + 0.5); + } else if ((c == 'p') && (strncmp(string, "pixels", length) == 0)) { + fract = count * scale; } else { - int count; - double fract; + Tcl_AppendResult(interp, "unknown \"scroll\" units \"", string, + "\"", (char *)NULL); + return TCL_ERROR; + } + offset += fract; + } else if ((c == 'm') && (strncmp(string, "moveto", length) == 0)) { + double fract; - /* Treat like "scroll units" */ - if (Tcl_GetIntFromObj(interp, objv[0], &count) != TCL_OK) { - return TCL_ERROR; - } - fract = (double)count * scrollUnits; - offset += fract; - /* CHECK THIS: return TCL_OK; */ + assert(objc == 2); + /* moveto fraction */ + if (Tcl_GetDoubleFromObj(interp, objv[1], &fract) != TCL_OK) { + return TCL_ERROR; } - *offsetPtr = AdjustViewport(offset, windowSize); - return TCL_OK; + offset = fract; + } else { + int count; + double fract; + + /* Treat like "scroll units" */ + if (Tcl_GetIntFromObj(interp, objv[0], &count) != TCL_OK) { + return TCL_ERROR; + } + fract = (double)count * scrollUnits; + offset += fract; + /* CHECK THIS: return TCL_OK; */ + } + *offsetPtr = AdjustViewport(offset, windowSize); + return TCL_OK; } /* @@ -2891,139 +2895,139 @@ GetAxisScrollInfo( static void DrawAxis(Axis *axisPtr, Drawable drawable) { - Graph *graphPtr = axisPtr->obj.graphPtr; - - if (axisPtr->normalBg != NULL) { - Tk_Fill3DRectangle(graphPtr->tkwin, drawable, - axisPtr->normalBg, - axisPtr->left, axisPtr->top, - axisPtr->right - axisPtr->left, - axisPtr->bottom - axisPtr->top, - axisPtr->borderWidth, - axisPtr->relief); - } - if (axisPtr->title != NULL) { - TextStyle ts; - - Blt_Ts_InitStyle(ts); - Blt_Ts_SetAngle(ts, axisPtr->titleAngle); - Blt_Ts_SetFont(ts, axisPtr->titleFont); - Blt_Ts_SetPadding(ts, 1, 0); - Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor); - Blt_Ts_SetJustify(ts, axisPtr->titleJustify); - if (axisPtr->flags & ACTIVE) { - Blt_Ts_SetForeground(ts, axisPtr->activeFgColor); - } else { - Blt_Ts_SetForeground(ts, axisPtr->titleColor); - } - Blt_Ts_SetForeground(ts, axisPtr->titleColor); - if ((axisPtr->titleAngle == 90.0) || (axisPtr->titleAngle == 270.0)) { - Blt_Ts_SetMaxLength(ts, axisPtr->height); - } else { - Blt_Ts_SetMaxLength(ts, axisPtr->width); - } - Blt_Ts_DrawText(graphPtr->tkwin, drawable, axisPtr->title, -1, &ts, - (int)axisPtr->titlePos.x, (int)axisPtr->titlePos.y); - } - if (axisPtr->scrollCmdObjPtr != NULL) { - double viewWidth, viewMin, viewMax; - double worldWidth, worldMin, worldMax; - double fract; - int isHoriz; - - worldMin = axisPtr->valueRange.min; - worldMax = axisPtr->valueRange.max; - if (!isnan(axisPtr->scrollMin)) { - worldMin = axisPtr->scrollMin; - } - if (!isnan(axisPtr->scrollMax)) { - worldMax = axisPtr->scrollMax; - } - viewMin = axisPtr->min; - viewMax = axisPtr->max; - if (viewMin < worldMin) { - viewMin = worldMin; - } - if (viewMax > worldMax) { - viewMax = worldMax; - } - if (axisPtr->logScale) { - worldMin = log10(worldMin); - worldMax = log10(worldMax); - viewMin = log10(viewMin); - viewMax = log10(viewMax); - } - worldWidth = worldMax - worldMin; - viewWidth = viewMax - viewMin; - isHoriz = AxisIsHorizontal(axisPtr); + Graph *graphPtr = axisPtr->obj.graphPtr; + + if (axisPtr->normalBg != NULL) { + Tk_Fill3DRectangle(graphPtr->tkwin, drawable, + axisPtr->normalBg, + axisPtr->left, axisPtr->top, + axisPtr->right - axisPtr->left, + axisPtr->bottom - axisPtr->top, + axisPtr->borderWidth, + axisPtr->relief); + } + if (axisPtr->title != NULL) { + TextStyle ts; + + Blt_Ts_InitStyle(ts); + Blt_Ts_SetAngle(ts, axisPtr->titleAngle); + Blt_Ts_SetFont(ts, axisPtr->titleFont); + Blt_Ts_SetPadding(ts, 1, 0); + Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor); + Blt_Ts_SetJustify(ts, axisPtr->titleJustify); + if (axisPtr->flags & ACTIVE) { + Blt_Ts_SetForeground(ts, axisPtr->activeFgColor); + } else { + Blt_Ts_SetForeground(ts, axisPtr->titleColor); + } + Blt_Ts_SetForeground(ts, axisPtr->titleColor); + if ((axisPtr->titleAngle == 90.0) || (axisPtr->titleAngle == 270.0)) { + Blt_Ts_SetMaxLength(ts, axisPtr->height); + } else { + Blt_Ts_SetMaxLength(ts, axisPtr->width); + } + Blt_Ts_DrawText(graphPtr->tkwin, drawable, axisPtr->title, -1, &ts, + (int)axisPtr->titlePos.x, (int)axisPtr->titlePos.y); + } + if (axisPtr->scrollCmdObjPtr != NULL) { + double viewWidth, viewMin, viewMax; + double worldWidth, worldMin, worldMax; + double fract; + int isHoriz; - if (isHoriz != axisPtr->descending) { - fract = (viewMin - worldMin) / worldWidth; - } else { - fract = (worldMax - viewMax) / worldWidth; - } - fract = AdjustViewport(fract, viewWidth / worldWidth); - - if (isHoriz != axisPtr->descending) { - viewMin = (fract * worldWidth); - axisPtr->min = viewMin + worldMin; - axisPtr->max = axisPtr->min + viewWidth; - viewMax = viewMin + viewWidth; - if (axisPtr->logScale) { - axisPtr->min = EXP10(axisPtr->min); - axisPtr->max = EXP10(axisPtr->max); - } - Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr, - viewMin, viewMax, worldWidth); - } else { - viewMax = (fract * worldWidth); - axisPtr->max = worldMax - viewMax; - axisPtr->min = axisPtr->max - viewWidth; - viewMin = viewMax + viewWidth; - if (axisPtr->logScale) { - axisPtr->min = EXP10(axisPtr->min); - axisPtr->max = EXP10(axisPtr->max); - } - Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr, - viewMax, viewMin, worldWidth); - } + worldMin = axisPtr->valueRange.min; + worldMax = axisPtr->valueRange.max; + if (!isnan(axisPtr->scrollMin)) { + worldMin = axisPtr->scrollMin; } - if (axisPtr->flags & AXIS_SHOWTICKS) { - Blt_ChainLink link; - TextStyle ts; - - Blt_Ts_InitStyle(ts); - Blt_Ts_SetAngle(ts, axisPtr->tickAngle); - Blt_Ts_SetFont(ts, axisPtr->tickFont); - Blt_Ts_SetPadding(ts, 2, 0); - Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor); - if (axisPtr->flags & ACTIVE) { - Blt_Ts_SetForeground(ts, axisPtr->activeFgColor); - } else { - Blt_Ts_SetForeground(ts, axisPtr->tickColor); - } - for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; - link = Blt_Chain_NextLink(link)) { - TickLabel *labelPtr; - - labelPtr = Blt_Chain_GetValue(link); - /* Draw major tick labels */ - Blt_DrawText(graphPtr->tkwin, drawable, labelPtr->string, &ts, - (int)labelPtr->anchorPos.x, (int)labelPtr->anchorPos.y); - } + if (!isnan(axisPtr->scrollMax)) { + worldMax = axisPtr->scrollMax; + } + viewMin = axisPtr->min; + viewMax = axisPtr->max; + if (viewMin < worldMin) { + viewMin = worldMin; + } + if (viewMax > worldMax) { + viewMax = worldMax; + } + if (axisPtr->logScale) { + worldMin = log10(worldMin); + worldMax = log10(worldMax); + viewMin = log10(viewMin); + viewMax = log10(viewMax); } - if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) { - GC gc; + worldWidth = worldMax - worldMin; + viewWidth = viewMax - viewMin; + isHoriz = AxisIsHorizontal(axisPtr); - if (axisPtr->flags & ACTIVE) { - gc = axisPtr->activeTickGC; - } else { - gc = axisPtr->tickGC; - } - /* Draw the tick marks and axis line. */ - Blt_Draw2DSegments(graphPtr->display, drawable, gc, axisPtr->segments, - axisPtr->nSegments); + if (isHoriz != axisPtr->descending) { + fract = (viewMin - worldMin) / worldWidth; + } else { + fract = (worldMax - viewMax) / worldWidth; + } + fract = AdjustViewport(fract, viewWidth / worldWidth); + + if (isHoriz != axisPtr->descending) { + viewMin = (fract * worldWidth); + axisPtr->min = viewMin + worldMin; + axisPtr->max = axisPtr->min + viewWidth; + viewMax = viewMin + viewWidth; + if (axisPtr->logScale) { + axisPtr->min = EXP10(axisPtr->min); + axisPtr->max = EXP10(axisPtr->max); + } + Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr, + viewMin, viewMax, worldWidth); + } else { + viewMax = (fract * worldWidth); + axisPtr->max = worldMax - viewMax; + axisPtr->min = axisPtr->max - viewWidth; + viewMin = viewMax + viewWidth; + if (axisPtr->logScale) { + axisPtr->min = EXP10(axisPtr->min); + axisPtr->max = EXP10(axisPtr->max); + } + Blt_UpdateScrollbar(graphPtr->interp, axisPtr->scrollCmdObjPtr, + viewMax, viewMin, worldWidth); + } + } + if (axisPtr->flags & AXIS_SHOWTICKS) { + Blt_ChainLink link; + TextStyle ts; + + Blt_Ts_InitStyle(ts); + Blt_Ts_SetAngle(ts, axisPtr->tickAngle); + Blt_Ts_SetFont(ts, axisPtr->tickFont); + Blt_Ts_SetPadding(ts, 2, 0); + Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor); + if (axisPtr->flags & ACTIVE) { + Blt_Ts_SetForeground(ts, axisPtr->activeFgColor); + } else { + Blt_Ts_SetForeground(ts, axisPtr->tickColor); } + for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; + link = Blt_Chain_NextLink(link)) { + TickLabel *labelPtr; + + labelPtr = Blt_Chain_GetValue(link); + /* Draw major tick labels */ + Blt_DrawText(graphPtr->tkwin, drawable, labelPtr->string, &ts, + (int)labelPtr->anchorPos.x, (int)labelPtr->anchorPos.y); + } + } + if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) { + GC gc; + + if (axisPtr->flags & ACTIVE) { + gc = axisPtr->activeTickGC; + } else { + gc = axisPtr->tickGC; + } + /* Draw the tick marks and axis line. */ + Blt_Draw2DSegments(graphPtr->display, drawable, gc, axisPtr->segments, + axisPtr->nSegments); + } } /* @@ -3048,71 +3052,71 @@ DrawAxis(Axis *axisPtr, Drawable drawable) static void AxisToPostScript(Blt_Ps ps, Axis *axisPtr) { - Blt_Ps_Format(ps, "%% Axis \"%s\"\n", axisPtr->obj.name); - if (axisPtr->normalBg != NULL) { - Blt_Ps_Fill3DRectangle(ps, axisPtr->normalBg, - (double)axisPtr->left, (double)axisPtr->top, - axisPtr->right - axisPtr->left, axisPtr->bottom - axisPtr->top, - axisPtr->borderWidth, axisPtr->relief); - } - if (axisPtr->title != NULL) { - TextStyle ts; - - Blt_Ts_InitStyle(ts); - Blt_Ts_SetAngle(ts, axisPtr->titleAngle); - Blt_Ts_SetFont(ts, axisPtr->titleFont); - Blt_Ts_SetPadding(ts, 1, 0); - Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor); - Blt_Ts_SetJustify(ts, axisPtr->titleJustify); - Blt_Ts_SetForeground(ts, axisPtr->titleColor); - Blt_Ps_DrawText(ps, axisPtr->title, &ts, axisPtr->titlePos.x, - axisPtr->titlePos.y); - } - if (axisPtr->flags & AXIS_SHOWTICKS) { - Blt_ChainLink link; - TextStyle ts; - - Blt_Ts_InitStyle(ts); - Blt_Ts_SetAngle(ts, axisPtr->tickAngle); - Blt_Ts_SetFont(ts, axisPtr->tickFont); - Blt_Ts_SetPadding(ts, 2, 0); - Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor); - Blt_Ts_SetForeground(ts, axisPtr->tickColor); - - for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; - link = Blt_Chain_NextLink(link)) { - TickLabel *labelPtr; - - labelPtr = Blt_Chain_GetValue(link); - Blt_Ps_DrawText(ps, labelPtr->string, &ts, labelPtr->anchorPos.x, - labelPtr->anchorPos.y); - } - } - if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) { - Blt_Ps_XSetLineAttributes(ps, axisPtr->tickColor, axisPtr->lineWidth, - (Blt_Dashes *)NULL, CapButt, JoinMiter); - Blt_Ps_Draw2DSegments(ps, axisPtr->segments, axisPtr->nSegments); - } + Blt_Ps_Format(ps, "%% Axis \"%s\"\n", axisPtr->obj.name); + if (axisPtr->normalBg != NULL) { + Blt_Ps_Fill3DRectangle(ps, axisPtr->normalBg, + (double)axisPtr->left, (double)axisPtr->top, + axisPtr->right - axisPtr->left, axisPtr->bottom - axisPtr->top, + axisPtr->borderWidth, axisPtr->relief); + } + if (axisPtr->title != NULL) { + TextStyle ts; + + Blt_Ts_InitStyle(ts); + Blt_Ts_SetAngle(ts, axisPtr->titleAngle); + Blt_Ts_SetFont(ts, axisPtr->titleFont); + Blt_Ts_SetPadding(ts, 1, 0); + Blt_Ts_SetAnchor(ts, axisPtr->titleAnchor); + Blt_Ts_SetJustify(ts, axisPtr->titleJustify); + Blt_Ts_SetForeground(ts, axisPtr->titleColor); + Blt_Ps_DrawText(ps, axisPtr->title, &ts, axisPtr->titlePos.x, + axisPtr->titlePos.y); + } + if (axisPtr->flags & AXIS_SHOWTICKS) { + Blt_ChainLink link; + TextStyle ts; + + Blt_Ts_InitStyle(ts); + Blt_Ts_SetAngle(ts, axisPtr->tickAngle); + Blt_Ts_SetFont(ts, axisPtr->tickFont); + Blt_Ts_SetPadding(ts, 2, 0); + Blt_Ts_SetAnchor(ts, axisPtr->tickAnchor); + Blt_Ts_SetForeground(ts, axisPtr->tickColor); + + for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; + link = Blt_Chain_NextLink(link)) { + TickLabel *labelPtr; + + labelPtr = Blt_Chain_GetValue(link); + Blt_Ps_DrawText(ps, labelPtr->string, &ts, labelPtr->anchorPos.x, + labelPtr->anchorPos.y); + } + } + if ((axisPtr->nSegments > 0) && (axisPtr->lineWidth > 0)) { + Blt_Ps_XSetLineAttributes(ps, axisPtr->tickColor, axisPtr->lineWidth, + (Blt_Dashes *)NULL, CapButt, JoinMiter); + Blt_Ps_Draw2DSegments(ps, axisPtr->segments, axisPtr->nSegments); + } } static void MakeGridLine(Axis *axisPtr, double value, Segment2d *sp) { - Graph *graphPtr = axisPtr->obj.graphPtr; - - if (axisPtr->logScale) { - value = EXP10(value); - } - /* Grid lines run orthogonally to the axis */ - if (AxisIsHorizontal(axisPtr)) { - sp->p.y = graphPtr->top; - sp->q.y = graphPtr->bottom; - sp->p.x = sp->q.x = Blt_HMap(axisPtr, value); - } else { - sp->p.x = graphPtr->left; - sp->q.x = graphPtr->right; - sp->p.y = sp->q.y = Blt_VMap(axisPtr, value); - } + Graph *graphPtr = axisPtr->obj.graphPtr; + + if (axisPtr->logScale) { + value = EXP10(value); + } + /* Grid lines run orthogonally to the axis */ + if (AxisIsHorizontal(axisPtr)) { + sp->p.y = graphPtr->top; + sp->q.y = graphPtr->bottom; + sp->p.x = sp->q.x = Blt_HMap(axisPtr, value); + } else { + sp->p.x = graphPtr->left; + sp->q.x = graphPtr->right; + sp->p.y = sp->q.y = Blt_VMap(axisPtr, value); + } } /* @@ -3132,79 +3136,79 @@ MakeGridLine(Axis *axisPtr, double value, Segment2d *sp) static void MapGridlines(Axis *axisPtr) { - Segment2d *s1, *s2; - Ticks *t1Ptr, *t2Ptr; - int needed; - int i; + Segment2d *s1, *s2; + Ticks *t1Ptr, *t2Ptr; + int needed; + int i; + + if (axisPtr == NULL) { + return; + } + t1Ptr = axisPtr->t1Ptr; + if (t1Ptr == NULL) { + t1Ptr = GenerateTicks(&axisPtr->majorSweep); + } + t2Ptr = axisPtr->t2Ptr; + if (t2Ptr == NULL) { + t2Ptr = GenerateTicks(&axisPtr->minorSweep); + } + needed = t1Ptr->nTicks; + if (axisPtr->flags & AXIS_GRIDMINOR) { + needed += (t1Ptr->nTicks * t2Ptr->nTicks); + } + if (needed == 0) { + return; + } + needed = t1Ptr->nTicks; + if (needed != axisPtr->major.nAllocated) { + if (axisPtr->major.segments != NULL) { + free(axisPtr->major.segments); + axisPtr->major.segments = NULL; + } + axisPtr->major.segments = malloc(sizeof(Segment2d) * needed); + axisPtr->major.nAllocated = needed; + } + needed = (t1Ptr->nTicks * t2Ptr->nTicks); + if (needed != axisPtr->minor.nAllocated) { + if (axisPtr->minor.segments != NULL) { + free(axisPtr->minor.segments); + axisPtr->minor.segments = NULL; + } + axisPtr->minor.segments = malloc(sizeof(Segment2d) * needed); + axisPtr->minor.nAllocated = needed; + } + s1 = axisPtr->major.segments, s2 = axisPtr->minor.segments; + for (i = 0; i < t1Ptr->nTicks; i++) { + double value; - if (axisPtr == NULL) { - return; - } - t1Ptr = axisPtr->t1Ptr; - if (t1Ptr == NULL) { - t1Ptr = GenerateTicks(&axisPtr->majorSweep); - } - t2Ptr = axisPtr->t2Ptr; - if (t2Ptr == NULL) { - t2Ptr = GenerateTicks(&axisPtr->minorSweep); - } - needed = t1Ptr->nTicks; + value = t1Ptr->values[i]; if (axisPtr->flags & AXIS_GRIDMINOR) { - needed += (t1Ptr->nTicks * t2Ptr->nTicks); - } - if (needed == 0) { - return; - } - needed = t1Ptr->nTicks; - if (needed != axisPtr->major.nAllocated) { - if (axisPtr->major.segments != NULL) { - free(axisPtr->major.segments); - axisPtr->major.segments = NULL; - } - axisPtr->major.segments = malloc(sizeof(Segment2d) * needed); - axisPtr->major.nAllocated = needed; - } - needed = (t1Ptr->nTicks * t2Ptr->nTicks); - if (needed != axisPtr->minor.nAllocated) { - if (axisPtr->minor.segments != NULL) { - free(axisPtr->minor.segments); - axisPtr->minor.segments = NULL; - } - axisPtr->minor.segments = malloc(sizeof(Segment2d) * needed); - axisPtr->minor.nAllocated = needed; - } - s1 = axisPtr->major.segments, s2 = axisPtr->minor.segments; - for (i = 0; i < t1Ptr->nTicks; i++) { - double value; - - value = t1Ptr->values[i]; - if (axisPtr->flags & AXIS_GRIDMINOR) { - int j; - - for (j = 0; j < t2Ptr->nTicks; j++) { - double subValue; - - subValue = value + (axisPtr->majorSweep.step * - t2Ptr->values[j]); - if (InRange(subValue, &axisPtr->axisRange)) { - MakeGridLine(axisPtr, subValue, s2); - s2++; - } - } - } - if (InRange(value, &axisPtr->axisRange)) { - MakeGridLine(axisPtr, value, s1); - s1++; - } - } - if (t1Ptr != axisPtr->t1Ptr) { - free(t1Ptr); /* Free generated ticks. */ - } - if (t2Ptr != axisPtr->t2Ptr) { - free(t2Ptr); /* Free generated ticks. */ - } - axisPtr->major.nUsed = s1 - axisPtr->major.segments; - axisPtr->minor.nUsed = s2 - axisPtr->minor.segments; + int j; + + for (j = 0; j < t2Ptr->nTicks; j++) { + double subValue; + + subValue = value + (axisPtr->majorSweep.step * + t2Ptr->values[j]); + if (InRange(subValue, &axisPtr->axisRange)) { + MakeGridLine(axisPtr, subValue, s2); + s2++; + } + } + } + if (InRange(value, &axisPtr->axisRange)) { + MakeGridLine(axisPtr, value, s1); + s1++; + } + } + if (t1Ptr != axisPtr->t1Ptr) { + free(t1Ptr); /* Free generated ticks. */ + } + if (t2Ptr != axisPtr->t2Ptr) { + free(t2Ptr); /* Free generated ticks. */ + } + axisPtr->major.nUsed = s1 - axisPtr->major.segments; + axisPtr->minor.nUsed = s2 - axisPtr->minor.segments; } /* @@ -3238,106 +3242,106 @@ MapGridlines(Axis *axisPtr) static void GetAxisGeometry(Graph *graphPtr, Axis *axisPtr) { - unsigned int y; + unsigned int y; - FreeTickLabels(axisPtr->tickLabels); - y = 0; + FreeTickLabels(axisPtr->tickLabels); + y = 0; - if ((axisPtr->flags & AXIS_EXTERIOR) && - (graphPtr->plotRelief != TK_RELIEF_SOLID)) { - /* Leave room for axis baseline and padding */ - y += axisPtr->lineWidth + 2; - } + if ((axisPtr->flags & AXIS_EXTERIOR) && + (graphPtr->plotRelief != TK_RELIEF_SOLID)) { + /* Leave room for axis baseline and padding */ + y += axisPtr->lineWidth + 2; + } - axisPtr->maxTickHeight = axisPtr->maxTickWidth = 0; - if (axisPtr->flags & AXIS_SHOWTICKS) { - unsigned int pad; - unsigned int i, nLabels, nTicks; + axisPtr->maxTickHeight = axisPtr->maxTickWidth = 0; + if (axisPtr->flags & AXIS_SHOWTICKS) { + unsigned int pad; + unsigned int i, nLabels, nTicks; - SweepTicks(axisPtr); + SweepTicks(axisPtr); - nTicks = 0; - if (axisPtr->t1Ptr != NULL) { - nTicks = axisPtr->t1Ptr->nTicks; - } - assert(nTicks <= MAXTICKS); + nTicks = 0; + if (axisPtr->t1Ptr != NULL) { + nTicks = axisPtr->t1Ptr->nTicks; + } + assert(nTicks <= MAXTICKS); - nLabels = 0; - for (i = 0; i < nTicks; i++) { - TickLabel *labelPtr; - double x, x2; - unsigned int lw, lh; /* Label width and height. */ - - x2 = x = axisPtr->t1Ptr->values[i]; - if (axisPtr->labelOffset) { - x2 += axisPtr->majorSweep.step * 0.5; - } - if (!InRange(x2, &axisPtr->axisRange)) { - continue; - } - labelPtr = MakeLabel(axisPtr, x); - Blt_Chain_Append(axisPtr->tickLabels, labelPtr); - nLabels++; - /* - * Get the dimensions of each tick label. Remember tick labels - * can be multi-lined and/or rotated. - */ - Blt_GetTextExtents(axisPtr->tickFont, 0, labelPtr->string, -1, - &lw, &lh); - labelPtr->width = lw; - labelPtr->height = lh; - - if (axisPtr->tickAngle != 0.0f) { - double rlw, rlh; /* Rotated label width and height. */ - Blt_GetBoundingBox(lw, lh, axisPtr->tickAngle, &rlw, &rlh,NULL); - lw = ROUND(rlw), lh = ROUND(rlh); - } - if (axisPtr->maxTickWidth < lw) { - axisPtr->maxTickWidth = lw; - } - if (axisPtr->maxTickHeight < lh) { - axisPtr->maxTickHeight = lh; - } - } - assert(nLabels <= nTicks); + nLabels = 0; + for (i = 0; i < nTicks; i++) { + TickLabel *labelPtr; + double x, x2; + unsigned int lw, lh; /* Label width and height. */ + + x2 = x = axisPtr->t1Ptr->values[i]; + if (axisPtr->labelOffset) { + x2 += axisPtr->majorSweep.step * 0.5; + } + if (!InRange(x2, &axisPtr->axisRange)) { + continue; + } + labelPtr = MakeLabel(axisPtr, x); + Blt_Chain_Append(axisPtr->tickLabels, labelPtr); + nLabels++; + /* + * Get the dimensions of each tick label. Remember tick labels + * can be multi-lined and/or rotated. + */ + Blt_GetTextExtents(axisPtr->tickFont, 0, labelPtr->string, -1, + &lw, &lh); + labelPtr->width = lw; + labelPtr->height = lh; + + if (axisPtr->tickAngle != 0.0f) { + double rlw, rlh; /* Rotated label width and height. */ + Blt_GetBoundingBox(lw, lh, axisPtr->tickAngle, &rlw, &rlh,NULL); + lw = ROUND(rlw), lh = ROUND(rlh); + } + if (axisPtr->maxTickWidth < lw) { + axisPtr->maxTickWidth = lw; + } + if (axisPtr->maxTickHeight < lh) { + axisPtr->maxTickHeight = lh; + } + } + assert(nLabels <= nTicks); - pad = 0; - if (axisPtr->flags & AXIS_EXTERIOR) { - /* Because the axis cap style is "CapProjecting", we need to - * account for an extra 1.5 linewidth at the end of each line. */ - pad = ((axisPtr->lineWidth * 12) / 8); - } - if (AxisIsHorizontal(axisPtr)) { - y += axisPtr->maxTickHeight + pad; - } else { - y += axisPtr->maxTickWidth + pad; - if (axisPtr->maxTickWidth > 0) { - y += 5; /* Pad either size of label. */ - } - } - y += 2 * AXIS_PAD_TITLE; - if ((axisPtr->lineWidth > 0) && (axisPtr->flags & AXIS_EXTERIOR)) { - /* Distance from axis line to tick label. */ - y += axisPtr->tickLength; - } - } - - if (axisPtr->title != NULL) { - if (axisPtr->titleAlternate) { - if (y < axisPtr->titleHeight) { - y = axisPtr->titleHeight; - } - } else { - y += axisPtr->titleHeight + AXIS_PAD_TITLE; - } + pad = 0; + if (axisPtr->flags & AXIS_EXTERIOR) { + /* Because the axis cap style is "CapProjecting", we need to + * account for an extra 1.5 linewidth at the end of each line. */ + pad = ((axisPtr->lineWidth * 12) / 8); } - - /* Correct for orientation of the axis. */ if (AxisIsHorizontal(axisPtr)) { - axisPtr->height = y; + y += axisPtr->maxTickHeight + pad; + } else { + y += axisPtr->maxTickWidth + pad; + if (axisPtr->maxTickWidth > 0) { + y += 5; /* Pad either size of label. */ + } + } + y += 2 * AXIS_PAD_TITLE; + if ((axisPtr->lineWidth > 0) && (axisPtr->flags & AXIS_EXTERIOR)) { + /* Distance from axis line to tick label. */ + y += axisPtr->tickLength; + } + } + + if (axisPtr->title != NULL) { + if (axisPtr->titleAlternate) { + if (y < axisPtr->titleHeight) { + y = axisPtr->titleHeight; + } } else { - axisPtr->width = y; + y += axisPtr->titleHeight + AXIS_PAD_TITLE; } + } + + /* Correct for orientation of the axis. */ + if (AxisIsHorizontal(axisPtr)) { + axisPtr->height = y; + } else { + axisPtr->width = y; + } } /* @@ -3365,86 +3369,86 @@ GetAxisGeometry(Graph *graphPtr, Axis *axisPtr) static int GetMarginGeometry(Graph *graphPtr, Margin *marginPtr) { - Blt_ChainLink link; - unsigned int l, w, h; /* Length, width, and height. */ - int isHoriz; - unsigned int nVisible; - - isHoriz = HORIZMARGIN(marginPtr); - - /* Count the visible axes. */ - nVisible = 0; - l = w = h = 0; - marginPtr->maxTickWidth = marginPtr->maxTickHeight = 0; - if (graphPtr->stackAxes) { - for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; + Blt_ChainLink link; + unsigned int l, w, h; /* Length, width, and height. */ + int isHoriz; + unsigned int nVisible; + + isHoriz = HORIZMARGIN(marginPtr); + + /* Count the visible axes. */ + nVisible = 0; + l = w = h = 0; + marginPtr->maxTickWidth = marginPtr->maxTickHeight = 0; + if (graphPtr->stackAxes) { + for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; - axisPtr = Blt_Chain_GetValue(link); - if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) { - nVisible++; - if (graphPtr->flags & GET_AXIS_GEOMETRY) { - GetAxisGeometry(graphPtr, axisPtr); - } - if (isHoriz) { - if (h < axisPtr->height) { - h = axisPtr->height; - } - } else { - if (w < axisPtr->width) { - w = axisPtr->width; - } - } - if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) { - marginPtr->maxTickWidth = axisPtr->maxTickWidth; - } - if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) { - marginPtr->maxTickHeight = axisPtr->maxTickHeight; - } - } + axisPtr = Blt_Chain_GetValue(link); + if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) { + nVisible++; + if (graphPtr->flags & GET_AXIS_GEOMETRY) { + GetAxisGeometry(graphPtr, axisPtr); + } + if (isHoriz) { + if (h < axisPtr->height) { + h = axisPtr->height; + } + } else { + if (w < axisPtr->width) { + w = axisPtr->width; + } } - } else { - for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; - - axisPtr = Blt_Chain_GetValue(link); - if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) { - nVisible++; - if (graphPtr->flags & GET_AXIS_GEOMETRY) { - GetAxisGeometry(graphPtr, axisPtr); - } - if ((axisPtr->titleAlternate) && (l < axisPtr->titleWidth)) { - l = axisPtr->titleWidth; - } - if (isHoriz) { - h += axisPtr->height; - } else { - w += axisPtr->width; - } - if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) { - marginPtr->maxTickWidth = axisPtr->maxTickWidth; - } - if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) { - marginPtr->maxTickHeight = axisPtr->maxTickHeight; - } - } + if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) { + marginPtr->maxTickWidth = axisPtr->maxTickWidth; } + if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) { + marginPtr->maxTickHeight = axisPtr->maxTickHeight; + } + } } - /* Enforce a minimum size for margins. */ - if (w < 3) { - w = 3; - } - if (h < 3) { - h = 3; - } - marginPtr->nAxes = nVisible; - marginPtr->axesTitleLength = l; - marginPtr->width = w; - marginPtr->height = h; - marginPtr->axesOffset = (isHoriz) ? h : w; - return marginPtr->axesOffset; + } else { + for (link = Blt_Chain_FirstLink(marginPtr->axes); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; + + axisPtr = Blt_Chain_GetValue(link); + if ((axisPtr->flags & (HIDE|AXIS_USE)) == AXIS_USE) { + nVisible++; + if (graphPtr->flags & GET_AXIS_GEOMETRY) { + GetAxisGeometry(graphPtr, axisPtr); + } + if ((axisPtr->titleAlternate) && (l < axisPtr->titleWidth)) { + l = axisPtr->titleWidth; + } + if (isHoriz) { + h += axisPtr->height; + } else { + w += axisPtr->width; + } + if (axisPtr->maxTickWidth > marginPtr->maxTickWidth) { + marginPtr->maxTickWidth = axisPtr->maxTickWidth; + } + if (axisPtr->maxTickHeight > marginPtr->maxTickHeight) { + marginPtr->maxTickHeight = axisPtr->maxTickHeight; + } + } + } + } + /* Enforce a minimum size for margins. */ + if (w < 3) { + w = 3; + } + if (h < 3) { + h = 3; + } + marginPtr->nAxes = nVisible; + marginPtr->axesTitleLength = l; + marginPtr->width = w; + marginPtr->height = h; + marginPtr->axesOffset = (isHoriz) ? h : w; + return marginPtr->axesOffset; } /* @@ -3533,290 +3537,290 @@ GetMarginGeometry(Graph *graphPtr, Margin *marginPtr) void Blt_LayoutGraph(Graph *graphPtr) { - unsigned int titleY; - unsigned int left, right, top, bottom; - unsigned int plotWidth, plotHeight; - unsigned int inset, inset2; - int width, height; - int pad; - - width = graphPtr->width; - height = graphPtr->height; - - /* - * Step 1: Compute the amount of space needed to display the axes - * associated with each margin. They can be overridden by - * -leftmargin, -rightmargin, -bottommargin, and -topmargin - * graph options, respectively. - */ - left = GetMarginGeometry(graphPtr, &graphPtr->leftMargin); - right = GetMarginGeometry(graphPtr, &graphPtr->rightMargin); - top = GetMarginGeometry(graphPtr, &graphPtr->topMargin); - bottom = GetMarginGeometry(graphPtr, &graphPtr->bottomMargin); - - pad = graphPtr->bottomMargin.maxTickWidth; - if (pad < graphPtr->topMargin.maxTickWidth) { - pad = graphPtr->topMargin.maxTickWidth; - } - pad = pad / 2 + 3; - if (right < pad) { - right = pad; - } - if (left < pad) { - left = pad; - } - pad = graphPtr->leftMargin.maxTickHeight; - if (pad < graphPtr->rightMargin.maxTickHeight) { - pad = graphPtr->rightMargin.maxTickHeight; - } - pad = pad / 2; - if (top < pad) { - top = pad; - } - if (bottom < pad) { - bottom = pad; - } - - if (graphPtr->leftMargin.reqSize > 0) { - left = graphPtr->leftMargin.reqSize; - } - if (graphPtr->rightMargin.reqSize > 0) { - right = graphPtr->rightMargin.reqSize; - } - if (graphPtr->topMargin.reqSize > 0) { - top = graphPtr->topMargin.reqSize; - } - if (graphPtr->bottomMargin.reqSize > 0) { - bottom = graphPtr->bottomMargin.reqSize; - } - - /* - * Step 2: Add the graph title height to the top margin. - */ - if (graphPtr->title != NULL) { - top += graphPtr->titleHeight + 6; - } - inset = (graphPtr->inset + graphPtr->plotBW); - inset2 = 2 * inset; - - /* - * Step 3: Estimate the size of the plot area from the remaining - * space. This may be overridden by the -plotwidth and - * -plotheight graph options. We use this to compute the - * size of the legend. - */ - if (width == 0) { - width = 400; - } - if (height == 0) { - height = 400; - } - plotWidth = (graphPtr->reqPlotWidth > 0) ? graphPtr->reqPlotWidth : - width - (inset2 + left + right); /* Plot width. */ - plotHeight = (graphPtr->reqPlotHeight > 0) ? graphPtr->reqPlotHeight : - height - (inset2 + top + bottom); /* Plot height. */ - Blt_MapLegend(graphPtr, plotWidth, plotHeight); + unsigned int titleY; + unsigned int left, right, top, bottom; + unsigned int plotWidth, plotHeight; + unsigned int inset, inset2; + int width, height; + int pad; + + width = graphPtr->width; + height = graphPtr->height; + + /* + * Step 1: Compute the amount of space needed to display the axes + * associated with each margin. They can be overridden by + * -leftmargin, -rightmargin, -bottommargin, and -topmargin + * graph options, respectively. + */ + left = GetMarginGeometry(graphPtr, &graphPtr->leftMargin); + right = GetMarginGeometry(graphPtr, &graphPtr->rightMargin); + top = GetMarginGeometry(graphPtr, &graphPtr->topMargin); + bottom = GetMarginGeometry(graphPtr, &graphPtr->bottomMargin); + + pad = graphPtr->bottomMargin.maxTickWidth; + if (pad < graphPtr->topMargin.maxTickWidth) { + pad = graphPtr->topMargin.maxTickWidth; + } + pad = pad / 2 + 3; + if (right < pad) { + right = pad; + } + if (left < pad) { + left = pad; + } + pad = graphPtr->leftMargin.maxTickHeight; + if (pad < graphPtr->rightMargin.maxTickHeight) { + pad = graphPtr->rightMargin.maxTickHeight; + } + pad = pad / 2; + if (top < pad) { + top = pad; + } + if (bottom < pad) { + bottom = pad; + } + + if (graphPtr->leftMargin.reqSize > 0) { + left = graphPtr->leftMargin.reqSize; + } + if (graphPtr->rightMargin.reqSize > 0) { + right = graphPtr->rightMargin.reqSize; + } + if (graphPtr->topMargin.reqSize > 0) { + top = graphPtr->topMargin.reqSize; + } + if (graphPtr->bottomMargin.reqSize > 0) { + bottom = graphPtr->bottomMargin.reqSize; + } + + /* + * Step 2: Add the graph title height to the top margin. + */ + if (graphPtr->title != NULL) { + top += graphPtr->titleHeight + 6; + } + inset = (graphPtr->inset + graphPtr->plotBW); + inset2 = 2 * inset; + + /* + * Step 3: Estimate the size of the plot area from the remaining + * space. This may be overridden by the -plotwidth and + * -plotheight graph options. We use this to compute the + * size of the legend. + */ + if (width == 0) { + width = 400; + } + if (height == 0) { + height = 400; + } + plotWidth = (graphPtr->reqPlotWidth > 0) ? graphPtr->reqPlotWidth : + width - (inset2 + left + right); /* Plot width. */ + plotHeight = (graphPtr->reqPlotHeight > 0) ? graphPtr->reqPlotHeight : + height - (inset2 + top + bottom); /* Plot height. */ + Blt_MapLegend(graphPtr, plotWidth, plotHeight); + + /* + * Step 2: Add the legend to the appropiate margin. + */ + if (!Blt_Legend_IsHidden(graphPtr)) { + switch (Blt_Legend_Site(graphPtr)) { + case LEGEND_RIGHT: + right += Blt_Legend_Width(graphPtr) + 2; + break; + case LEGEND_LEFT: + left += Blt_Legend_Width(graphPtr) + 2; + break; + case LEGEND_TOP: + top += Blt_Legend_Height(graphPtr) + 2; + break; + case LEGEND_BOTTOM: + bottom += Blt_Legend_Height(graphPtr) + 2; + break; + case LEGEND_XY: + case LEGEND_PLOT: + case LEGEND_WINDOW: + /* Do nothing. */ + break; + } + } + + /* + * Recompute the plotarea or graph size, now accounting for the legend. + */ + if (graphPtr->reqPlotWidth == 0) { + plotWidth = width - (inset2 + left + right); + if (plotWidth < 1) { + plotWidth = 1; + } + } + if (graphPtr->reqPlotHeight == 0) { + plotHeight = height - (inset2 + top + bottom); + if (plotHeight < 1) { + plotHeight = 1; + } + } + + /* + * Step 5: If necessary, correct for the requested plot area aspect + * ratio. + */ + if ((graphPtr->reqPlotWidth == 0) && (graphPtr->reqPlotHeight == 0) && + (graphPtr->aspect > 0.0f)) { + float ratio; /* - * Step 2: Add the legend to the appropiate margin. + * Shrink one dimension of the plotarea to fit the requested + * width/height aspect ratio. */ - if (!Blt_Legend_IsHidden(graphPtr)) { - switch (Blt_Legend_Site(graphPtr)) { - case LEGEND_RIGHT: - right += Blt_Legend_Width(graphPtr) + 2; - break; - case LEGEND_LEFT: - left += Blt_Legend_Width(graphPtr) + 2; - break; - case LEGEND_TOP: - top += Blt_Legend_Height(graphPtr) + 2; - break; - case LEGEND_BOTTOM: - bottom += Blt_Legend_Height(graphPtr) + 2; - break; - case LEGEND_XY: - case LEGEND_PLOT: - case LEGEND_WINDOW: - /* Do nothing. */ - break; - } - } + ratio = (float)plotWidth / (float)plotHeight; + if (ratio > graphPtr->aspect) { + int scaledWidth; + + /* Shrink the width. */ + scaledWidth = (int)(plotHeight * graphPtr->aspect); + if (scaledWidth < 1) { + scaledWidth = 1; + } + /* Add the difference to the right margin. */ + /* CHECK THIS: w = scaledWidth; */ + right += (plotWidth - scaledWidth); + } else { + int scaledHeight; + + /* Shrink the height. */ + scaledHeight = (int)(plotWidth / graphPtr->aspect); + if (scaledHeight < 1) { + scaledHeight = 1; + } + /* Add the difference to the top margin. */ + /* CHECK THIS: h = scaledHeight; */ + top += (plotHeight - scaledHeight); + } + } + + /* + * Step 6: If there's multiple axes in a margin, the axis titles will be + * displayed in the adjoining margins. Make sure there's room + * for the longest axis titles. + */ + + if (top < graphPtr->leftMargin.axesTitleLength) { + top = graphPtr->leftMargin.axesTitleLength; + } + if (right < graphPtr->bottomMargin.axesTitleLength) { + right = graphPtr->bottomMargin.axesTitleLength; + } + if (top < graphPtr->rightMargin.axesTitleLength) { + top = graphPtr->rightMargin.axesTitleLength; + } + if (right < graphPtr->topMargin.axesTitleLength) { + right = graphPtr->topMargin.axesTitleLength; + } + + /* + * Step 7: Override calculated values with requested margin sizes. + */ + if (graphPtr->leftMargin.reqSize > 0) { + left = graphPtr->leftMargin.reqSize; + } + if (graphPtr->rightMargin.reqSize > 0) { + right = graphPtr->rightMargin.reqSize; + } + if (graphPtr->topMargin.reqSize > 0) { + top = graphPtr->topMargin.reqSize; + } + if (graphPtr->bottomMargin.reqSize > 0) { + bottom = graphPtr->bottomMargin.reqSize; + } + if (graphPtr->reqPlotWidth > 0) { + int w; /* - * Recompute the plotarea or graph size, now accounting for the legend. + * Width of plotarea is constained. If there's extra space, add it to + * th left and/or right margins. If there's too little, grow the + * graph width to accomodate it. */ - if (graphPtr->reqPlotWidth == 0) { - plotWidth = width - (inset2 + left + right); - if (plotWidth < 1) { - plotWidth = 1; - } - } - if (graphPtr->reqPlotHeight == 0) { - plotHeight = height - (inset2 + top + bottom); - if (plotHeight < 1) { - plotHeight = 1; - } - } - - /* - * Step 5: If necessary, correct for the requested plot area aspect - * ratio. - */ - if ((graphPtr->reqPlotWidth == 0) && (graphPtr->reqPlotHeight == 0) && - (graphPtr->aspect > 0.0f)) { - float ratio; - - /* - * Shrink one dimension of the plotarea to fit the requested - * width/height aspect ratio. - */ - ratio = (float)plotWidth / (float)plotHeight; - if (ratio > graphPtr->aspect) { - int scaledWidth; - - /* Shrink the width. */ - scaledWidth = (int)(plotHeight * graphPtr->aspect); - if (scaledWidth < 1) { - scaledWidth = 1; - } - /* Add the difference to the right margin. */ - /* CHECK THIS: w = scaledWidth; */ - right += (plotWidth - scaledWidth); + w = plotWidth + inset2 + left + right; + if (width > w) { /* Extra space in window. */ + int extra; + + extra = (width - w) / 2; + if (graphPtr->leftMargin.reqSize == 0) { + left += extra; + if (graphPtr->rightMargin.reqSize == 0) { + right += extra; } else { - int scaledHeight; - - /* Shrink the height. */ - scaledHeight = (int)(plotWidth / graphPtr->aspect); - if (scaledHeight < 1) { - scaledHeight = 1; - } - /* Add the difference to the top margin. */ - /* CHECK THIS: h = scaledHeight; */ - top += (plotHeight - scaledHeight); + left += extra; } + } else if (graphPtr->rightMargin.reqSize == 0) { + right += extra + extra; + } + } else if (width < w) { + width = w; } + } + if (graphPtr->reqPlotHeight > 0) { /* Constrain the plotarea height. */ + int h; /* - * Step 6: If there's multiple axes in a margin, the axis titles will be - * displayed in the adjoining margins. Make sure there's room - * for the longest axis titles. + * Height of plotarea is constained. If there's extra space, + * add it to th top and/or bottom margins. If there's too little, + * grow the graph height to accomodate it. */ - - if (top < graphPtr->leftMargin.axesTitleLength) { - top = graphPtr->leftMargin.axesTitleLength; - } - if (right < graphPtr->bottomMargin.axesTitleLength) { - right = graphPtr->bottomMargin.axesTitleLength; - } - if (top < graphPtr->rightMargin.axesTitleLength) { - top = graphPtr->rightMargin.axesTitleLength; - } - if (right < graphPtr->topMargin.axesTitleLength) { - right = graphPtr->topMargin.axesTitleLength; - } - - /* - * Step 7: Override calculated values with requested margin sizes. - */ - if (graphPtr->leftMargin.reqSize > 0) { - left = graphPtr->leftMargin.reqSize; - } - if (graphPtr->rightMargin.reqSize > 0) { - right = graphPtr->rightMargin.reqSize; - } - if (graphPtr->topMargin.reqSize > 0) { - top = graphPtr->topMargin.reqSize; - } - if (graphPtr->bottomMargin.reqSize > 0) { - bottom = graphPtr->bottomMargin.reqSize; - } - if (graphPtr->reqPlotWidth > 0) { - int w; - - /* - * Width of plotarea is constained. If there's extra space, add it to - * th left and/or right margins. If there's too little, grow the - * graph width to accomodate it. - */ - w = plotWidth + inset2 + left + right; - if (width > w) { /* Extra space in window. */ - int extra; - - extra = (width - w) / 2; - if (graphPtr->leftMargin.reqSize == 0) { - left += extra; - if (graphPtr->rightMargin.reqSize == 0) { - right += extra; - } else { - left += extra; - } - } else if (graphPtr->rightMargin.reqSize == 0) { - right += extra + extra; - } - } else if (width < w) { - width = w; - } - } - if (graphPtr->reqPlotHeight > 0) { /* Constrain the plotarea height. */ - int h; - - /* - * Height of plotarea is constained. If there's extra space, - * add it to th top and/or bottom margins. If there's too little, - * grow the graph height to accomodate it. - */ - h = plotHeight + inset2 + top + bottom; - if (height > h) { /* Extra space in window. */ - int extra; - - extra = (height - h) / 2; - if (graphPtr->topMargin.reqSize == 0) { - top += extra; - if (graphPtr->bottomMargin.reqSize == 0) { - bottom += extra; - } else { - top += extra; - } - } else if (graphPtr->bottomMargin.reqSize == 0) { - bottom += extra + extra; - } - } else if (height < h) { - height = h; - } - } - graphPtr->width = width; - graphPtr->height = height; - graphPtr->left = left + inset; - graphPtr->top = top + inset; - graphPtr->right = width - right - inset; - graphPtr->bottom = height - bottom - inset; - - graphPtr->leftMargin.width = left + graphPtr->inset; - graphPtr->rightMargin.width = right + graphPtr->inset; - graphPtr->topMargin.height = top + graphPtr->inset; - graphPtr->bottomMargin.height = bottom + graphPtr->inset; + h = plotHeight + inset2 + top + bottom; + if (height > h) { /* Extra space in window. */ + int extra; + + extra = (height - h) / 2; + if (graphPtr->topMargin.reqSize == 0) { + top += extra; + if (graphPtr->bottomMargin.reqSize == 0) { + bottom += extra; + } else { + top += extra; + } + } else if (graphPtr->bottomMargin.reqSize == 0) { + bottom += extra + extra; + } + } else if (height < h) { + height = h; + } + } + graphPtr->width = width; + graphPtr->height = height; + graphPtr->left = left + inset; + graphPtr->top = top + inset; + graphPtr->right = width - right - inset; + graphPtr->bottom = height - bottom - inset; + + graphPtr->leftMargin.width = left + graphPtr->inset; + graphPtr->rightMargin.width = right + graphPtr->inset; + graphPtr->topMargin.height = top + graphPtr->inset; + graphPtr->bottomMargin.height = bottom + graphPtr->inset; - graphPtr->vOffset = graphPtr->top + graphPtr->yPad; - graphPtr->vRange = plotHeight - 2*graphPtr->yPad; - graphPtr->hOffset = graphPtr->left + graphPtr->xPad; - graphPtr->hRange = plotWidth - 2*graphPtr->xPad; - - if (graphPtr->vRange < 1) { - graphPtr->vRange = 1; - } - if (graphPtr->hRange < 1) { - graphPtr->hRange = 1; - } - graphPtr->hScale = 1.0f / (float)graphPtr->hRange; - graphPtr->vScale = 1.0f / (float)graphPtr->vRange; - - /* - * Calculate the placement of the graph title so it is centered within the - * space provided for it in the top margin - */ - titleY = graphPtr->titleHeight; - graphPtr->titleY = 3 + graphPtr->inset; - graphPtr->titleX = (graphPtr->right + graphPtr->left) / 2; + graphPtr->vOffset = graphPtr->top + graphPtr->yPad; + graphPtr->vRange = plotHeight - 2*graphPtr->yPad; + graphPtr->hOffset = graphPtr->left + graphPtr->xPad; + graphPtr->hRange = plotWidth - 2*graphPtr->xPad; + + if (graphPtr->vRange < 1) { + graphPtr->vRange = 1; + } + if (graphPtr->hRange < 1) { + graphPtr->hRange = 1; + } + graphPtr->hScale = 1.0f / (float)graphPtr->hRange; + graphPtr->vScale = 1.0f / (float)graphPtr->vRange; + + /* + * Calculate the placement of the graph title so it is centered within the + * space provided for it in the top margin + */ + titleY = graphPtr->titleHeight; + graphPtr->titleY = 3 + graphPtr->inset; + graphPtr->titleX = (graphPtr->right + graphPtr->left) / 2; } @@ -3839,71 +3843,71 @@ Blt_LayoutGraph(Graph *graphPtr) static int ConfigureAxis(Axis *axisPtr) { - Graph *graphPtr = axisPtr->obj.graphPtr; - float angle; - - /* Check the requested axis limits. Can't allow -min to be greater than - * -max. Do this regardless of -checklimits option. We want to always - * detect when the user has zoomed in beyond the precision of the data.*/ - if (((!isnan(axisPtr->reqMin)) && (!isnan(axisPtr->reqMax))) && - (axisPtr->reqMin >= axisPtr->reqMax)) { - char msg[200]; - sprintf_s(msg, 200, - "impossible axis limits (-min %g >= -max %g) for \"%s\"", - axisPtr->reqMin, axisPtr->reqMax, axisPtr->obj.name); - Tcl_AppendResult(graphPtr->interp, msg, (char *)NULL); + Graph *graphPtr = axisPtr->obj.graphPtr; + float angle; + + /* Check the requested axis limits. Can't allow -min to be greater than + * -max. Do this regardless of -checklimits option. We want to always + * detect when the user has zoomed in beyond the precision of the data.*/ + if (((!isnan(axisPtr->reqMin)) && (!isnan(axisPtr->reqMax))) && + (axisPtr->reqMin >= axisPtr->reqMax)) { + char msg[200]; + sprintf_s(msg, 200, + "impossible axis limits (-min %g >= -max %g) for \"%s\"", + axisPtr->reqMin, axisPtr->reqMax, axisPtr->obj.name); + Tcl_AppendResult(graphPtr->interp, msg, (char *)NULL); + return TCL_ERROR; + } + axisPtr->scrollMin = axisPtr->reqScrollMin; + axisPtr->scrollMax = axisPtr->reqScrollMax; + if (axisPtr->logScale) { + if (axisPtr->flags & AXIS_CHECK_LIMITS) { + /* Check that the logscale limits are positive. */ + if ((!isnan(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) { + Tcl_AppendResult(graphPtr->interp,"bad logscale -min limit \"", + Blt_Dtoa(graphPtr->interp, axisPtr->reqMin), + "\" for axis \"", axisPtr->obj.name, "\"", + (char *)NULL); return TCL_ERROR; - } - axisPtr->scrollMin = axisPtr->reqScrollMin; - axisPtr->scrollMax = axisPtr->reqScrollMax; - if (axisPtr->logScale) { - if (axisPtr->flags & AXIS_CHECK_LIMITS) { - /* Check that the logscale limits are positive. */ - if ((!isnan(axisPtr->reqMin)) && (axisPtr->reqMin <= 0.0)) { - Tcl_AppendResult(graphPtr->interp,"bad logscale -min limit \"", - Blt_Dtoa(graphPtr->interp, axisPtr->reqMin), - "\" for axis \"", axisPtr->obj.name, "\"", - (char *)NULL); - return TCL_ERROR; - } - } - if ((!isnan(axisPtr->scrollMin)) && (axisPtr->scrollMin <= 0.0)) { - axisPtr->scrollMin = NAN; - } - if ((!isnan(axisPtr->scrollMax)) && (axisPtr->scrollMax <= 0.0)) { - axisPtr->scrollMax = NAN; - } - } - angle = fmod(axisPtr->tickAngle, 360.0); - if (angle < 0.0f) { - angle += 360.0f; - } - axisPtr->tickAngle = angle; - ResetTextStyles(axisPtr); - - axisPtr->titleWidth = axisPtr->titleHeight = 0; - if (axisPtr->title != NULL) { - unsigned int w, h; - - Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title, -1, &w, &h); - axisPtr->titleWidth = (unsigned short int)w; - axisPtr->titleHeight = (unsigned short int)h; - } - - /* - * Don't bother to check what configuration options have changed. Almost - * every option changes the size of the plotting area (except for -color - * and -titlecolor), requiring the graph and its contents to be completely - * redrawn. - * - * Recompute the scale and offset of the axis in case -min, -max options - * have changed. - */ - graphPtr->flags |= REDRAW_WORLD; - graphPtr->flags |= MAP_WORLD | RESET_AXES | CACHE_DIRTY; - axisPtr->flags |= DIRTY; - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; + } + } + if ((!isnan(axisPtr->scrollMin)) && (axisPtr->scrollMin <= 0.0)) { + axisPtr->scrollMin = NAN; + } + if ((!isnan(axisPtr->scrollMax)) && (axisPtr->scrollMax <= 0.0)) { + axisPtr->scrollMax = NAN; + } + } + angle = fmod(axisPtr->tickAngle, 360.0); + if (angle < 0.0f) { + angle += 360.0f; + } + axisPtr->tickAngle = angle; + ResetTextStyles(axisPtr); + + axisPtr->titleWidth = axisPtr->titleHeight = 0; + if (axisPtr->title != NULL) { + unsigned int w, h; + + Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title, -1, &w, &h); + axisPtr->titleWidth = (unsigned short int)w; + axisPtr->titleHeight = (unsigned short int)h; + } + + /* + * Don't bother to check what configuration options have changed. Almost + * every option changes the size of the plotting area (except for -color + * and -titlecolor), requiring the graph and its contents to be completely + * redrawn. + * + * Recompute the scale and offset of the axis in case -min, -max options + * have changed. + */ + graphPtr->flags |= REDRAW_WORLD; + graphPtr->flags |= MAP_WORLD | RESET_AXES | CACHE_DIRTY; + axisPtr->flags |= DIRTY; + Blt_EventuallyRedrawGraph(graphPtr); + return TCL_OK; } /* @@ -3922,203 +3926,203 @@ ConfigureAxis(Axis *axisPtr) static Axis * NewAxis(Graph *graphPtr, const char *name, int margin) { - Axis *axisPtr; - Tcl_HashEntry *hPtr; - int isNew; - - if (name[0] == '-') { - Tcl_AppendResult(graphPtr->interp, "name of axis \"", name, - "\" can't start with a '-'", (char *)NULL); - return NULL; - } - hPtr = Tcl_CreateHashEntry(&graphPtr->axes.table, name, &isNew); - if (!isNew) { - axisPtr = Tcl_GetHashValue(hPtr); - if ((axisPtr->flags & DELETE_PENDING) == 0) { - Tcl_AppendResult(graphPtr->interp, "axis \"", name, - "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"", - (char *)NULL); - return NULL; - } - axisPtr->flags &= ~DELETE_PENDING; - } else { - axisPtr = calloc(1, sizeof(Axis)); - if (axisPtr == NULL) { - Tcl_AppendResult(graphPtr->interp, - "can't allocate memory for axis \"", name, "\"", (char *)NULL); - return NULL; - } - axisPtr->obj.name = Blt_Strdup(name); - axisPtr->hashPtr = hPtr; - Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); - axisPtr->obj.graphPtr = graphPtr; - axisPtr->looseMin = axisPtr->looseMax = AXIS_TIGHT; - axisPtr->reqNumMinorTicks = 2; - axisPtr->reqNumMajorTicks = 4 /*10*/; - axisPtr->margin = MARGIN_NONE; - axisPtr->tickLength = 8; - axisPtr->scrollUnits = 10; - axisPtr->reqMin = axisPtr->reqMax = NAN; - axisPtr->reqScrollMin = axisPtr->reqScrollMax = NAN; - axisPtr->flags = (AXIS_SHOWTICKS|AXIS_GRIDMINOR|AXIS_AUTO_MAJOR| - AXIS_AUTO_MINOR | AXIS_EXTERIOR); - if (graphPtr->classId == CID_ELEM_BAR) { - axisPtr->flags |= AXIS_GRID; - } - if ((graphPtr->classId == CID_ELEM_BAR) && - ((margin == MARGIN_TOP) || (margin == MARGIN_BOTTOM))) { - axisPtr->reqStep = 1.0; - axisPtr->reqNumMinorTicks = 0; - } - if ((margin == MARGIN_RIGHT) || (margin == MARGIN_TOP)) { - axisPtr->flags |= HIDE; - } - Blt_Ts_InitStyle(axisPtr->limitsTextStyle); - axisPtr->tickLabels = Blt_Chain_Create(); - axisPtr->lineWidth = 1; - Tcl_SetHashValue(hPtr, axisPtr); - } - return axisPtr; + Axis *axisPtr; + Tcl_HashEntry *hPtr; + int isNew; + + if (name[0] == '-') { + Tcl_AppendResult(graphPtr->interp, "name of axis \"", name, + "\" can't start with a '-'", (char *)NULL); + return NULL; + } + hPtr = Tcl_CreateHashEntry(&graphPtr->axes.table, name, &isNew); + if (!isNew) { + axisPtr = Tcl_GetHashValue(hPtr); + if ((axisPtr->flags & DELETE_PENDING) == 0) { + Tcl_AppendResult(graphPtr->interp, "axis \"", name, + "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"", + (char *)NULL); + return NULL; + } + axisPtr->flags &= ~DELETE_PENDING; + } else { + axisPtr = calloc(1, sizeof(Axis)); + if (axisPtr == NULL) { + Tcl_AppendResult(graphPtr->interp, + "can't allocate memory for axis \"", name, "\"", (char *)NULL); + return NULL; + } + axisPtr->obj.name = Blt_Strdup(name); + axisPtr->hashPtr = hPtr; + Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); + axisPtr->obj.graphPtr = graphPtr; + axisPtr->looseMin = axisPtr->looseMax = AXIS_TIGHT; + axisPtr->reqNumMinorTicks = 2; + axisPtr->reqNumMajorTicks = 4 /*10*/; + axisPtr->margin = MARGIN_NONE; + axisPtr->tickLength = 8; + axisPtr->scrollUnits = 10; + axisPtr->reqMin = axisPtr->reqMax = NAN; + axisPtr->reqScrollMin = axisPtr->reqScrollMax = NAN; + axisPtr->flags = (AXIS_SHOWTICKS|AXIS_GRIDMINOR|AXIS_AUTO_MAJOR| + AXIS_AUTO_MINOR | AXIS_EXTERIOR); + if (graphPtr->classId == CID_ELEM_BAR) { + axisPtr->flags |= AXIS_GRID; + } + if ((graphPtr->classId == CID_ELEM_BAR) && + ((margin == MARGIN_TOP) || (margin == MARGIN_BOTTOM))) { + axisPtr->reqStep = 1.0; + axisPtr->reqNumMinorTicks = 0; + } + if ((margin == MARGIN_RIGHT) || (margin == MARGIN_TOP)) { + axisPtr->flags |= HIDE; + } + Blt_Ts_InitStyle(axisPtr->limitsTextStyle); + axisPtr->tickLabels = Blt_Chain_Create(); + axisPtr->lineWidth = 1; + Tcl_SetHashValue(hPtr, axisPtr); + } + return axisPtr; } static int GetAxisFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Axis **axisPtrPtr) { - Tcl_HashEntry *hPtr; - const char *name; + Tcl_HashEntry *hPtr; + const char *name; - *axisPtrPtr = NULL; - name = Tcl_GetString(objPtr); - hPtr = Tcl_FindHashEntry(&graphPtr->axes.table, name); - if (hPtr != NULL) { - Axis *axisPtr; - - axisPtr = Tcl_GetHashValue(hPtr); - if ((axisPtr->flags & DELETE_PENDING) == 0) { - *axisPtrPtr = axisPtr; - return TCL_OK; - } - } - if (interp != NULL) { - Tcl_AppendResult(interp, "can't find axis \"", name, "\" in \"", - Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); - } - return TCL_ERROR; + *axisPtrPtr = NULL; + name = Tcl_GetString(objPtr); + hPtr = Tcl_FindHashEntry(&graphPtr->axes.table, name); + if (hPtr != NULL) { + Axis *axisPtr; + + axisPtr = Tcl_GetHashValue(hPtr); + if ((axisPtr->flags & DELETE_PENDING) == 0) { + *axisPtrPtr = axisPtr; + return TCL_OK; + } + } + if (interp != NULL) { + Tcl_AppendResult(interp, "can't find axis \"", name, "\" in \"", + Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL); + } + return TCL_ERROR; } static int GetAxisByClass(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, Axis **axisPtrPtr) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objPtr, &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - if (classId != CID_NONE) { - if ((axisPtr->refCount == 0) || (axisPtr->obj.classId == CID_NONE)) { - /* Set the axis type on the first use of it. */ - Blt_GraphSetObjectClass(&axisPtr->obj, classId); - } else if (axisPtr->obj.classId != classId) { - if (interp != NULL) { - Tcl_AppendResult(interp, "axis \"", Tcl_GetString(objPtr), - "\" is already in use on an opposite ", - axisPtr->obj.className, "-axis", - (char *)NULL); - } - return TCL_ERROR; - } - axisPtr->refCount++; - } - *axisPtrPtr = axisPtr; - return TCL_OK; + if (GetAxisFromObj(interp, graphPtr, objPtr, &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + if (classId != CID_NONE) { + if ((axisPtr->refCount == 0) || (axisPtr->obj.classId == CID_NONE)) { + /* Set the axis type on the first use of it. */ + Blt_GraphSetObjectClass(&axisPtr->obj, classId); + } else if (axisPtr->obj.classId != classId) { + if (interp != NULL) { + Tcl_AppendResult(interp, "axis \"", Tcl_GetString(objPtr), + "\" is already in use on an opposite ", + axisPtr->obj.className, "-axis", + (char *)NULL); + } + return TCL_ERROR; + } + axisPtr->refCount++; + } + *axisPtrPtr = axisPtr; + return TCL_OK; } void Blt_DestroyAxes(Graph *graphPtr) { - { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; + { + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; - axisPtr = Tcl_GetHashValue(hPtr); - axisPtr->hashPtr = NULL; - DestroyAxis(axisPtr); - } + axisPtr = Tcl_GetHashValue(hPtr); + axisPtr->hashPtr = NULL; + DestroyAxis(axisPtr); } - Tcl_DeleteHashTable(&graphPtr->axes.table); - { - int i; + } + Tcl_DeleteHashTable(&graphPtr->axes.table); + { + int i; - for (i = 0; i < 4; i++) { - Blt_Chain_Destroy(graphPtr->axisChain[i]); - } + for (i = 0; i < 4; i++) { + Blt_Chain_Destroy(graphPtr->axisChain[i]); } - Tcl_DeleteHashTable(&graphPtr->axes.tagTable); - Blt_Chain_Destroy(graphPtr->axes.displayList); + } + Tcl_DeleteHashTable(&graphPtr->axes.tagTable); + Blt_Chain_Destroy(graphPtr->axes.displayList); } void Blt_ConfigureAxes(Graph *graphPtr) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; - axisPtr = Tcl_GetHashValue(hPtr); - ConfigureAxis(axisPtr); - } + axisPtr = Tcl_GetHashValue(hPtr); + ConfigureAxis(axisPtr); + } } int Blt_DefaultAxes(Graph *graphPtr) { - int i; - int flags; + int i; + int flags; - flags = Blt_GraphType(graphPtr); - for (i = 0; i < 4; i++) { - Blt_Chain chain; - Axis *axisPtr; + flags = Blt_GraphType(graphPtr); + for (i = 0; i < 4; i++) { + Blt_Chain chain; + Axis *axisPtr; - chain = Blt_Chain_Create(); - graphPtr->axisChain[i] = chain; + chain = Blt_Chain_Create(); + graphPtr->axisChain[i] = chain; - /* Create a default axis for each chain. */ - axisPtr = NewAxis(graphPtr, axisNames[i].name, i); - if (axisPtr == NULL) { - return TCL_ERROR; - } - axisPtr->refCount = 1; /* Default axes are assumed in use. */ - axisPtr->margin = i; - axisPtr->flags |= AXIS_USE; - Blt_GraphSetObjectClass(&axisPtr->obj, axisNames[i].classId); - /* - * Blt_ConfigureComponentFromObj creates a temporary child window - * by the name of the axis. It's used so that the Tk routines - * that access the X resource database can describe a single - * component and not the entire graph. - */ - if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, - axisPtr->obj.name, "Axis", configSpecs, 0, (Tcl_Obj **)NULL, - (char *)axisPtr, flags) != TCL_OK) { - return TCL_ERROR; - } - if (ConfigureAxis(axisPtr) != TCL_OK) { - return TCL_ERROR; - } - axisPtr->link = Blt_Chain_Append(chain, axisPtr); - axisPtr->chain = chain; + /* Create a default axis for each chain. */ + axisPtr = NewAxis(graphPtr, axisNames[i].name, i); + if (axisPtr == NULL) { + return TCL_ERROR; } - return TCL_OK; + axisPtr->refCount = 1; /* Default axes are assumed in use. */ + axisPtr->margin = i; + axisPtr->flags |= AXIS_USE; + Blt_GraphSetObjectClass(&axisPtr->obj, axisNames[i].classId); + /* + * Blt_ConfigureComponentFromObj creates a temporary child window + * by the name of the axis. It's used so that the Tk routines + * that access the X resource database can describe a single + * component and not the entire graph. + */ + if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, + axisPtr->obj.name, "Axis", configSpecs, 0, (Tcl_Obj **)NULL, + (char *)axisPtr, flags) != TCL_OK) { + return TCL_ERROR; + } + if (ConfigureAxis(axisPtr) != TCL_OK) { + return TCL_ERROR; + } + axisPtr->link = Blt_Chain_Append(chain, axisPtr); + axisPtr->chain = chain; + } + return TCL_OK; } /* @@ -4140,20 +4144,20 @@ Blt_DefaultAxes(Graph *graphPtr) static int ActivateOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; - const char *string; - - string = Tcl_GetString(objv[2]); - if (string[0] == 'a') { - axisPtr->flags |= ACTIVE; - } else { - axisPtr->flags &= ~ACTIVE; - } - if ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE) { - graphPtr->flags |= DRAW_MARGINS | CACHE_DIRTY; - Blt_EventuallyRedrawGraph(graphPtr); - } - return TCL_OK; + Graph *graphPtr = axisPtr->obj.graphPtr; + const char *string; + + string = Tcl_GetString(objv[2]); + if (string[0] == 'a') { + axisPtr->flags |= ACTIVE; + } else { + axisPtr->flags &= ~ACTIVE; + } + if ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE) { + graphPtr->flags |= DRAW_MARGINS | CACHE_DIRTY; + Blt_EventuallyRedrawGraph(graphPtr); + } + return TCL_OK; } /*------------------------------------------------------------------------------- @@ -4167,10 +4171,10 @@ ActivateOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int BindOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; + Graph *graphPtr = axisPtr->obj.graphPtr; - return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, - Blt_MakeAxisTag(graphPtr, axisPtr->obj.name), objc, objv); + return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, + Blt_MakeAxisTag(graphPtr, axisPtr->obj.name), objc, objv); } /* @@ -4190,10 +4194,10 @@ BindOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int CgetOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; + Graph *graphPtr = axisPtr->obj.graphPtr; - return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, - (char *)axisPtr, objv[0], Blt_GraphType(graphPtr)); + return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, + (char *)axisPtr, objv[0], Blt_GraphType(graphPtr)); } /* @@ -4216,32 +4220,32 @@ CgetOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int ConfigureOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; - int flags; - - flags = BLT_CONFIG_OBJV_ONLY | Blt_GraphType(graphPtr); - if (objc == 0) { - return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, - (char *)axisPtr, (Tcl_Obj *)NULL, flags); - } else if (objc == 1) { - return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, - (char *)axisPtr, objv[0], flags); - } - if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, - objc, objv, (char *)axisPtr, flags) != TCL_OK) { - return TCL_ERROR; - } - if (ConfigureAxis(axisPtr) != TCL_OK) { - return TCL_ERROR; - } - if (axisPtr->flags & AXIS_USE) { - if (!Blt_ConfigModified(configSpecs, "-*color", "-background", "-bg", - (char *)NULL)) { - graphPtr->flags |= CACHE_DIRTY; - } - Blt_EventuallyRedrawGraph(graphPtr); + Graph *graphPtr = axisPtr->obj.graphPtr; + int flags; + + flags = BLT_CONFIG_OBJV_ONLY | Blt_GraphType(graphPtr); + if (objc == 0) { + return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, + (char *)axisPtr, (Tcl_Obj *)NULL, flags); + } else if (objc == 1) { + return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, + (char *)axisPtr, objv[0], flags); + } + if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, + objc, objv, (char *)axisPtr, flags) != TCL_OK) { + return TCL_ERROR; + } + if (ConfigureAxis(axisPtr) != TCL_OK) { + return TCL_ERROR; + } + if (axisPtr->flags & AXIS_USE) { + if (!Blt_ConfigModified(configSpecs, "-*color", "-background", "-bg", + (char *)NULL)) { + graphPtr->flags |= CACHE_DIRTY; } - return TCL_OK; + Blt_EventuallyRedrawGraph(graphPtr); + } + return TCL_OK; } @@ -4263,25 +4267,25 @@ ConfigureOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int LimitsOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; - Tcl_Obj *listObjPtr; - double min, max; - - if (graphPtr->flags & RESET_AXES) { - Blt_ResetAxes(graphPtr); - } - if (axisPtr->logScale) { - min = EXP10(axisPtr->axisRange.min); - max = EXP10(axisPtr->axisRange.max); - } else { - min = axisPtr->axisRange.min; - max = axisPtr->axisRange.max; - } - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(min)); - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(max)); - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; + Graph *graphPtr = axisPtr->obj.graphPtr; + Tcl_Obj *listObjPtr; + double min, max; + + if (graphPtr->flags & RESET_AXES) { + Blt_ResetAxes(graphPtr); + } + if (axisPtr->logScale) { + min = EXP10(axisPtr->axisRange.min); + max = EXP10(axisPtr->axisRange.max); + } else { + min = axisPtr->axisRange.min; + max = axisPtr->axisRange.max; + } + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(min)); + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(max)); + Tcl_SetObjResult(interp, listObjPtr); + return TCL_OK; } /* @@ -4303,30 +4307,30 @@ static int InvTransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; - double y; /* Real graph coordinate */ - int sy; /* Integer window coordinate*/ - - if (graphPtr->flags & RESET_AXES) { - Blt_ResetAxes(graphPtr); - } - if (Tcl_GetIntFromObj(interp, objv[0], &sy) != TCL_OK) { - return TCL_ERROR; - } - /* - * Is the axis vertical or horizontal? - * - * Check the site where the axis was positioned. If the axis is - * virtual, all we have to go on is how it was mapped to an - * element (using either -mapx or -mapy options). - */ - if (AxisIsHorizontal(axisPtr)) { - y = Blt_InvHMap(axisPtr, (double)sy); - } else { - y = Blt_InvVMap(axisPtr, (double)sy); - } - Tcl_SetDoubleObj(Tcl_GetObjResult(interp), y); - return TCL_OK; + Graph *graphPtr = axisPtr->obj.graphPtr; + double y; /* Real graph coordinate */ + int sy; /* Integer window coordinate*/ + + if (graphPtr->flags & RESET_AXES) { + Blt_ResetAxes(graphPtr); + } + if (Tcl_GetIntFromObj(interp, objv[0], &sy) != TCL_OK) { + return TCL_ERROR; + } + /* + * Is the axis vertical or horizontal? + * + * Check the site where the axis was positioned. If the axis is + * virtual, all we have to go on is how it was mapped to an + * element (using either -mapx or -mapy options). + */ + if (AxisIsHorizontal(axisPtr)) { + y = Blt_InvHMap(axisPtr, (double)sy); + } else { + y = Blt_InvVMap(axisPtr, (double)sy); + } + Tcl_SetDoubleObj(Tcl_GetObjResult(interp), y); + return TCL_OK; } @@ -4348,14 +4352,14 @@ InvTransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, static int MarginOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - const char *marginName; - - marginName = ""; - if (axisPtr->flags & AXIS_USE) { - marginName = axisNames[axisPtr->margin].name; - } - Tcl_SetStringObj(Tcl_GetObjResult(interp), marginName, -1); - return TCL_OK; + const char *marginName; + + marginName = ""; + if (axisPtr->flags & AXIS_USE) { + marginName = axisNames[axisPtr->margin].name; + } + Tcl_SetStringObj(Tcl_GetObjResult(interp), marginName, -1); + return TCL_OK; } /* @@ -4377,22 +4381,22 @@ MarginOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int TransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = axisPtr->obj.graphPtr; - double x; + Graph *graphPtr = axisPtr->obj.graphPtr; + double x; - if (graphPtr->flags & RESET_AXES) { - Blt_ResetAxes(graphPtr); - } - if (Blt_ExprDoubleFromObj(interp, objv[0], &x) != TCL_OK) { - return TCL_ERROR; - } - if (AxisIsHorizontal(axisPtr)) { - x = Blt_HMap(axisPtr, x); - } else { - x = Blt_VMap(axisPtr, x); - } - Tcl_SetIntObj(Tcl_GetObjResult(interp), (int)x); - return TCL_OK; + if (graphPtr->flags & RESET_AXES) { + Blt_ResetAxes(graphPtr); + } + if (Blt_ExprDoubleFromObj(interp, objv[0], &x) != TCL_OK) { + return TCL_ERROR; + } + if (AxisIsHorizontal(axisPtr)) { + x = Blt_HMap(axisPtr, x); + } else { + x = Blt_VMap(axisPtr, x); + } + Tcl_SetIntObj(Tcl_GetObjResult(interp), (int)x); + return TCL_OK; } @@ -4414,18 +4418,18 @@ TransformOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int TypeOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - const char *typeName; - - typeName = ""; - if (axisPtr->flags & AXIS_USE) { - if (axisNames[axisPtr->margin].classId == CID_AXIS_X) { - typeName = "x"; - } else if (axisNames[axisPtr->margin].classId == CID_AXIS_Y) { - typeName = "y"; - } - } - Tcl_SetStringObj(Tcl_GetObjResult(interp), typeName, -1); - return TCL_OK; + const char *typeName; + + typeName = ""; + if (axisPtr->flags & AXIS_USE) { + if (axisNames[axisPtr->margin].classId == CID_AXIS_X) { + typeName = "x"; + } else if (axisNames[axisPtr->margin].classId == CID_AXIS_Y) { + typeName = "y"; + } + } + Tcl_SetStringObj(Tcl_GetObjResult(interp), typeName, -1); + return TCL_OK; } /* @@ -4448,161 +4452,161 @@ TypeOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) static int UseOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr = (Graph *)axisPtr; - Blt_Chain chain; - Blt_ChainLink link; - Tcl_Obj **axisObjv; - ClassId classId; - int axisObjc; - int i; - - chain = graphPtr->margins[lastMargin].axes; - if (objc == 0) { - Tcl_Obj *listObjPtr; + Graph *graphPtr = (Graph *)axisPtr; + Blt_Chain chain; + Blt_ChainLink link; + Tcl_Obj **axisObjv; + ClassId classId; + int axisObjc; + int i; + + chain = graphPtr->margins[lastMargin].axes; + if (objc == 0) { + Tcl_Obj *listObjPtr; - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - for (link = Blt_Chain_FirstLink(chain); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + for (link = Blt_Chain_FirstLink(chain); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; - axisPtr = Blt_Chain_GetValue(link); - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj(axisPtr->obj.name, -1)); - } - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; + axisPtr = Blt_Chain_GetValue(link); + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj(axisPtr->obj.name, -1)); } - if ((lastMargin == MARGIN_BOTTOM) || (lastMargin == MARGIN_TOP)) { - classId = (graphPtr->inverted) ? CID_AXIS_Y : CID_AXIS_X; - } else { - classId = (graphPtr->inverted) ? CID_AXIS_X : CID_AXIS_Y; + Tcl_SetObjResult(interp, listObjPtr); + return TCL_OK; + } + if ((lastMargin == MARGIN_BOTTOM) || (lastMargin == MARGIN_TOP)) { + classId = (graphPtr->inverted) ? CID_AXIS_Y : CID_AXIS_X; + } else { + classId = (graphPtr->inverted) ? CID_AXIS_X : CID_AXIS_Y; + } + if (Tcl_ListObjGetElements(interp, objv[0], &axisObjc, &axisObjv) + != TCL_OK) { + return TCL_ERROR; + } + for (link = Blt_Chain_FirstLink(chain); link!= NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; + + axisPtr = Blt_Chain_GetValue(link); + axisPtr->link = NULL; + axisPtr->flags &= ~AXIS_USE; + /* Clear the axis type if it's not currently used.*/ + if (axisPtr->refCount == 0) { + Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); } - if (Tcl_ListObjGetElements(interp, objv[0], &axisObjc, &axisObjv) - != TCL_OK) { - return TCL_ERROR; + } + Blt_Chain_Reset(chain); + for (i = 0; i < axisObjc; i++) { + Axis *axisPtr; + + if (GetAxisFromObj(interp, graphPtr, axisObjv[i], &axisPtr) != TCL_OK){ + return TCL_ERROR; } - for (link = Blt_Chain_FirstLink(chain); link!= NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; - - axisPtr = Blt_Chain_GetValue(link); - axisPtr->link = NULL; - axisPtr->flags &= ~AXIS_USE; - /* Clear the axis type if it's not currently used.*/ - if (axisPtr->refCount == 0) { - Blt_GraphSetObjectClass(&axisPtr->obj, CID_NONE); - } + if (axisPtr->obj.classId == CID_NONE) { + Blt_GraphSetObjectClass(&axisPtr->obj, classId); + } else if (axisPtr->obj.classId != classId) { + Tcl_AppendResult(interp, "wrong type axis \"", + axisPtr->obj.name, "\": can't use ", + axisPtr->obj.className, " type axis.", (char *)NULL); + return TCL_ERROR; } - Blt_Chain_Reset(chain); - for (i = 0; i < axisObjc; i++) { - Axis *axisPtr; - - if (GetAxisFromObj(interp, graphPtr, axisObjv[i], &axisPtr) != TCL_OK){ - return TCL_ERROR; - } - if (axisPtr->obj.classId == CID_NONE) { - Blt_GraphSetObjectClass(&axisPtr->obj, classId); - } else if (axisPtr->obj.classId != classId) { - Tcl_AppendResult(interp, "wrong type axis \"", - axisPtr->obj.name, "\": can't use ", - axisPtr->obj.className, " type axis.", (char *)NULL); - return TCL_ERROR; - } - if (axisPtr->link != NULL) { - /* Move the axis from the old margin's "use" list to the new. */ - Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link); - Blt_Chain_AppendLink(chain, axisPtr->link); - } else { - axisPtr->link = Blt_Chain_Append(chain, axisPtr); - } - axisPtr->chain = chain; - axisPtr->flags |= AXIS_USE; + if (axisPtr->link != NULL) { + /* Move the axis from the old margin's "use" list to the new. */ + Blt_Chain_UnlinkLink(axisPtr->chain, axisPtr->link); + Blt_Chain_AppendLink(chain, axisPtr->link); + } else { + axisPtr->link = Blt_Chain_Append(chain, axisPtr); } - graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); - /* When any axis changes, we need to layout the entire graph. */ - graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; + axisPtr->chain = chain; + axisPtr->flags |= AXIS_USE; + } + graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); + /* When any axis changes, we need to layout the entire graph. */ + graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); + Blt_EventuallyRedrawGraph(graphPtr); + return TCL_OK; } static int ViewOp(Tcl_Interp *interp, Axis *axisPtr, int objc, Tcl_Obj *const *objv) { - Graph *graphPtr; - double axisOffset, axisScale; - double fract; - double viewMin, viewMax, worldMin, worldMax; - double viewWidth, worldWidth; + Graph *graphPtr; + double axisOffset, axisScale; + double fract; + double viewMin, viewMax, worldMin, worldMax; + double viewWidth, worldWidth; + + graphPtr = axisPtr->obj.graphPtr; + worldMin = axisPtr->valueRange.min; + worldMax = axisPtr->valueRange.max; + /* Override data dimensions with user-selected limits. */ + if (!isnan(axisPtr->scrollMin)) { + worldMin = axisPtr->scrollMin; + } + if (!isnan(axisPtr->scrollMax)) { + worldMax = axisPtr->scrollMax; + } + viewMin = axisPtr->min; + viewMax = axisPtr->max; + /* Bound the view within scroll region. */ + if (viewMin < worldMin) { + viewMin = worldMin; + } + if (viewMax > worldMax) { + viewMax = worldMax; + } + if (axisPtr->logScale) { + worldMin = log10(worldMin); + worldMax = log10(worldMax); + viewMin = log10(viewMin); + viewMax = log10(viewMax); + } + worldWidth = worldMax - worldMin; + viewWidth = viewMax - viewMin; + + /* Unlike horizontal axes, vertical axis values run opposite of the + * scrollbar first/last values. So instead of pushing the axis minimum + * around, we move the maximum instead. */ + if (AxisIsHorizontal(axisPtr) != axisPtr->descending) { + axisOffset = viewMin - worldMin; + axisScale = graphPtr->hScale; + } else { + axisOffset = worldMax - viewMax; + axisScale = graphPtr->vScale; + } + if (objc == 4) { + Tcl_Obj *listObjPtr; + double first, last; - graphPtr = axisPtr->obj.graphPtr; - worldMin = axisPtr->valueRange.min; - worldMax = axisPtr->valueRange.max; - /* Override data dimensions with user-selected limits. */ - if (!isnan(axisPtr->scrollMin)) { - worldMin = axisPtr->scrollMin; - } - if (!isnan(axisPtr->scrollMax)) { - worldMax = axisPtr->scrollMax; - } - viewMin = axisPtr->min; - viewMax = axisPtr->max; - /* Bound the view within scroll region. */ - if (viewMin < worldMin) { - viewMin = worldMin; - } - if (viewMax > worldMax) { - viewMax = worldMax; - } - if (axisPtr->logScale) { - worldMin = log10(worldMin); - worldMax = log10(worldMax); - viewMin = log10(viewMin); - viewMax = log10(viewMax); - } - worldWidth = worldMax - worldMin; - viewWidth = viewMax - viewMin; - - /* Unlike horizontal axes, vertical axis values run opposite of the - * scrollbar first/last values. So instead of pushing the axis minimum - * around, we move the maximum instead. */ - if (AxisIsHorizontal(axisPtr) != axisPtr->descending) { - axisOffset = viewMin - worldMin; - axisScale = graphPtr->hScale; - } else { - axisOffset = worldMax - viewMax; - axisScale = graphPtr->vScale; - } - if (objc == 4) { - Tcl_Obj *listObjPtr; - double first, last; - - first = Clamp(axisOffset / worldWidth); - last = Clamp((axisOffset + viewWidth) / worldWidth); - listObjPtr = Tcl_NewListObj(0, NULL); - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(first)); - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(last)); - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; - } - fract = axisOffset / worldWidth; - if (GetAxisScrollInfo(interp, objc, objv, &fract, - viewWidth / worldWidth, axisPtr->scrollUnits, axisScale) != TCL_OK) { - return TCL_ERROR; - } - if (AxisIsHorizontal(axisPtr) != axisPtr->descending) { - axisPtr->reqMin = (fract * worldWidth) + worldMin; - axisPtr->reqMax = axisPtr->reqMin + viewWidth; - } else { - axisPtr->reqMax = worldMax - (fract * worldWidth); - axisPtr->reqMin = axisPtr->reqMax - viewWidth; - } - if (axisPtr->logScale) { - axisPtr->reqMin = EXP10(axisPtr->reqMin); - axisPtr->reqMax = EXP10(axisPtr->reqMax); - } - graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); - Blt_EventuallyRedrawGraph(graphPtr); + first = Clamp(axisOffset / worldWidth); + last = Clamp((axisOffset + viewWidth) / worldWidth); + listObjPtr = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(first)); + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(last)); + Tcl_SetObjResult(interp, listObjPtr); return TCL_OK; + } + fract = axisOffset / worldWidth; + if (GetAxisScrollInfo(interp, objc, objv, &fract, + viewWidth / worldWidth, axisPtr->scrollUnits, axisScale) != TCL_OK) { + return TCL_ERROR; + } + if (AxisIsHorizontal(axisPtr) != axisPtr->descending) { + axisPtr->reqMin = (fract * worldWidth) + worldMin; + axisPtr->reqMax = axisPtr->reqMin + viewWidth; + } else { + axisPtr->reqMax = worldMax - (fract * worldWidth); + axisPtr->reqMin = axisPtr->reqMax - viewWidth; + } + if (axisPtr->logScale) { + axisPtr->reqMin = EXP10(axisPtr->reqMin); + axisPtr->reqMax = EXP10(axisPtr->reqMax); + } + graphPtr->flags |= (GET_AXIS_GEOMETRY | LAYOUT_NEEDED | RESET_AXES); + Blt_EventuallyRedrawGraph(graphPtr); + return TCL_OK; } /* @@ -4622,23 +4626,23 @@ static int AxisCreateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; - int flags; + Axis *axisPtr; + int flags; - axisPtr = NewAxis(graphPtr, Tcl_GetString(objv[3]), MARGIN_NONE); - if (axisPtr == NULL) { - return TCL_ERROR; - } - flags = Blt_GraphType(graphPtr); - if ((Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, - axisPtr->obj.name, "Axis", configSpecs, objc - 4, objv + 4, - (char *)axisPtr, flags) != TCL_OK) || - (ConfigureAxis(axisPtr) != TCL_OK)) { - DestroyAxis(axisPtr); - return TCL_ERROR; - } - Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name, -1); - return TCL_OK; + axisPtr = NewAxis(graphPtr, Tcl_GetString(objv[3]), MARGIN_NONE); + if (axisPtr == NULL) { + return TCL_ERROR; + } + flags = Blt_GraphType(graphPtr); + if ((Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, + axisPtr->obj.name, "Axis", configSpecs, objc - 4, objv + 4, + (char *)axisPtr, flags) != TCL_OK) || + (ConfigureAxis(axisPtr) != TCL_OK)) { + DestroyAxis(axisPtr); + return TCL_ERROR; + } + Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name, -1); + return TCL_OK; } /* *--------------------------------------------------------------------------- @@ -4660,12 +4664,12 @@ static int AxisActivateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return ActivateOp(interp, axisPtr, objc, objv); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return ActivateOp(interp, axisPtr, objc, objv); } @@ -4680,28 +4684,28 @@ AxisActivateOp(Tcl_Interp *interp, Graph *graphPtr, int objc, /*ARGSUSED*/ static int AxisBindOp(Tcl_Interp *interp, Graph *graphPtr, int objc, - Tcl_Obj *const *objv) + Tcl_Obj *const *objv) { - if (objc == 3) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - Tcl_Obj *listObjPtr; - - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.tagTable, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - const char *tagName; - Tcl_Obj *objPtr; - - tagName = Tcl_GetHashKey(&graphPtr->axes.tagTable, hPtr); - objPtr = Tcl_NewStringObj(tagName, -1); - Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); - } - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; + if (objc == 3) { + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + Tcl_Obj *listObjPtr; + + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.tagTable, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + const char *tagName; + Tcl_Obj *objPtr; + + tagName = Tcl_GetHashKey(&graphPtr->axes.tagTable, hPtr); + objPtr = Tcl_NewStringObj(tagName, -1); + Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } - return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, - Blt_MakeAxisTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); + Tcl_SetObjResult(interp, listObjPtr); + return TCL_OK; + } + return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, + Blt_MakeAxisTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } @@ -4722,12 +4726,12 @@ AxisBindOp(Tcl_Interp *interp, Graph *graphPtr, int objc, static int AxisCgetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return CgetOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return CgetOp(interp, axisPtr, objc - 4, objv + 4); } /* @@ -4751,43 +4755,43 @@ static int AxisConfigureOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Tcl_Obj *const *options; - int i; - int nNames, nOpts; - - /* Figure out where the option value pairs begin */ - objc -= 3; - objv += 3; - for (i = 0; i < objc; i++) { - Axis *axisPtr; - const char *string; + Tcl_Obj *const *options; + int i; + int nNames, nOpts; + + /* Figure out where the option value pairs begin */ + objc -= 3; + objv += 3; + for (i = 0; i < objc; i++) { + Axis *axisPtr; + const char *string; - string = Tcl_GetString(objv[i]); - if (string[0] == '-') { - break; - } - if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } + string = Tcl_GetString(objv[i]); + if (string[0] == '-') { + break; + } + if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { + return TCL_ERROR; } - nNames = i; /* Number of pen names specified */ - nOpts = objc - i; /* Number of options specified */ - options = objv + i; /* Start of options in objv */ + } + nNames = i; /* Number of pen names specified */ + nOpts = objc - i; /* Number of options specified */ + options = objv + i; /* Start of options in objv */ - for (i = 0; i < nNames; i++) { - Axis *axisPtr; + for (i = 0; i < nNames; i++) { + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - if (ConfigureOp(interp, axisPtr, nOpts, options) != TCL_OK) { - break; - } + if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { + return TCL_ERROR; } - if (i < nNames) { - return TCL_ERROR; + if (ConfigureOp(interp, axisPtr, nOpts, options) != TCL_OK) { + break; } - return TCL_OK; + } + if (i < nNames) { + return TCL_ERROR; + } + return TCL_OK; } /* @@ -4809,20 +4813,20 @@ static int AxisDeleteOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - int i; + int i; - for (i = 3; i < objc; i++) { - Axis *axisPtr; + for (i = 3; i < objc; i++) { + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - axisPtr->flags |= DELETE_PENDING; - if (axisPtr->refCount == 0) { - Tcl_EventuallyFree(axisPtr, FreeAxis); - } + if (GetAxisFromObj(interp, graphPtr, objv[i], &axisPtr) != TCL_OK) { + return TCL_ERROR; } - return TCL_OK; + axisPtr->flags |= DELETE_PENDING; + if (axisPtr->refCount == 0) { + Tcl_EventuallyFree(axisPtr, FreeAxis); + } + } + return TCL_OK; } /* @@ -4844,29 +4848,29 @@ AxisDeleteOp(Tcl_Interp *interp, Graph *graphPtr, int objc, static int AxisFocusOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - if (objc > 3) { - Axis *axisPtr; - const char *string; - - axisPtr = NULL; - string = Tcl_GetString(objv[3]); - if ((string[0] != '\0') && - (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK)) { - return TCL_ERROR; - } - graphPtr->focusPtr = NULL; - if ((axisPtr != NULL) && - ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE)) { - graphPtr->focusPtr = axisPtr; - } - Blt_SetFocusItem(graphPtr->bindTable, graphPtr->focusPtr, NULL); - } - /* Return the name of the axis that has focus. */ - if (graphPtr->focusPtr != NULL) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - graphPtr->focusPtr->obj.name, -1); + if (objc > 3) { + Axis *axisPtr; + const char *string; + + axisPtr = NULL; + string = Tcl_GetString(objv[3]); + if ((string[0] != '\0') && + (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK)) { + return TCL_ERROR; } - return TCL_OK; + graphPtr->focusPtr = NULL; + if ((axisPtr != NULL) && + ((axisPtr->flags & (AXIS_USE|HIDE)) == AXIS_USE)) { + graphPtr->focusPtr = axisPtr; + } + Blt_SetFocusItem(graphPtr->bindTable, graphPtr->focusPtr, NULL); + } + /* Return the name of the axis that has focus. */ + if (graphPtr->focusPtr != NULL) { + Tcl_SetStringObj(Tcl_GetObjResult(interp), + graphPtr->focusPtr->obj.name, -1); + } + return TCL_OK; } @@ -4888,26 +4892,26 @@ AxisFocusOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) static int AxisGetOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; + + axisPtr = Blt_GetCurrentItem(graphPtr->bindTable); + /* Report only on axes. */ + if ((axisPtr != NULL) && + ((axisPtr->obj.classId == CID_AXIS_X) || + (axisPtr->obj.classId == CID_AXIS_Y) || + (axisPtr->obj.classId == CID_NONE))) { + char c; + char *string; - axisPtr = Blt_GetCurrentItem(graphPtr->bindTable); - /* Report only on axes. */ - if ((axisPtr != NULL) && - ((axisPtr->obj.classId == CID_AXIS_X) || - (axisPtr->obj.classId == CID_AXIS_Y) || - (axisPtr->obj.classId == CID_NONE))) { - char c; - char *string; - - string = Tcl_GetString(objv[3]); - c = string[0]; - if ((c == 'c') && (strcmp(string, "current") == 0)) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name,-1); - } else if ((c == 'd') && (strcmp(string, "detail") == 0)) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->detail, -1); - } + string = Tcl_GetString(objv[3]); + c = string[0]; + if ((c == 'c') && (strcmp(string, "current") == 0)) { + Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->obj.name,-1); + } else if ((c == 'd') && (strcmp(string, "detail") == 0)) { + Tcl_SetStringObj(Tcl_GetObjResult(interp), axisPtr->detail, -1); } - return TCL_OK; + } + return TCL_OK; } /* @@ -4928,12 +4932,12 @@ static int AxisInvTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return InvTransformOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return InvTransformOp(interp, axisPtr, objc - 4, objv + 4); } /* @@ -4954,12 +4958,12 @@ static int AxisLimitsOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return LimitsOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return LimitsOp(interp, axisPtr, objc - 4, objv + 4); } /* @@ -4980,12 +4984,12 @@ static int AxisMarginOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return MarginOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return MarginOp(interp, axisPtr, objc - 4, objv + 4); } @@ -5006,48 +5010,48 @@ AxisMarginOp(Tcl_Interp *interp, Graph *graphPtr, int objc, static int AxisNamesOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Tcl_Obj *listObjPtr; + Tcl_Obj *listObjPtr; - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - if (objc == 3) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; - - axisPtr = Tcl_GetHashValue(hPtr); - if (axisPtr->flags & DELETE_PENDING) { - continue; - } - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj(axisPtr->obj.name, -1)); - } - } else { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; - int i; - - axisPtr = Tcl_GetHashValue(hPtr); - for (i = 3; i < objc; i++) { - const char *pattern; - - pattern = Tcl_GetString(objv[i]); - if (Tcl_StringMatch(axisPtr->obj.name, pattern)) { - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj(axisPtr->obj.name, -1)); - break; - } - } + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + if (objc == 3) { + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; + + axisPtr = Tcl_GetHashValue(hPtr); + if (axisPtr->flags & DELETE_PENDING) { + continue; + } + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj(axisPtr->obj.name, -1)); + } + } else { + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; + int i; + + axisPtr = Tcl_GetHashValue(hPtr); + for (i = 3; i < objc; i++) { + const char *pattern; + + pattern = Tcl_GetString(objv[i]); + if (Tcl_StringMatch(axisPtr->obj.name, pattern)) { + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj(axisPtr->obj.name, -1)); + break; } + } } - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; + } + Tcl_SetObjResult(interp, listObjPtr); + return TCL_OK; } /* @@ -5067,12 +5071,12 @@ static int AxisTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return TransformOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return TransformOp(interp, axisPtr, objc - 4, objv + 4); } /* @@ -5091,47 +5095,47 @@ AxisTransformOp(Tcl_Interp *interp, Graph *graphPtr, int objc, */ static int AxisTypeOp(Tcl_Interp *interp, Graph *graphPtr, int objc, - Tcl_Obj *const *objv) + Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return TypeOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return TypeOp(interp, axisPtr, objc - 4, objv + 4); } static int AxisViewOp(Tcl_Interp *interp, Graph *graphPtr, int objc, Tcl_Obj *const *objv) { - Axis *axisPtr; + Axis *axisPtr; - if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { - return TCL_ERROR; - } - return ViewOp(interp, axisPtr, objc - 4, objv + 4); + if (GetAxisFromObj(interp, graphPtr, objv[3], &axisPtr) != TCL_OK) { + return TCL_ERROR; + } + return ViewOp(interp, axisPtr, objc - 4, objv + 4); } static Blt_OpSpec virtAxisOps[] = { - {"activate", 1, AxisActivateOp, 4, 4, "axisName"}, - {"bind", 1, AxisBindOp, 3, 6, "axisName sequence command"}, - {"cget", 2, AxisCgetOp, 5, 5, "axisName option"}, - {"configure", 2, AxisConfigureOp, 4, 0, "axisName ?axisName?... " - "?option value?..."}, - {"create", 2, AxisCreateOp, 4, 0, "axisName ?option value?..."}, - {"deactivate", 3, AxisActivateOp, 4, 4, "axisName"}, - {"delete", 3, AxisDeleteOp, 3, 0, "?axisName?..."}, - {"focus", 1, AxisFocusOp, 3, 4, "?axisName?"}, - {"get", 1, AxisGetOp, 4, 4, "name"}, - {"invtransform", 1, AxisInvTransformOp, 5, 5, "axisName value"}, - {"limits", 1, AxisLimitsOp, 4, 4, "axisName"}, - {"margin", 1, AxisMarginOp, 4, 4, "axisName"}, - {"names", 1, AxisNamesOp, 3, 0, "?pattern?..."}, - {"transform", 2, AxisTransformOp, 5, 5, "axisName value"}, - {"type", 2, AxisTypeOp, 4, 4, "axisName"}, - {"view", 1, AxisViewOp, 4, 7, "axisName ?moveto fract? " - "?scroll number what?"}, + {"activate", 1, AxisActivateOp, 4, 4, "axisName"}, + {"bind", 1, AxisBindOp, 3, 6, "axisName sequence command"}, + {"cget", 2, AxisCgetOp, 5, 5, "axisName option"}, + {"configure", 2, AxisConfigureOp, 4, 0, "axisName ?axisName?... " + "?option value?..."}, + {"create", 2, AxisCreateOp, 4, 0, "axisName ?option value?..."}, + {"deactivate", 3, AxisActivateOp, 4, 4, "axisName"}, + {"delete", 3, AxisDeleteOp, 3, 0, "?axisName?..."}, + {"focus", 1, AxisFocusOp, 3, 4, "?axisName?"}, + {"get", 1, AxisGetOp, 4, 4, "name"}, + {"invtransform", 1, AxisInvTransformOp, 5, 5, "axisName value"}, + {"limits", 1, AxisLimitsOp, 4, 4, "axisName"}, + {"margin", 1, AxisMarginOp, 4, 4, "axisName"}, + {"names", 1, AxisNamesOp, 3, 0, "?pattern?..."}, + {"transform", 2, AxisTransformOp, 5, 5, "axisName value"}, + {"type", 2, AxisTypeOp, 4, 4, "axisName"}, + {"view", 1, AxisViewOp, 4, 7, "axisName ?moveto fract? " + "?scroll number what?"}, }; static int nVirtAxisOps = sizeof(virtAxisOps) / sizeof(Blt_OpSpec); @@ -5139,29 +5143,29 @@ int Blt_VirtualAxisOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { - GraphVirtualAxisProc *proc; - int result; + GraphVirtualAxisProc *proc; + int result; - proc = Blt_GetOpFromObj(interp, nVirtAxisOps, virtAxisOps, BLT_OP_ARG2, - objc, objv, 0); - if (proc == NULL) { - return TCL_ERROR; - } - result = (*proc) (interp, graphPtr, objc, objv); - return result; + proc = Blt_GetOpFromObj(interp, nVirtAxisOps, virtAxisOps, BLT_OP_ARG2, + objc, objv, 0); + if (proc == NULL) { + return TCL_ERROR; + } + result = (*proc) (interp, graphPtr, objc, objv); + return result; } static Blt_OpSpec axisOps[] = { - {"activate", 1, ActivateOp, 3, 3, "",}, - {"bind", 1, BindOp, 2, 5, "sequence command",}, - {"cget", 2, CgetOp, 4, 4, "option",}, - {"configure", 2, ConfigureOp, 3, 0, "?option value?...",}, - {"deactivate", 1, ActivateOp, 3, 3, "",}, - {"invtransform", 1, InvTransformOp, 4, 4, "value",}, - {"limits", 1, LimitsOp, 3, 3, "",}, - {"transform", 1, TransformOp, 4, 4, "value",}, - {"use", 1, UseOp, 3, 4, "?axisName?",}, - {"view", 1, ViewOp, 3, 6, "?moveto fract? ",}, + {"activate", 1, ActivateOp, 3, 3, "",}, + {"bind", 1, BindOp, 2, 5, "sequence command",}, + {"cget", 2, CgetOp, 4, 4, "option",}, + {"configure", 2, ConfigureOp, 3, 0, "?option value?...",}, + {"deactivate", 1, ActivateOp, 3, 3, "",}, + {"invtransform", 1, InvTransformOp, 4, 4, "value",}, + {"limits", 1, LimitsOp, 3, 3, "",}, + {"transform", 1, TransformOp, 4, 4, "value",}, + {"use", 1, UseOp, 3, 4, "?axisName?",}, + {"view", 1, ViewOp, 3, 6, "?moveto fract? ",}, }; static int nAxisOps = sizeof(axisOps) / sizeof(Blt_OpSpec); @@ -5170,90 +5174,90 @@ int Blt_AxisOp(Tcl_Interp *interp, Graph *graphPtr, int margin, int objc, Tcl_Obj *const *objv) { - int result; - GraphAxisProc *proc; + int result; + GraphAxisProc *proc; - proc = Blt_GetOpFromObj(interp, nAxisOps, axisOps, BLT_OP_ARG2, - objc, objv, 0); - if (proc == NULL) { - return TCL_ERROR; - } - if (proc == UseOp) { - lastMargin = margin; /* Set global variable to the margin + proc = Blt_GetOpFromObj(interp, nAxisOps, axisOps, BLT_OP_ARG2, + objc, objv, 0); + if (proc == NULL) { + return TCL_ERROR; + } + if (proc == UseOp) { + lastMargin = margin; /* Set global variable to the margin * in the argument list. Needed only * for UseOp. */ - result = (*proc)(interp, (Axis *)graphPtr, objc - 3, objv + 3); - } else { - Axis *axisPtr; + result = (*proc)(interp, (Axis *)graphPtr, objc - 3, objv + 3); + } else { + Axis *axisPtr; - axisPtr = Blt_GetFirstAxis(graphPtr->margins[margin].axes); - if (axisPtr == NULL) { - return TCL_OK; - } - result = (*proc)(interp, axisPtr, objc - 3, objv + 3); + axisPtr = Blt_GetFirstAxis(graphPtr->margins[margin].axes); + if (axisPtr == NULL) { + return TCL_OK; } - return result; + result = (*proc)(interp, axisPtr, objc - 3, objv + 3); + } + return result; } void Blt_MapAxes(Graph *graphPtr) { - int margin; + int margin; - for (margin = 0; margin < 4; margin++) { - Blt_Chain chain; - Blt_ChainLink link; - int count, offset; - - chain = graphPtr->margins[margin].axes; - count = offset = 0; - for (link = Blt_Chain_FirstLink(chain); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; - - axisPtr = Blt_Chain_GetValue(link); - if ((axisPtr->flags & (AXIS_USE|DELETE_PENDING)) != AXIS_USE) { - continue; - } - if (graphPtr->stackAxes) { - if (axisPtr->reqNumMajorTicks <= 0) { - axisPtr->reqNumMajorTicks = 4; - } - MapStackedAxis(axisPtr, count, margin); - } else { - if (axisPtr->reqNumMajorTicks <= 0) { - axisPtr->reqNumMajorTicks = 4; - } - MapAxis(axisPtr, offset, margin); - } - if (axisPtr->flags & AXIS_GRID) { - MapGridlines(axisPtr); - } - offset += (AxisIsHorizontal(axisPtr)) - ? axisPtr->height : axisPtr->width; - count++; - } - } + for (margin = 0; margin < 4; margin++) { + Blt_Chain chain; + Blt_ChainLink link; + int count, offset; + + chain = graphPtr->margins[margin].axes; + count = offset = 0; + for (link = Blt_Chain_FirstLink(chain); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; + + axisPtr = Blt_Chain_GetValue(link); + if ((axisPtr->flags & (AXIS_USE|DELETE_PENDING)) != AXIS_USE) { + continue; + } + if (graphPtr->stackAxes) { + if (axisPtr->reqNumMajorTicks <= 0) { + axisPtr->reqNumMajorTicks = 4; + } + MapStackedAxis(axisPtr, count, margin); + } else { + if (axisPtr->reqNumMajorTicks <= 0) { + axisPtr->reqNumMajorTicks = 4; + } + MapAxis(axisPtr, offset, margin); + } + if (axisPtr->flags & AXIS_GRID) { + MapGridlines(axisPtr); + } + offset += (AxisIsHorizontal(axisPtr)) + ? axisPtr->height : axisPtr->width; + count++; + } + } } void Blt_DrawAxes(Graph *graphPtr, Drawable drawable) { - int i; + int i; - for (i = 0; i < 4; i++) { - Blt_ChainLink link; + for (i = 0; i < 4; i++) { + Blt_ChainLink link; - for (link = Blt_Chain_LastLink(graphPtr->margins[i].axes); - link != NULL; link = Blt_Chain_PrevLink(link)) { - Axis *axisPtr; + for (link = Blt_Chain_LastLink(graphPtr->margins[i].axes); + link != NULL; link = Blt_Chain_PrevLink(link)) { + Axis *axisPtr; - axisPtr = Blt_Chain_GetValue(link); - if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) { - DrawAxis(axisPtr, drawable); - } - } + axisPtr = Blt_Chain_GetValue(link); + if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) { + DrawAxis(axisPtr, drawable); + } } + } } /* @@ -5271,31 +5275,31 @@ Blt_DrawAxes(Graph *graphPtr, Drawable drawable) void Blt_DrawGrids(Graph *graphPtr, Drawable drawable) { - int i; + int i; - for (i = 0; i < 4; i++) { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; - - axisPtr = Blt_Chain_GetValue(link); - if (axisPtr->flags & (DELETE_PENDING|HIDE)) { - continue; - } - if ((axisPtr->flags & AXIS_USE) && (axisPtr->flags & AXIS_GRID)) { - Blt_Draw2DSegments(graphPtr->display, drawable, - axisPtr->major.gc, axisPtr->major.segments, - axisPtr->major.nUsed); - if (axisPtr->flags & AXIS_GRIDMINOR) { - Blt_Draw2DSegments(graphPtr->display, drawable, - axisPtr->minor.gc, axisPtr->minor.segments, - axisPtr->minor.nUsed); - } - } + for (i = 0; i < 4; i++) { + Blt_ChainLink link; + + for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; + + axisPtr = Blt_Chain_GetValue(link); + if (axisPtr->flags & (DELETE_PENDING|HIDE)) { + continue; + } + if ((axisPtr->flags & AXIS_USE) && (axisPtr->flags & AXIS_GRID)) { + Blt_Draw2DSegments(graphPtr->display, drawable, + axisPtr->major.gc, axisPtr->major.segments, + axisPtr->major.nUsed); + if (axisPtr->flags & AXIS_GRIDMINOR) { + Blt_Draw2DSegments(graphPtr->display, drawable, + axisPtr->minor.gc, axisPtr->minor.segments, + axisPtr->minor.nUsed); } + } } + } } /* @@ -5313,60 +5317,60 @@ Blt_DrawGrids(Graph *graphPtr, Drawable drawable) void Blt_GridsToPostScript(Graph *graphPtr, Blt_Ps ps) { - int i; + int i; - for (i = 0; i < 4; i++) { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; - - axisPtr = Blt_Chain_GetValue(link); - if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE|AXIS_GRID)) != - (AXIS_GRID|AXIS_USE)) { - continue; - } - Blt_Ps_Format(ps, "%% Axis %s: grid line attributes\n", - axisPtr->obj.name); - Blt_Ps_XSetLineAttributes(ps, axisPtr->major.color, - axisPtr->major.lineWidth, &axisPtr->major.dashes, CapButt, - JoinMiter); - Blt_Ps_Format(ps, "%% Axis %s: major grid line segments\n", - axisPtr->obj.name); - Blt_Ps_Draw2DSegments(ps, axisPtr->major.segments, - axisPtr->major.nUsed); - if (axisPtr->flags & AXIS_GRIDMINOR) { - Blt_Ps_XSetLineAttributes(ps, axisPtr->minor.color, - axisPtr->minor.lineWidth, &axisPtr->minor.dashes, CapButt, - JoinMiter); - Blt_Ps_Format(ps, "%% Axis %s: minor grid line segments\n", - axisPtr->obj.name); - Blt_Ps_Draw2DSegments(ps, axisPtr->minor.segments, - axisPtr->minor.nUsed); - } - } - } + for (i = 0; i < 4; i++) { + Blt_ChainLink link; + + for (link = Blt_Chain_FirstLink(graphPtr->margins[i].axes); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; + + axisPtr = Blt_Chain_GetValue(link); + if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE|AXIS_GRID)) != + (AXIS_GRID|AXIS_USE)) { + continue; + } + Blt_Ps_Format(ps, "%% Axis %s: grid line attributes\n", + axisPtr->obj.name); + Blt_Ps_XSetLineAttributes(ps, axisPtr->major.color, + axisPtr->major.lineWidth, &axisPtr->major.dashes, CapButt, + JoinMiter); + Blt_Ps_Format(ps, "%% Axis %s: major grid line segments\n", + axisPtr->obj.name); + Blt_Ps_Draw2DSegments(ps, axisPtr->major.segments, + axisPtr->major.nUsed); + if (axisPtr->flags & AXIS_GRIDMINOR) { + Blt_Ps_XSetLineAttributes(ps, axisPtr->minor.color, + axisPtr->minor.lineWidth, &axisPtr->minor.dashes, CapButt, + JoinMiter); + Blt_Ps_Format(ps, "%% Axis %s: minor grid line segments\n", + axisPtr->obj.name); + Blt_Ps_Draw2DSegments(ps, axisPtr->minor.segments, + axisPtr->minor.nUsed); + } + } + } } void Blt_AxesToPostScript(Graph *graphPtr, Blt_Ps ps) { - Margin *mp, *mend; + Margin *mp, *mend; - for (mp = graphPtr->margins, mend = mp + 4; mp < mend; mp++) { - Blt_ChainLink link; + for (mp = graphPtr->margins, mend = mp + 4; mp < mend; mp++) { + Blt_ChainLink link; - for (link = Blt_Chain_FirstLink(mp->axes); link != NULL; - link = Blt_Chain_NextLink(link)) { - Axis *axisPtr; + for (link = Blt_Chain_FirstLink(mp->axes); link != NULL; + link = Blt_Chain_NextLink(link)) { + Axis *axisPtr; - axisPtr = Blt_Chain_GetValue(link); - if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) { - AxisToPostScript(ps, axisPtr); - } - } + axisPtr = Blt_Chain_GetValue(link); + if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) == AXIS_USE) { + AxisToPostScript(ps, axisPtr); + } } + } } @@ -5391,246 +5395,244 @@ Blt_AxesToPostScript(Graph *graphPtr, Blt_Ps ps) void Blt_DrawAxisLimits(Graph *graphPtr, Drawable drawable) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - char minString[200], maxString[200]; - int vMin, hMin, vMax, hMax; + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + char minString[200], maxString[200]; + int vMin, hMin, vMax, hMax; #define SPACING 8 - vMin = vMax = graphPtr->left + graphPtr->xPad + 2; - hMin = hMax = graphPtr->bottom - graphPtr->yPad - 2; /* Offsets */ + vMin = vMax = graphPtr->left + graphPtr->xPad + 2; + hMin = hMax = graphPtr->bottom - graphPtr->yPad - 2; /* Offsets */ - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; - Dim2D textDim; - const char *minFmt, *maxFmt; - char *minPtr, *maxPtr; - int isHoriz; - - axisPtr = Tcl_GetHashValue(hPtr); - if (axisPtr->flags & DELETE_PENDING) { - continue; - } - if (axisPtr->nFormats == 0) { - continue; - } - isHoriz = AxisIsHorizontal(axisPtr); - minPtr = maxPtr = NULL; - minFmt = maxFmt = axisPtr->limitsFormats[0]; - if (axisPtr->nFormats > 1) { - maxFmt = axisPtr->limitsFormats[1]; - } - if (minFmt[0] != '\0') { - minPtr = minString; - sprintf_s(minString, 200, minFmt, axisPtr->axisRange.min); - } - if (maxFmt[0] != '\0') { - maxPtr = maxString; - sprintf_s(maxString, 200, maxFmt, axisPtr->axisRange.max); - } - if (axisPtr->descending) { - char *tmp; + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; + Dim2D textDim; + const char *minFmt, *maxFmt; + char *minPtr, *maxPtr; + int isHoriz; - tmp = minPtr, minPtr = maxPtr, maxPtr = tmp; - } - if (maxPtr != NULL) { - if (isHoriz) { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); - Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE); - Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr, - &axisPtr->limitsTextStyle, graphPtr->right, hMax, &textDim); - hMax -= (textDim.height + SPACING); - } else { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); - Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW); - Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr, - &axisPtr->limitsTextStyle, vMax, graphPtr->top, &textDim); - vMax += (textDim.width + SPACING); - } - } - if (minPtr != NULL) { - Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW); - if (isHoriz) { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); - Blt_DrawText2(graphPtr->tkwin, drawable, minPtr, - &axisPtr->limitsTextStyle, graphPtr->left, hMin, &textDim); - hMin -= (textDim.height + SPACING); - } else { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); - Blt_DrawText2(graphPtr->tkwin, drawable, minPtr, - &axisPtr->limitsTextStyle, vMin, graphPtr->bottom, &textDim); - vMin += (textDim.width + SPACING); - } - } - } /* Loop on axes */ + axisPtr = Tcl_GetHashValue(hPtr); + if (axisPtr->flags & DELETE_PENDING) { + continue; + } + if (axisPtr->nFormats == 0) { + continue; + } + isHoriz = AxisIsHorizontal(axisPtr); + minPtr = maxPtr = NULL; + minFmt = maxFmt = axisPtr->limitsFormats[0]; + if (axisPtr->nFormats > 1) { + maxFmt = axisPtr->limitsFormats[1]; + } + if (minFmt[0] != '\0') { + minPtr = minString; + sprintf_s(minString, 200, minFmt, axisPtr->axisRange.min); + } + if (maxFmt[0] != '\0') { + maxPtr = maxString; + sprintf_s(maxString, 200, maxFmt, axisPtr->axisRange.max); + } + if (axisPtr->descending) { + char *tmp; + + tmp = minPtr, minPtr = maxPtr, maxPtr = tmp; + } + if (maxPtr != NULL) { + if (isHoriz) { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); + Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE); + Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr, + &axisPtr->limitsTextStyle, graphPtr->right, hMax, &textDim); + hMax -= (textDim.height + SPACING); + } else { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); + Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW); + Blt_DrawText2(graphPtr->tkwin, drawable, maxPtr, + &axisPtr->limitsTextStyle, vMax, graphPtr->top, &textDim); + vMax += (textDim.width + SPACING); + } + } + if (minPtr != NULL) { + Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW); + if (isHoriz) { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); + Blt_DrawText2(graphPtr->tkwin, drawable, minPtr, + &axisPtr->limitsTextStyle, graphPtr->left, hMin, &textDim); + hMin -= (textDim.height + SPACING); + } else { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); + Blt_DrawText2(graphPtr->tkwin, drawable, minPtr, + &axisPtr->limitsTextStyle, vMin, graphPtr->bottom, &textDim); + vMin += (textDim.width + SPACING); + } + } + } /* Loop on axes */ } void Blt_AxisLimitsToPostScript(Graph *graphPtr, Blt_Ps ps) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - double vMin, hMin, vMax, hMax; - char string[200]; + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + double vMin, hMin, vMax, hMax; + char string[200]; #define SPACING 8 - vMin = vMax = graphPtr->left + graphPtr->xPad + 2; - hMin = hMax = graphPtr->bottom - graphPtr->yPad - 2; /* Offsets */ - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; - const char *minFmt, *maxFmt; - unsigned int textWidth, textHeight; - - axisPtr = Tcl_GetHashValue(hPtr); - if (axisPtr->flags & DELETE_PENDING) { - continue; - } - if (axisPtr->nFormats == 0) { - continue; - } - minFmt = maxFmt = axisPtr->limitsFormats[0]; - if (axisPtr->nFormats > 1) { - maxFmt = axisPtr->limitsFormats[1]; - } - if (*maxFmt != '\0') { - sprintf_s(string, 200, maxFmt, axisPtr->axisRange.max); - Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth, - &textHeight); - if ((textWidth > 0) && (textHeight > 0)) { - if (axisPtr->obj.classId == CID_AXIS_X) { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); - Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE); - Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, - (double)graphPtr->right, hMax); - hMax -= (textWidth + SPACING); - } else { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); - Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW); - Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, - vMax, (double)graphPtr->top); - vMax += (textWidth + SPACING); - } - } - } - if (*minFmt != '\0') { - sprintf_s(string, 200, minFmt, axisPtr->axisRange.min); - Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth, - &textHeight); - if ((textWidth > 0) && (textHeight > 0)) { - Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW); - if (axisPtr->obj.classId == CID_AXIS_X) { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); - Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, - (double)graphPtr->left, hMin); - hMin -= (textWidth + SPACING); - } else { - Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); - Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, - vMin, (double)graphPtr->bottom); - vMin += (textWidth + SPACING); - } - } + vMin = vMax = graphPtr->left + graphPtr->xPad + 2; + hMin = hMax = graphPtr->bottom - graphPtr->yPad - 2; /* Offsets */ + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; + const char *minFmt, *maxFmt; + unsigned int textWidth, textHeight; + + axisPtr = Tcl_GetHashValue(hPtr); + if (axisPtr->flags & DELETE_PENDING) { + continue; + } + if (axisPtr->nFormats == 0) { + continue; + } + minFmt = maxFmt = axisPtr->limitsFormats[0]; + if (axisPtr->nFormats > 1) { + maxFmt = axisPtr->limitsFormats[1]; + } + if (*maxFmt != '\0') { + sprintf_s(string, 200, maxFmt, axisPtr->axisRange.max); + Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth, + &textHeight); + if ((textWidth > 0) && (textHeight > 0)) { + if (axisPtr->obj.classId == CID_AXIS_X) { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); + Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SE); + Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, + (double)graphPtr->right, hMax); + hMax -= (textWidth + SPACING); + } else { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); + Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_NW); + Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, + vMax, (double)graphPtr->top); + vMax += (textWidth + SPACING); + } + } + } + if (*minFmt != '\0') { + sprintf_s(string, 200, minFmt, axisPtr->axisRange.min); + Blt_GetTextExtents(axisPtr->tickFont, 0, string, -1, &textWidth, + &textHeight); + if ((textWidth > 0) && (textHeight > 0)) { + Blt_Ts_SetAnchor(axisPtr->limitsTextStyle, TK_ANCHOR_SW); + if (axisPtr->obj.classId == CID_AXIS_X) { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 90.0); + Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, + (double)graphPtr->left, hMin); + hMin -= (textWidth + SPACING); + } else { + Blt_Ts_SetAngle(axisPtr->limitsTextStyle, 0.0); + Blt_Ps_DrawText(ps, string, &axisPtr->limitsTextStyle, + vMin, (double)graphPtr->bottom); + vMin += (textWidth + SPACING); } + } } + } } Axis * Blt_GetFirstAxis(Blt_Chain chain) { - Blt_ChainLink link; + Blt_ChainLink link; - link = Blt_Chain_FirstLink(chain); - if (link == NULL) { - return NULL; - } - return Blt_Chain_GetValue(link); + link = Blt_Chain_FirstLink(chain); + if (link == NULL) { + return NULL; + } + return Blt_Chain_GetValue(link); } Axis * Blt_NearestAxis(Graph *graphPtr, int x, int y) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; - for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { - Axis *axisPtr; + for (hPtr = Tcl_FirstHashEntry(&graphPtr->axes.table, &cursor); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { + Axis *axisPtr; - axisPtr = Tcl_GetHashValue(hPtr); - if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) != AXIS_USE) { - continue; - } - if (axisPtr->flags & AXIS_SHOWTICKS) { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; - link = Blt_Chain_NextLink(link)) { - TickLabel *labelPtr; - Point2d t; - double rw, rh; - Point2d bbox[5]; - - labelPtr = Blt_Chain_GetValue(link); - Blt_GetBoundingBox(labelPtr->width, labelPtr->height, - axisPtr->tickAngle, &rw, &rh, bbox); - t = Blt_AnchorPoint(labelPtr->anchorPos.x, - labelPtr->anchorPos.y, rw, rh, axisPtr->tickAnchor); - t.x = x - t.x - (rw * 0.5); - t.y = y - t.y - (rh * 0.5); - - bbox[4] = bbox[0]; - if (Blt_PointInPolygon(&t, bbox, 5)) { - axisPtr->detail = "label"; - return axisPtr; - } - } - } - if (axisPtr->title != NULL) { /* and then the title string. */ - Point2d bbox[5]; - Point2d t; - double rw, rh; - unsigned int w, h; - - Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title,-1,&w,&h); - Blt_GetBoundingBox(w, h, axisPtr->titleAngle, &rw, &rh, bbox); - t = Blt_AnchorPoint(axisPtr->titlePos.x, axisPtr->titlePos.y, - rw, rh, axisPtr->titleAnchor); - /* Translate the point so that the 0,0 is the upper left - * corner of the bounding box. */ - t.x = x - t.x - (rw * 0.5); - t.y = y - t.y - (rh * 0.5); - - bbox[4] = bbox[0]; - if (Blt_PointInPolygon(&t, bbox, 5)) { - axisPtr->detail = "title"; - return axisPtr; - } - } - if (axisPtr->lineWidth > 0) { /* Check for the axis region */ - if ((x <= axisPtr->right) && (x >= axisPtr->left) && - (y <= axisPtr->bottom) && (y >= axisPtr->top)) { - axisPtr->detail = "line"; - return axisPtr; - } - } + axisPtr = Tcl_GetHashValue(hPtr); + if ((axisPtr->flags & (DELETE_PENDING|HIDE|AXIS_USE)) != AXIS_USE) { + continue; } - return NULL; + if (axisPtr->flags & AXIS_SHOWTICKS) { + Blt_ChainLink link; + + for (link = Blt_Chain_FirstLink(axisPtr->tickLabels); link != NULL; + link = Blt_Chain_NextLink(link)) { + TickLabel *labelPtr; + Point2d t; + double rw, rh; + Point2d bbox[5]; + + labelPtr = Blt_Chain_GetValue(link); + Blt_GetBoundingBox(labelPtr->width, labelPtr->height, + axisPtr->tickAngle, &rw, &rh, bbox); + t = Blt_AnchorPoint(labelPtr->anchorPos.x, + labelPtr->anchorPos.y, rw, rh, axisPtr->tickAnchor); + t.x = x - t.x - (rw * 0.5); + t.y = y - t.y - (rh * 0.5); + + bbox[4] = bbox[0]; + if (Blt_PointInPolygon(&t, bbox, 5)) { + axisPtr->detail = "label"; + return axisPtr; + } + } + } + if (axisPtr->title != NULL) { /* and then the title string. */ + Point2d bbox[5]; + Point2d t; + double rw, rh; + unsigned int w, h; + + Blt_GetTextExtents(axisPtr->titleFont, 0, axisPtr->title,-1,&w,&h); + Blt_GetBoundingBox(w, h, axisPtr->titleAngle, &rw, &rh, bbox); + t = Blt_AnchorPoint(axisPtr->titlePos.x, axisPtr->titlePos.y, + rw, rh, axisPtr->titleAnchor); + /* Translate the point so that the 0,0 is the upper left + * corner of the bounding box. */ + t.x = x - t.x - (rw * 0.5); + t.y = y - t.y - (rh * 0.5); + + bbox[4] = bbox[0]; + if (Blt_PointInPolygon(&t, bbox, 5)) { + axisPtr->detail = "title"; + return axisPtr; + } + } + if (axisPtr->lineWidth > 0) { /* Check for the axis region */ + if ((x <= axisPtr->right) && (x >= axisPtr->left) && + (y <= axisPtr->bottom) && (y >= axisPtr->top)) { + axisPtr->detail = "line"; + return axisPtr; + } + } + } + return NULL; } ClientData Blt_MakeAxisTag(Graph *graphPtr, const char *tagName) { - Tcl_HashEntry *hPtr; - int isNew; + Tcl_HashEntry *hPtr; + int isNew; - hPtr = Tcl_CreateHashEntry(&graphPtr->axes.tagTable, tagName, &isNew); - return Tcl_GetHashKey(&graphPtr->axes.tagTable, hPtr); + hPtr = Tcl_CreateHashEntry(&graphPtr->axes.tagTable, tagName, &isNew); + return Tcl_GetHashKey(&graphPtr->axes.tagTable, hPtr); } - - /* *--------------------------------------------------------------------------- * @@ -5692,8 +5694,7 @@ Blt_MakeAxisTag(Graph *graphPtr, const char *tagName) * *--------------------------------------------------------------------------- */ -static void -TimeScaleAxis(Axis *axisPtr, double min, double max) +static void TimeScaleAxis(Axis *axisPtr, double min, double max) { } diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C index 5faa855..8f06097 100644 --- a/src/bltGrElemBar.C +++ b/src/bltGrElemBar.C @@ -118,6 +118,7 @@ typedef struct { typedef struct { GraphObj obj; /* Must be first field in element. */ unsigned int flags; + int hide; Tcl_HashEntry *hashPtr; /* Fields specific to elements. */ @@ -251,11 +252,6 @@ static Tk_OptionSpec barElemOptionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -Blt_CustomOption bitmaskBarElemHideOption = - { - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)HIDE - }; - /* static Blt_ConfigSpec barElemConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen", @@ -2295,7 +2291,7 @@ void Blt_InitBarSetTable(Graph *graphPtr) int nPoints; elemPtr = Blt_Chain_GetValue(link); - if ((elemPtr->flags & HIDE) || (elemPtr->obj.classId != CID_ELEM_BAR)) { + if ((elemPtr->hide) || (elemPtr->obj.classId != CID_ELEM_BAR)) { continue; } nSegs++; @@ -2436,7 +2432,7 @@ void Blt_ComputeBarStacks(Graph *graphPtr) double *x, *y, *xend; elemPtr = Blt_Chain_GetValue(link); - if ((elemPtr->flags & HIDE) || (elemPtr->obj.classId != CID_ELEM_BAR)) { + if ((elemPtr->hide) || (elemPtr->obj.classId != CID_ELEM_BAR)) { continue; } for (x = elemPtr->x.values, y = elemPtr->y.values, diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C index 8139ae6..c07b3eb 100644 --- a/src/bltGrElemLine.C +++ b/src/bltGrElemLine.C @@ -248,6 +248,7 @@ typedef struct { typedef struct { GraphObj obj; /* Must be first field in element. */ unsigned int flags; + int hide; Tcl_HashEntry *hashPtr; /* Fields specific to elements. */ @@ -350,39 +351,12 @@ typedef struct { * grouped by pen style. */ } LineElement; -static Blt_OptionParseProc ObjToSmoothProc; -static Blt_OptionPrintProc SmoothToObjProc; -static Blt_CustomOption smoothOption = - { - ObjToSmoothProc, SmoothToObjProc, NULL, (ClientData)0 - }; - -static Blt_OptionParseProc ObjToPenDirProc; -static Blt_OptionPrintProc PenDirToObjProc; -static Blt_CustomOption penDirOption = - { - ObjToPenDirProc, PenDirToObjProc, NULL, (ClientData)0 - }; - -static Blt_OptionFreeProc FreeSymbolProc; -static Blt_OptionParseProc ObjToSymbolProc; -static Blt_OptionPrintProc SymbolToObjProc; -static Blt_CustomOption symbolOption = - { - ObjToSymbolProc, SymbolToObjProc, FreeSymbolProc, (ClientData)0 - }; - -extern Blt_CustomOption bltLineStylesOption; -extern Blt_CustomOption bltColorOption; -extern Blt_CustomOption bltValuesOption; -extern Blt_CustomOption bltValuePairsOption; -extern Blt_CustomOption bltXAxisOption; -extern Blt_CustomOption bltYAxisOption; - //*** extern Tk_ObjCustomOption linePenObjOption; extern Tk_ObjCustomOption pairsObjOption; +extern Tk_ObjCustomOption xAxisObjOption; +extern Tk_ObjCustomOption yAxisObjOption; static Tk_OptionSpec lineElemOptionSpecs[] = { {TK_OPTION_CUSTOM, "-activepen", "activePen", "ActivePen", @@ -404,10 +378,17 @@ static Tk_OptionSpec lineElemOptionSpecs[] = { TK_OPTION_NULL_OK, &dashesObjOption, 0}, {TK_OPTION_CUSTOM, "-data", "data", "Data", NULL, -1, 0, 0, &pairsObjOption, 0}, + {TK_OPTION_COLOR, "-errorbarcolor", "errorBarColor", "ErrorBarColor", + "red", -1, Tk_Offset(LineElement, builtinPen.errorBarColor), 0, NULL, 0}, {TK_OPTION_PIXELS,"-errorbarwidth", "errorBarWidth", "ErrorBarWidth", "1", -1, Tk_Offset(LineElement, builtinPen.errorBarLineWidth), 0, NULL, 0}, {TK_OPTION_PIXELS, "-errorbarcap", "errorBarCap", "ErrorBarCap", "1", -1, Tk_Offset(LineElement, builtinPen.errorBarCapWidth), 0, NULL, 0}, + {TK_OPTION_COLOR, "-fill", "fill", "Fill", + NULL, -1, Tk_Offset(LineElement, builtinPen.symbol.fillColor), + TK_OPTION_NULL_OK, NULL, 0}, + {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide", + "no", -1, Tk_Offset(LineElement, hide), 0, NULL, 0}, {TK_OPTION_STRING, "-label", "label", "Label", NULL, -1, Tk_Offset(LineElement, label), TK_OPTION_NULL_OK, NULL, 0}, @@ -415,8 +396,18 @@ static Tk_OptionSpec lineElemOptionSpecs[] = { "flat", -1, Tk_Offset(LineElement, legendRelief), 0, NULL, 0}, {TK_OPTION_PIXELS, "-linewidth", "lineWidth", "LineWidth", "1", -1, Tk_Offset(LineElement, builtinPen.traceWidth), 0, NULL, 0}, + {TK_OPTION_CUSTOM, "-mapx", "mapX", "MapX", + "x", -1, Tk_Offset(LineElement, axes.x), 0, &xAxisObjOption, 0}, + {TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY", + "y", -1, Tk_Offset(LineElement, axes.y), 0, &yAxisObjOption, 0}, {TK_OPTION_INT, "-maxsymbols", "maxSymbols", "MaxSymbols", 0, -1, Tk_Offset(LineElement, reqMaxSymbols), 0, NULL, 0}, + {TK_OPTION_COLOR, "-offdash", "offDash", "OffDash", + NULL, -1, Tk_Offset(LineElement, builtinPen.traceOffColor), + TK_OPTION_NULL_OK, NULL, 0}, + {TK_OPTION_COLOR, "-outline", "outline", "Outline", + NULL, -1, Tk_Offset(LineElement, builtinPen.symbol.outlineColor), + TK_OPTION_NULL_OK, NULL,0}, {TK_OPTION_PIXELS, "-outlinewidth", "outlineWidth", "OutlineWidth", "1", -1, Tk_Offset(LineElement, builtinPen.symbol.outlineWidth), 0, NULL, 0}, {TK_OPTION_CUSTOM, "-pen", "pen", "Pen", @@ -443,12 +434,36 @@ static Tk_OptionSpec lineElemOptionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -Blt_CustomOption bitmaskLineElemHideOption = +extern Blt_CustomOption bltLineStylesOption; +/* +static Blt_OptionParseProc ObjToSmoothProc; +static Blt_OptionPrintProc SmoothToObjProc; +static Blt_CustomOption smoothOption = { - ObjToBitmaskProc, BitmaskToObjProc, NULL, (ClientData)HIDE + ObjToSmoothProc, SmoothToObjProc, NULL, (ClientData)0 }; -/* +static Blt_OptionParseProc ObjToPenDirProc; +static Blt_OptionPrintProc PenDirToObjProc; +static Blt_CustomOption penDirOption = + { + ObjToPenDirProc, PenDirToObjProc, NULL, (ClientData)0 + }; + +static Blt_OptionFreeProc FreeSymbolProc; +static Blt_OptionParseProc ObjToSymbolProc; +static Blt_OptionPrintProc SymbolToObjProc; +static Blt_CustomOption symbolOption = + { + ObjToSymbolProc, SymbolToObjProc, FreeSymbolProc, (ClientData)0 + }; + +extern Blt_CustomOption bltColorOption; +extern Blt_CustomOption bltValuesOption; +extern Blt_CustomOption bltValuePairsOption; +extern Blt_CustomOption bltXAxisOption; +extern Blt_CustomOption bltYAxisOption; + static Blt_ConfigSpec lineElemConfigSpecs[] = { {BLT_CONFIG_CUSTOM, "-activepen", "activePen", "ActivePen", "activeLine", Tk_Offset(LineElement, activePenPtr), @@ -996,15 +1011,15 @@ static int ConfigurePenProc(Graph* graphPtr, Pen* penPtr) */ gcMask = (GCLineWidth | GCForeground); colorPtr = lpPtr->symbol.outlineColor; - if (colorPtr == COLOR_DEFAULT) { + if (colorPtr == NULL) { colorPtr = lpPtr->traceColor; } gcValues.foreground = colorPtr->pixel; if (lpPtr->symbol.type == SYMBOL_BITMAP) { colorPtr = lpPtr->symbol.fillColor; - if (colorPtr == COLOR_DEFAULT) { + if (!colorPtr) colorPtr = lpPtr->traceColor; - } + /* * Set a clip mask if either * 1) no background color was designated or @@ -1037,9 +1052,9 @@ static int ConfigurePenProc(Graph* graphPtr, Pen* penPtr) gcMask = (GCLineWidth | GCForeground); colorPtr = lpPtr->symbol.fillColor; - if (colorPtr == COLOR_DEFAULT) { + if (!colorPtr) colorPtr = lpPtr->traceColor; - } + newGC = NULL; if (colorPtr != NULL) { gcValues.foreground = colorPtr->pixel; @@ -1140,7 +1155,8 @@ static void InitLinePen(Graph* graphPtr, LinePen* penPtr) penPtr->flags = NORMAL_PEN; penPtr->name = ""; penPtr->symbol.bitmap = penPtr->symbol.mask = None; - penPtr->symbol.outlineColor = penPtr->symbol.fillColor = COLOR_DEFAULT; + penPtr->symbol.outlineColor = NULL; + penPtr->symbol.fillColor = NULL; penPtr->symbol.outlineWidth = penPtr->traceWidth = 1; penPtr->symbol.type = SYMBOL_NONE; penPtr->valueShow = SHOW_NONE; @@ -3805,23 +3821,19 @@ static void DrawNormalLineProc(Graph *graphPtr, Drawable drawable, static void GetSymbolPostScriptInfo(Graph *graphPtr, Blt_Ps ps, LinePen *penPtr, int size) { - XColor *outlineColor, *fillColor, *defaultColor; - /* Set line and foreground attributes */ - outlineColor = penPtr->symbol.outlineColor; - fillColor = penPtr->symbol.fillColor; - defaultColor = penPtr->traceColor; + XColor* fillColor = penPtr->symbol.fillColor; + if (!fillColor) + fillColor = penPtr->traceColor; - if (fillColor == COLOR_DEFAULT) { - fillColor = defaultColor; - } - if (outlineColor == COLOR_DEFAULT) { - outlineColor = defaultColor; - } - if (penPtr->symbol.type == SYMBOL_NONE) { - Blt_Ps_XSetLineAttributes(ps, defaultColor, penPtr->traceWidth + 2, + XColor* outlineColor = penPtr->symbol.outlineColor; + if (!outlineColor) + outlineColor = penPtr->traceColor; + + if (penPtr->symbol.type == SYMBOL_NONE) + Blt_Ps_XSetLineAttributes(ps, penPtr->traceColor, penPtr->traceWidth + 2, &penPtr->traceDashes, CapButt, JoinMiter); - } else { + else { Blt_Ps_XSetLineWidth(ps, penPtr->symbol.outlineWidth); Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); } @@ -3849,7 +3861,7 @@ static void GetSymbolPostScriptInfo(Graph *graphPtr, Blt_Ps ps, sy = (double)size / (double)h; scale = MIN(sx, sy); - if ((penPtr->symbol.mask != None) && (fillColor != NULL)) { + if (penPtr->symbol.mask != None) { Blt_Ps_VarAppend(ps, "\n % Bitmap mask is \"", Tk_NameOfBitmap(graphPtr->display, penPtr->symbol.mask), "\"\n\n ", (char *)NULL); @@ -3862,16 +3874,15 @@ static void GetSymbolPostScriptInfo(Graph *graphPtr, Blt_Ps ps, "\"\n\n ", (char *)NULL); Blt_Ps_XSetForeground(ps, outlineColor); Blt_Ps_DrawBitmap(ps, graphPtr->display, penPtr->symbol.bitmap, - scale, scale); + scale, scale); } break; default: - if (fillColor != NULL) { Blt_Ps_Append(ps, " "); Blt_Ps_XSetBackground(ps, fillColor); Blt_Ps_Append(ps, " gsave fill grestore\n"); - } - if ((outlineColor != NULL) && (penPtr->symbol.outlineWidth > 0)) { + + if (penPtr->symbol.outlineWidth > 0) { Blt_Ps_Append(ps, " "); Blt_Ps_XSetForeground(ps, outlineColor); Blt_Ps_Append(ps, " stroke\n"); diff --git a/src/bltGrElemOp.C b/src/bltGrElemOp.C index c5aad09..f57524d 100644 --- a/src/bltGrElemOp.C +++ b/src/bltGrElemOp.C @@ -853,7 +853,7 @@ void Blt_DrawElements(Graph *graphPtr, Drawable drawable) Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); - if ((elemPtr->flags & (HIDE|DELETE_PENDING)) == 0) { + if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) { (*elemPtr->procsPtr->drawNormalProc)(graphPtr, drawable, elemPtr); } } @@ -868,7 +868,9 @@ void Blt_DrawActiveElements(Graph *graphPtr, Drawable drawable) Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); - if ((elemPtr->flags & (HIDE|ACTIVE|DELETE_PENDING)) == ACTIVE) { + if (!(elemPtr->flags & DELETE_PENDING) && + (elemPtr->flags & ACTIVE) && + !elemPtr->hide) { (*elemPtr->procsPtr->drawActiveProc)(graphPtr, drawable, elemPtr); } } @@ -883,7 +885,7 @@ void Blt_ElementsToPostScript(Graph *graphPtr, Blt_Ps ps) Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); - if (elemPtr->flags & (HIDE|DELETE_PENDING)) { + if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) { continue; } /* Comment the PostScript to indicate the start of the element */ @@ -901,7 +903,9 @@ void Blt_ActiveElementsToPostScript( Graph *graphPtr, Blt_Ps ps) Element *elemPtr; elemPtr = Blt_Chain_GetValue(link); - if ((elemPtr->flags & (DELETE_PENDING|HIDE|ACTIVE)) == ACTIVE) { + if (!(elemPtr->flags & DELETE_PENDING) && + (elemPtr->flags & ACTIVE) && + !elemPtr->hide) { Blt_Ps_Format(ps, "\n%% Active Element \"%s\"\n\n", elemPtr->obj.name); (*elemPtr->procsPtr->printActiveProc)(graphPtr, ps, elemPtr); @@ -1180,7 +1184,7 @@ static int ClosestOp(Graph *graphPtr, Tcl_Interp *interp, if (IGNORE_ELEMENT(elemPtr)) { continue; } - if (elemPtr->flags & (HIDE|MAP_ITEM)) { + if ((elemPtr->flags & MAP_ITEM) && elemPtr->hide) { continue; } (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search); @@ -1197,7 +1201,7 @@ static int ClosestOp(Graph *graphPtr, Tcl_Interp *interp, for (link = Blt_Chain_LastLink(graphPtr->elements.displayList); link != NULL; link = Blt_Chain_PrevLink(link)) { elemPtr = Blt_Chain_GetValue(link); - if (elemPtr->flags & (HIDE|MAP_ITEM|DELETE_PENDING)) { + if ((elemPtr->flags & (MAP_ITEM|DELETE_PENDING)) && elemPtr->hide) { continue; } (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr, &search); diff --git a/src/bltGrElemOp.h b/src/bltGrElemOp.h index de35d67..b7303b9 100644 --- a/src/bltGrElemOp.h +++ b/src/bltGrElemOp.h @@ -62,8 +62,8 @@ #define NUMBEROFPOINTS(e) MIN((e)->x.nValues, (e)->y.nValues) -#define NORMALPEN(e) ((((e)->normalPenPtr == NULL) ? \ - (e)->builtinPenPtr : \ +#define NORMALPEN(e) ((((e)->normalPenPtr == NULL) ? \ + (e)->builtinPenPtr : \ (e)->normalPenPtr)) /* @@ -76,20 +76,20 @@ *--------------------------------------------------------------------------- */ typedef struct { - double min, max, range; + double min, max, range; } Weight; -#define SetRange(l) \ - ((l).range = ((l).max > (l).min) ? ((l).max - (l).min) : DBL_EPSILON) -#define SetScale(l) \ - ((l).scale = 1.0 / (l).range) -#define SetWeight(l, lo, hi) \ - ((l).min = (lo), (l).max = (hi), SetRange(l)) +#define SetRange(l) \ + ((l).range = ((l).max > (l).min) ? ((l).max - (l).min) : DBL_EPSILON) +#define SetScale(l) \ + ((l).scale = 1.0 / (l).range) +#define SetWeight(l, lo, hi) \ + ((l).min = (lo), (l).max = (hi), SetRange(l)) typedef struct { - Segment2d *segments; /* Point to start of this pen's X-error bar - * segments in the element's array. */ - int nSegments; + Segment2d *segments; /* Point to start of this pen's X-error bar + * segments in the element's array. */ + int nSegments; } ErrorBarSegments; /* @@ -98,50 +98,50 @@ typedef struct { * distinguishes it among the list of all elements. */ typedef struct { - Weight weight; /* Weight range where this pen is valid. */ - Pen *penPtr; /* Pen to use. */ + Weight weight; /* Weight range where this pen is valid. */ + Pen *penPtr; /* Pen to use. */ } PenStyle; typedef struct { - XColor *color; /* Color of error bar */ - int lineWidth; /* Width of the error bar segments. */ - GC gc; - int show; /* Flags for errorbars: none, x, y, or both */ + XColor *color; /* Color of error bar */ + int lineWidth; /* Width of the error bar segments. */ + GC gc; + int show; /* Flags for errorbars: none, x, y, or both */ } ErrorBarAttributes; typedef struct { - /* Inputs */ - int halo; /* Maximal screen distance a candidate point + /* Inputs */ + int halo; /* Maximal screen distance a candidate point * can be from the sample window coordinate */ - int mode; /* Indicates whether to find the closest data + int mode; /* Indicates whether to find the closest data * point or the closest point on the trace by * interpolating the line segments. Can also * be SEARCH_AUTO, indicating to choose how to * search.*/ - int x, y; /* Screen coordinates of test point */ + int x, y; /* Screen coordinates of test point */ - int along; /* Indicates to let search run along a + int along; /* Indicates to let search run along a * particular axis: x, y, or both. */ - /* Outputs */ - Element *elemPtr; /* Name of the closest element */ + /* Outputs */ + Element *elemPtr; /* Name of the closest element */ - Point2d point; /* Graph coordinates of closest point */ + Point2d point; /* Graph coordinates of closest point */ - int index; /* Index of closest data point */ + int index; /* Index of closest data point */ - double dist; /* Distance in screen coordinates */ + double dist; /* Distance in screen coordinates */ } ClosestSearch; typedef void (ElementDrawProc) (Graph *graphPtr, Drawable drawable, - Element *elemPtr); + Element *elemPtr); typedef void (ElementToPostScriptProc) (Graph *graphPtr, Blt_Ps ps, - Element *elemPtr); + Element *elemPtr); typedef void (ElementDestroyProc) (Graph *graphPtr, Element *elemPtr); @@ -152,30 +152,30 @@ typedef void (ElementMapProc) (Graph *graphPtr, Element *elemPtr); typedef void (ElementExtentsProc) (Element *elemPtr, Region2d *extsPtr); typedef void (ElementClosestProc) (Graph *graphPtr, Element *elemPtr, - ClosestSearch *searchPtr); + ClosestSearch *searchPtr); typedef void (ElementDrawSymbolProc) (Graph *graphPtr, Drawable drawable, - Element *elemPtr, int x, int y, int symbolSize); + Element *elemPtr, int x, int y, int symbolSize); typedef void (ElementSymbolToPostScriptProc) (Graph *graphPtr, - Blt_Ps ps, Element *elemPtr, double x, double y, int symSize); + Blt_Ps ps, Element *elemPtr, double x, double y, int symSize); typedef struct { - ElementClosestProc *closestProc; - ElementConfigProc *configProc; - ElementDestroyProc *destroyProc; - ElementDrawProc *drawActiveProc; - ElementDrawProc *drawNormalProc; - ElementDrawSymbolProc *drawSymbolProc; - ElementExtentsProc *extentsProc; - ElementToPostScriptProc *printActiveProc; - ElementToPostScriptProc *printNormalProc; - ElementSymbolToPostScriptProc *printSymbolProc; - ElementMapProc *mapProc; + ElementClosestProc *closestProc; + ElementConfigProc *configProc; + ElementDestroyProc *destroyProc; + ElementDrawProc *drawActiveProc; + ElementDrawProc *drawNormalProc; + ElementDrawSymbolProc *drawSymbolProc; + ElementExtentsProc *extentsProc; + ElementToPostScriptProc *printActiveProc; + ElementToPostScriptProc *printNormalProc; + ElementSymbolToPostScriptProc *printSymbolProc; + ElementMapProc *mapProc; } ElementProcs; typedef struct { - Blt_VectorId vector; + Blt_VectorId vector; } VectorDataSource; /* @@ -184,72 +184,73 @@ typedef struct { * the number and minimum/maximum values. */ typedef struct { - int type; /* Selects the type of data populating this + int type; /* Selects the type of data populating this * vector: ELEM_SOURCE_VECTOR, * ELEM_SOURCE_TABLE, or ELEM_SOURCE_VALUES */ - Element *elemPtr; /* Element associated with vector. */ - VectorDataSource vectorSource; - double *values; - int nValues; - int arraySize; - double min, max; + Element *elemPtr; /* Element associated with vector. */ + VectorDataSource vectorSource; + double *values; + int nValues; + int arraySize; + double min, max; } ElemValues; struct _Element { - GraphObj obj; /* Must be first field in element. */ - unsigned int flags; - Tcl_HashEntry *hashPtr; - - /* Fields specific to elements. */ - const char *label; /* Label displayed in legend */ - unsigned short row, col; /* Position of the entry in the + GraphObj obj; /* Must be first field in element. */ + unsigned int flags; + int hide; + Tcl_HashEntry *hashPtr; + + /* Fields specific to elements. */ + const char *label; /* Label displayed in legend */ + unsigned short row, col; /* Position of the entry in the * legend. */ - int legendRelief; /* Relief of label in legend. */ - Axis2d axes; /* X-axis and Y-axis mapping the - * element */ - ElemValues x, y, w; /* Contains array of floating point + int legendRelief; /* Relief of label in legend. */ + Axis2d axes; /* X-axis and Y-axis mapping the + * element */ + ElemValues x, y, w; /* Contains array of floating point * graph coordinate values. Also holds * min/max and the number of * coordinates */ - int *activeIndices; /* Array of indices (malloc-ed) which + int *activeIndices; /* Array of indices (malloc-ed) which * indicate which data points are * active (drawn with "active" * colors). */ - int nActiveIndices; /* Number of active data points. + int nActiveIndices; /* Number of active data points. * Special case: if nActiveIndices < 0 * and the active bit is set in * "flags", then all data points are * drawn active. */ - ElementProcs *procsPtr; - Tk_OptionTable optionTable; /* Configuration specifications. */ - Pen *activePenPtr; /* Standard Pens */ - Pen *normalPenPtr; - Pen *builtinPenPtr; - Blt_Chain stylePalette; /* Palette of pens. */ - - /* Symbol scaling */ - int scaleSymbols; /* If non-zero, the symbols will scale + ElementProcs *procsPtr; + Tk_OptionTable optionTable; /* Configuration specifications. */ + Pen *activePenPtr; /* Standard Pens */ + Pen *normalPenPtr; + Pen *builtinPenPtr; + Blt_Chain stylePalette; /* Palette of pens. */ + + /* Symbol scaling */ + int scaleSymbols; /* If non-zero, the symbols will scale * in size as the graph is zoomed * in/out. */ - double xRange, yRange; /* Initial X-axis and Y-axis ranges: + double xRange, yRange; /* Initial X-axis and Y-axis ranges: * used to scale the size of element's * symbol. */ - int state; - Blt_ChainLink link; /* Element's link in display list. */ + int state; + Blt_ChainLink link; /* Element's link in display list. */ }; extern double Blt_FindElemValuesMinimum(ElemValues *vecPtr, double minLimit); extern void Blt_ResizeStatusArray(Element *elemPtr, int nPoints); extern int Blt_GetPenStyle(Graph *graphPtr, char *name, size_t classId, - PenStyle *stylePtr); + PenStyle *stylePtr); extern void Blt_FreeStylePalette (Blt_Chain stylePalette); extern PenStyle **Blt_StyleMap (Element *elemPtr); extern void Blt_MapErrorBars(Graph *graphPtr, Element *elemPtr, - PenStyle **dataToStyle); + PenStyle **dataToStyle); extern void Blt_FreeDataValues(ElemValues *evPtr); extern int Blt_GetElement(Tcl_Interp *interp, Graph *graphPtr, - Tcl_Obj *objPtr, Element **elemPtrPtr); + Tcl_Obj *objPtr, Element **elemPtrPtr); #endif /* _BLT_GR_ELEM_H */ |