From d5e93bc941aeab65e85d86cf9f7e26c6731d23b9 Mon Sep 17 00:00:00 2001 From: joye Date: Wed, 12 Mar 2014 20:32:16 +0000 Subject: *** empty log message *** --- bltGrMarkerBitmap.C | 64 +-- bltGrMarkerBitmap.h | 1 + src/bltConfig.C | 157 ------ src/bltConfig.h | 4 +- src/bltGrAxis.C | 34 +- src/bltGrElemBar.C | 25 +- src/bltGrElemLine.C | 19 +- src/bltGrElemOp.C | 113 +++-- src/bltGrMarker.C | 1242 +++++++++++++++++++++------------------------- src/bltGrMarker.h | 24 +- src/bltGrMarkerLine.C | 66 +-- src/bltGrMarkerLine.h | 1 + src/bltGrMarkerPolygon.C | 69 +-- src/bltGrMarkerPolygon.h | 1 + src/bltGrMarkerText.C | 70 +-- src/bltGrMarkerText.h | 2 + src/bltGrPenOp.C | 8 +- src/bltGraph.h | 13 +- src/bltVector.C | 8 +- 19 files changed, 709 insertions(+), 1212 deletions(-) diff --git a/bltGrMarkerBitmap.C b/bltGrMarkerBitmap.C index 304988c..eb7da6f 100644 --- a/bltGrMarkerBitmap.C +++ b/bltGrMarkerBitmap.C @@ -33,7 +33,7 @@ #define GETBITMAP(b) (((b)->destBitmap == None) ? (b)->srcBitmap : (b)->destBitmap) -static Tk_OptionSpec bitmapOptionSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "center", -1, Tk_Offset(BitmapMarker, anchor), 0, NULL, 0}, {TK_OPTION_COLOR, "-background", "background", "Background", @@ -60,12 +60,10 @@ static Tk_OptionSpec bitmapOptionSpecs[] = { "x", -1, Tk_Offset(BitmapMarker, axes.x), 0, &xAxisObjOption, 0}, {TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY", "y", -1, Tk_Offset(BitmapMarker, axes.y), 0, &yAxisObjOption, 0}, - {TK_OPTION_STRING, "-name", "name", "Name", - NULL, -1, Tk_Offset(BitmapMarker, obj.name), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_SYNONYM, "-outline", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0}, {TK_OPTION_DOUBLE, "-rotate", "rotate", "Rotate", "0", -1, Tk_Offset(BitmapMarker, reqAngle), 0, NULL, 0}, - {TK_OPTION_CUSTOM, "-state", "state", "State", + {TK_OPTION_STRING_TABLE, "-state", "state", "State", "normal", -1, Tk_Offset(BitmapMarker, state), 0, &stateObjOption, 0}, {TK_OPTION_BOOLEAN, "-under", "under", "Under", "no", -1, Tk_Offset(BitmapMarker, drawUnder), 0, NULL, 0}, @@ -76,52 +74,6 @@ static Tk_OptionSpec bitmapOptionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static Blt_ConfigSpec bitmapConfigSpecs[] = { - {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", - Tk_Offset(BitmapMarker, anchor), 0}, - {BLT_CONFIG_COLOR, "-background", "background", "Background", - "white", Tk_Offset(BitmapMarker, fillColor), - BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_SYNONYM, "-bg", "background", (char*)NULL, (char*)NULL, 0, 0}, - {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Bitmap all", - Tk_Offset(BitmapMarker, obj.tags), BLT_CONFIG_NULL_OK, - &listOption}, - {BLT_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", NULL, - Tk_Offset(BitmapMarker, srcBitmap), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL, - Tk_Offset(BitmapMarker, worldPts), BLT_CONFIG_NULL_OK, - &coordsOption}, - {BLT_CONFIG_STRING, "-element", "element", "Element", NULL, - Tk_Offset(BitmapMarker, elemName), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_SYNONYM, "-fg", "foreground", (char*)NULL, (char*)NULL, 0, 0}, - {BLT_CONFIG_SYNONYM, "-fill", "background", (char*)NULL, (char*)NULL, - 0, 0}, - {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - "black", Tk_Offset(BitmapMarker, outlineColor), - BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no", - Tk_Offset(BitmapMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x", - Tk_Offset(BitmapMarker, axes.x), 0, &bltXAxisOption}, - {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y", - Tk_Offset(BitmapMarker, axes.y), 0, &bltYAxisOption}, - {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL, - Tk_Offset(BitmapMarker, obj.name), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char*)NULL, (char*)NULL, - 0, 0}, - {BLT_CONFIG_DOUBLE, "-rotate", "rotate", "Rotate", "0", - Tk_Offset(BitmapMarker, reqAngle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal", - Tk_Offset(BitmapMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, - {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no", - Tk_Offset(BitmapMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0", - Tk_Offset(BitmapMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0", - Tk_Offset(BitmapMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} -}; - MarkerCreateProc Blt_CreateBitmapProc; static MarkerConfigProc ConfigureBitmapProc; static MarkerDrawProc DrawBitmapProc; @@ -132,7 +84,7 @@ static MarkerPostscriptProc BitmapToPostscriptProc; static MarkerRegionProc RegionInBitmapProc; static MarkerClass bitmapMarkerClass = { - bitmapConfigSpecs, + optionSpecs, ConfigureBitmapProc, DrawBitmapProc, FreeBitmapProc, @@ -142,13 +94,13 @@ static MarkerClass bitmapMarkerClass = { BitmapToPostscriptProc, }; -Marker* Blt_CreateBitmapProc(void) +Marker* Blt_CreateBitmapProc(Graph* graphPtr) { - BitmapMarker *bmPtr; - - bmPtr = calloc(1, sizeof(BitmapMarker)); + BitmapMarker* bmPtr = calloc(1, sizeof(BitmapMarker)); bmPtr->classPtr = &bitmapMarkerClass; - return (Marker *)bmPtr; + bmPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + + return (Marker*)bmPtr; } static int ConfigureBitmapProc(Marker *markerPtr) diff --git a/bltGrMarkerBitmap.h b/bltGrMarkerBitmap.h index 458ff3d..c3049cc 100644 --- a/bltGrMarkerBitmap.h +++ b/bltGrMarkerBitmap.h @@ -37,6 +37,7 @@ typedef struct { MarkerClass *classPtr; + Tk_OptionTable optionTable; /* Configuration specifications */ Tcl_HashEntry *hashPtr; Blt_ChainLink link; diff --git a/src/bltConfig.C b/src/bltConfig.C index 0f938c7..3576174 100644 --- a/src/bltConfig.C +++ b/src/bltConfig.C @@ -278,163 +278,6 @@ static Tcl_Obj* ListGetProc(ClientData clientData, Tk_Window tkwin, return listObjPtr; }; -/* STATE */ - -static Blt_OptionParseProc ObjToStateProc; -static Blt_OptionPrintProc StateToObjProc; -Blt_CustomOption stateOption = -{ - ObjToStateProc, StateToObjProc, NULL, (ClientData)0 -}; - -static int ObjToStateProc(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec, - int offset, int flags) -{ - const char* string; - int length; - int* statePtr; - - statePtr = (int*)(widgRec + offset); - - string = Tcl_GetStringFromObj(objPtr, &length); - if (!strncmp(string, "normal", length)) { - *statePtr = BLT_STATE_NORMAL; - } else if (!strncmp(string, "disabled", length)) { - *statePtr = BLT_STATE_DISABLED; - } else if (!strncmp(string, "active", length)) { - *statePtr = BLT_STATE_ACTIVE; - } else { - Tcl_AppendResult(interp, "bad state \"", string, - "\": should be normal, active, or disabled", (char *)NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -static Tcl_Obj* StateToObjProc(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, char *widgRec, - int offset, int flags) -{ - int* statePtr; - - statePtr = (int*)(widgRec + offset); - switch (*statePtr) { - case BLT_STATE_ACTIVE: - return Tcl_NewStringObj("active", -1); - case BLT_STATE_DISABLED: - return Tcl_NewStringObj("disabled", -1); - case BLT_STATE_NORMAL: - return Tcl_NewStringObj("normal", -1); - } - return Tcl_NewStringObj("unknown", -1); -} - -/* DASHES */ - -static Blt_OptionParseProc ObjToDashesProc; -static Blt_OptionPrintProc DashesToObjProc; -Blt_CustomOption dashesOption = -{ - ObjToDashesProc, DashesToObjProc, NULL, (ClientData)0 -}; - -static int ObjToDashesProc(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec, - int offset, int flags) -{ - const char* string; - int length; - Blt_Dashes* dashesPtr; - - dashesPtr = (Blt_Dashes*)(widgRec + offset); - - string = Tcl_GetStringFromObj(objPtr, &length); - if (string == NULL) { - dashesPtr->values[0] = 0; - return TCL_OK; - } - - if (!string[0]) { - dashesPtr->values[0] = 0; - } else if (!strncmp(string, "dot", length)) { - /* 1 */ - dashesPtr->values[0] = 1; - dashesPtr->values[1] = 0; - } else if (!strncmp(string, "dash", length)) { - /* 5 2 */ - dashesPtr->values[0] = 5; - dashesPtr->values[1] = 2; - dashesPtr->values[2] = 0; - } else if (!strncmp(string, "dashdot", length)) { - /* 2 4 2 */ - dashesPtr->values[0] = 2; - dashesPtr->values[1] = 4; - dashesPtr->values[2] = 2; - dashesPtr->values[3] = 0; - } else if (!strncmp(string, "dashdotdot", length)) { - /* 2 4 2 2 */ - dashesPtr->values[0] = 2; - dashesPtr->values[1] = 4; - dashesPtr->values[2] = 2; - dashesPtr->values[3] = 2; - dashesPtr->values[4] = 0; - } else { - int objc; - Tcl_Obj **objv; - int i; - - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - return TCL_ERROR; - } - if (objc > 11) { /* This is the postscript limit */ - Tcl_AppendResult(interp, "too many values in dash list \"", - string, "\"", (char *)NULL); - return TCL_ERROR; - } - for (i = 0; i < objc; i++) { - int value; - - if (Tcl_GetIntFromObj(interp, objv[i], &value) != TCL_OK) { - return TCL_ERROR; - } - /* - * Backward compatibility: - * Allow list of 0 to turn off dashes - */ - if ((value == 0) && (objc == 1)) { - break; - } - if ((value < 1) || (value > 255)) { - Tcl_AppendResult(interp, "dash value \"", - Tcl_GetString(objv[i]), "\" is out of range", - (char *)NULL); - return TCL_ERROR; - } - dashesPtr->values[i] = (unsigned char)value; - } - /* Make sure the array ends with a NUL byte */ - dashesPtr->values[i] = 0; - } - return TCL_OK; -} - -static Tcl_Obj* DashesToObjProc(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, char *widgRec, - int offset, int flags) -{ - Blt_Dashes* dashesPtr = (Blt_Dashes*)(widgRec + offset); - - unsigned char *p; - Tcl_Obj *listObjPtr; - - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - for(p = dashesPtr->values; *p != 0; p++) { - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewIntObj(*p)); - } - return listObjPtr; -} - /* BITMASK */ int ObjToBitmaskProc(ClientData clientData, Tcl_Interp *interp, diff --git a/src/bltConfig.h b/src/bltConfig.h index d87fccd..6488f8b 100644 --- a/src/bltConfig.h +++ b/src/bltConfig.h @@ -161,6 +161,8 @@ typedef enum { #define BLT_STATE_ACTIVE (1<<0) #define BLT_STATE_DISABLED (1<<1) +extern char* stateObjOption[]; + typedef struct { unsigned char values[12]; int offset; @@ -168,8 +170,6 @@ typedef struct { #define LineIsDashed(d) ((d).values[0] != 0) -extern char* stateObjOption[]; - extern Tk_ObjCustomOption pointObjOption; extern Tk_ObjCustomOption dashesObjOption; extern Tk_ObjCustomOption listObjOption; diff --git a/src/bltGrAxis.C b/src/bltGrAxis.C index afc6f8f..5d66948 100644 --- a/src/bltGrAxis.C +++ b/src/bltGrAxis.C @@ -537,36 +537,27 @@ static int CreateAxis(Tcl_Interp* interp, Graph* graphPtr, return TCL_ERROR; } - Axis* axisPtr; int isNew; Tcl_HashEntry* hPtr = Tcl_CreateHashEntry(&graphPtr->axes.table, string, &isNew); if (!isNew) { - axisPtr = Tcl_GetHashValue(hPtr); - if ((axisPtr->flags & DELETE_PENDING) == 0) { - Tcl_AppendResult(graphPtr->interp, "axis \"", string, - "\" already exists in \"", Tcl_GetString(objv[0]), - "\"", NULL); - return TCL_ERROR; - } - axisPtr->flags &= ~DELETE_PENDING; - } - else { - axisPtr = NewAxis(graphPtr, Tcl_GetString(objv[3]), MARGIN_NONE); - if (!axisPtr) - return TCL_ERROR; - axisPtr->hashPtr = hPtr; - Tcl_SetHashValue(hPtr, axisPtr); + Tcl_AppendResult(graphPtr->interp, "axis \"", string, + "\" already exists in \"", Tcl_GetString(objv[0]), + "\"", NULL); + return TCL_ERROR; } + Axis* axisPtr = NewAxis(graphPtr, Tcl_GetString(objv[3]), MARGIN_NONE); + if (!axisPtr) + return TCL_ERROR; + axisPtr->hashPtr = hPtr; + Tcl_SetHashValue(hPtr, axisPtr); + if ((Tk_InitOptions(graphPtr->interp, (char*)axisPtr, axisPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (AxisObjConfigure(interp, axisPtr, objc-4, objv+4) != TCL_OK)) { DestroyAxis(axisPtr); return TCL_ERROR; } - graphPtr->flags |= CACHE_DIRTY; - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; } @@ -1088,6 +1079,7 @@ static int AxisCreateOp(Tcl_Interp* interp, Graph* graphPtr, if (CreateAxis(interp, graphPtr, objc, objv) != TCL_OK) return TCL_ERROR; Tcl_SetObjResult(interp, objv[3]); + return TCL_OK; } @@ -1099,8 +1091,10 @@ static int AxisDeleteOp(Tcl_Interp* interp, Graph* graphPtr, return TCL_ERROR; axisPtr->flags |= DELETE_PENDING; - if (axisPtr->refCount == 0) + if (axisPtr->refCount == 0) { Tcl_EventuallyFree(axisPtr, FreeAxis); + Blt_EventuallyRedrawGraph(graphPtr); + } return TCL_OK; } diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C index ad80f1c..46e8f41 100644 --- a/src/bltGrElemBar.C +++ b/src/bltGrElemBar.C @@ -235,7 +235,7 @@ extern Tk_ObjCustomOption valuesObjOption; extern Tk_ObjCustomOption xAxisObjOption; extern Tk_ObjCustomOption yAxisObjOption; -static Tk_OptionSpec barElemOptionSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_CUSTOM, "-activepen", "activePen", "ActivePen", "activeBar", -1, Tk_Offset(BarElement, activePenPtr), TK_OPTION_NULL_OK, &barPenObjOption, 0}, @@ -379,27 +379,16 @@ static Tk_OptionSpec barPenOptionSpecs[] = { // Create -Element* Blt_BarElement(Graph* graphPtr, const char* name, ClassId classId) +Element* Blt_BarElement(Graph* graphPtr) { BarElement* elemPtr = calloc(1, sizeof(BarElement)); elemPtr->procsPtr = &barProcs; - elemPtr->obj.name = Blt_Strdup(name); - Blt_GraphSetObjectClass(&elemPtr->obj, classId); - elemPtr->obj.graphPtr = graphPtr; - // this is an option and will be freed via Tk_FreeConfigOptions - // By default an element's name and label are the same - elemPtr->label = ckalloc(strlen(name)+1); - if (name) - strcpy((char*)elemPtr->label,(char*)name); - elemPtr->builtinPenPtr = &elemPtr->builtinPen; InitBarPen(graphPtr, elemPtr->builtinPenPtr); Tk_InitOptions(graphPtr->interp, (char*)elemPtr->builtinPenPtr, elemPtr->builtinPenPtr->optionTable, graphPtr->tkwin); - elemPtr->stylePalette = Blt_Chain_Create(); - elemPtr->optionTable = - Tk_CreateOptionTable(graphPtr->interp, barElemOptionSpecs); + elemPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); return (Element*)elemPtr; } @@ -432,21 +421,21 @@ static void DestroyBarProc(Graph* graphPtr, Element* basePtr) BarElement* elemPtr = (BarElement*)basePtr; DestroyPenProc(graphPtr, (Pen*)&elemPtr->builtinPen); + if (elemPtr->activePenPtr) Blt_FreePen((Pen *)elemPtr->activePenPtr); if (elemPtr->normalPenPtr) Blt_FreePen((Pen *)elemPtr->normalPenPtr); ResetBar(elemPtr); + if (elemPtr->stylePalette) { Blt_FreeStylePalette(elemPtr->stylePalette); Blt_Chain_Destroy(elemPtr->stylePalette); } - if (elemPtr->activeIndices) { - free(elemPtr->activeIndices); - } - Tk_FreeConfigOptions((char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin); + if (elemPtr->activeIndices) + free(elemPtr->activeIndices); } static void DestroyPenProc(Graph* graphPtr, Pen* basePtr) diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C index 5af305b..6cae8de 100644 --- a/src/bltGrElemLine.C +++ b/src/bltGrElemLine.C @@ -490,7 +490,7 @@ extern Tk_ObjCustomOption valuesObjOption; extern Tk_ObjCustomOption xAxisObjOption; extern Tk_ObjCustomOption yAxisObjOption; -static Tk_OptionSpec lineElemOptionSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_CUSTOM, "-activepen", "activePen", "ActivePen", "activeLine", -1, Tk_Offset(LineElement, activePenPtr), TK_OPTION_NULL_OK, &linePenObjOption, 0}, @@ -658,28 +658,17 @@ static Tk_OptionSpec linePenOptionSpecs[] = { // Create -Element * Blt_LineElement(Graph* graphPtr, const char* name, ClassId classId) +Element * Blt_LineElement(Graph* graphPtr) { LineElement* elemPtr = calloc(1, sizeof(LineElement)); elemPtr->procsPtr = &lineProcs; - elemPtr->obj.name = Blt_Strdup(name); - Blt_GraphSetObjectClass(&elemPtr->obj, classId); elemPtr->flags = SCALE_SYMBOL; - elemPtr->obj.graphPtr = graphPtr; - // this is an option and will be freed via Tk_FreeConfigOptions - // By default an element's name and label are the same - elemPtr->label = Tcl_Alloc(strlen(name)+1); - if (name) - strcpy((char*)elemPtr->label,(char*)name); - elemPtr->builtinPenPtr = &elemPtr->builtinPen; InitLinePen(graphPtr, elemPtr->builtinPenPtr); Tk_InitOptions(graphPtr->interp, (char*)elemPtr->builtinPenPtr, elemPtr->builtinPenPtr->optionTable, graphPtr->tkwin); - elemPtr->stylePalette = Blt_Chain_Create(); - elemPtr->optionTable = - Tk_CreateOptionTable(graphPtr->interp, lineElemOptionSpecs); + elemPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); return (Element*)elemPtr; } @@ -734,8 +723,6 @@ static void DestroyLineProc(Graph* graphPtr, Element* basePtr) if (elemPtr->fillGC) Tk_FreeGC(graphPtr->display, elemPtr->fillGC); - - Tk_FreeConfigOptions((char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin); } static void DestroyPenProc(Graph* graphPtr, Pen* basePtr) diff --git a/src/bltGrElemOp.C b/src/bltGrElemOp.C index 7e02dd3..979e317 100644 --- a/src/bltGrElemOp.C +++ b/src/bltGrElemOp.C @@ -165,7 +165,7 @@ static int PairsSetProc(ClientData clientData, Tcl_Interp* interp, return TCL_ERROR; if (nValues & 1) { - Tcl_AppendResult(interp, "odd number of data points", (char *)NULL); + Tcl_AppendResult(interp, "odd number of data points", NULL); free(values); return TCL_ERROR; } @@ -286,30 +286,30 @@ Tcl_Obj* StyleGetProc(ClientData clientData, Tk_Window tkwin, static int CreateElement(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj *const *objv, ClassId classId) { - char *string = Tcl_GetString(objv[3]); - if (string[0] == '-') { - Tcl_AppendResult(graphPtr->interp, "name of element \"", string, + char *name = Tcl_GetString(objv[3]); + if (name[0] == '-') { + Tcl_AppendResult(graphPtr->interp, "name of element \"", name, "\" can't start with a '-'", NULL); return TCL_ERROR; } int isNew; Tcl_HashEntry* hPtr = - Tcl_CreateHashEntry(&graphPtr->elements.table, string, &isNew); + Tcl_CreateHashEntry(&graphPtr->elements.table, name, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "element \"", string, + Tcl_AppendResult(interp, "element \"", name, "\" already exists in \"", Tcl_GetString(objv[0]), - "\"", (char *)NULL); + "\"", NULL); return TCL_ERROR; } Element* elemPtr; switch (classId) { case CID_ELEM_BAR: - elemPtr = Blt_BarElement(graphPtr, string, classId); + elemPtr = Blt_BarElement(graphPtr); break; case CID_ELEM_LINE: - elemPtr = Blt_LineElement(graphPtr, string, classId); + elemPtr = Blt_LineElement(graphPtr); break; default: return TCL_ERROR; @@ -317,6 +317,16 @@ static int CreateElement(Graph* graphPtr, Tcl_Interp* interp, int objc, if (!elemPtr) return TCL_ERROR; + elemPtr->obj.graphPtr = graphPtr; + elemPtr->obj.name = Blt_Strdup(name); + // this is an option and will be freed via Tk_FreeConfigOptions + // By default an element's name and label are the same + elemPtr->label = Tcl_Alloc(strlen(name)+1); + if (name) + strcpy((char*)elemPtr->label,(char*)name); + Blt_GraphSetObjectClass(&elemPtr->obj, classId); + elemPtr->stylePalette = Blt_Chain_Create(); + elemPtr->hashPtr = hPtr; Tcl_SetHashValue(hPtr, elemPtr); @@ -326,10 +336,6 @@ static int CreateElement(Graph* graphPtr, Tcl_Interp* interp, int objc, } elemPtr->link = Blt_Chain_Append(graphPtr->elements.displayList, elemPtr); - elemPtr->flags |= MAP_ITEM; - graphPtr->flags |= CACHE_DIRTY; - graphPtr->flags |= RESET_AXES; - Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } @@ -361,10 +367,12 @@ static void DestroyElement(Element* elemPtr) if (elemPtr->obj.name) free((void*)(elemPtr->obj.name)); - // should already been freed via Tk_FreeConfigOptions + // to be freed via Tk_FreeConfigOptions // if (elemPtr->label) // free((void*)(elemPtr->label)); + Tk_FreeConfigOptions((char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin); + free(elemPtr); } @@ -414,15 +422,6 @@ static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, return ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4); } -static int CreateOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[], ClassId classId) -{ - if (CreateElement(graphPtr, interp, objc, objv, classId) != TCL_OK) - return TCL_ERROR; - Tcl_SetObjResult(interp, objv[3]); - return TCL_OK; -} - static int ElementObjConfigure(Tcl_Interp* interp, Graph* graphPtr, Element* elemPtr, int objc, Tcl_Obj* const objv[]) @@ -446,8 +445,9 @@ static int ElementObjConfigure(Tcl_Interp* interp, Graph* graphPtr, } elemPtr->flags |= mask; - graphPtr->flags |= (RESET_WORLD | CACHE_DIRTY); - if ((*elemPtr->procsPtr->configProc) (graphPtr, elemPtr) != TCL_OK) + elemPtr->flags |= MAP_ITEM; + graphPtr->flags |= RESET_WORLD | CACHE_DIRTY; + if ((*elemPtr->procsPtr->configProc)(graphPtr, elemPtr) != TCL_OK) return TCL_ERROR; Blt_EventuallyRedrawGraph(graphPtr); @@ -554,12 +554,12 @@ static int ClosestOp(Graph* graphPtr, Tcl_Interp* interp, int x; if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { - Tcl_AppendResult(interp, ": bad window x-coordinate", (char *)NULL); + Tcl_AppendResult(interp, ": bad window x-coordinate", NULL); return TCL_ERROR; } int y; if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { - Tcl_AppendResult(interp, ": bad window y-coordinate", (char *)NULL); + Tcl_AppendResult(interp, ": bad window y-coordinate", NULL); return TCL_ERROR; } @@ -619,40 +619,42 @@ static int ClosestOp(Graph* graphPtr, Tcl_Interp* interp, static int DeactivateOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { - int i; - - for (i = 3; i < objc; i++) { - Element* elemPtr; + Element* elemPtr; + if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) + return TCL_ERROR; - if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { - return TCL_ERROR; /* Can't find named element */ - } - elemPtr->flags &= ~(ACTIVE | ACTIVE_PENDING); - if (elemPtr->activeIndices) { - free(elemPtr->activeIndices); - elemPtr->activeIndices = NULL; - } - elemPtr->nActiveIndices = 0; + elemPtr->flags &= ~(ACTIVE | ACTIVE_PENDING); + if (elemPtr->activeIndices) { + free(elemPtr->activeIndices); + elemPtr->activeIndices = NULL; } + elemPtr->nActiveIndices = 0; Blt_EventuallyRedrawGraph(graphPtr); + + return TCL_OK; +} + +static int CreateOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[], ClassId classId) +{ + if (CreateElement(graphPtr, interp, objc, objv, classId) != TCL_OK) + return TCL_ERROR; + Tcl_SetObjResult(interp, objv[3]); + return TCL_OK; } static int DeleteOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { - int i; - - for (i = 3; i < objc; i++) { - Element* elemPtr; + Element* elemPtr; + if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) + return TCL_ERROR; - if (Blt_GetElement(interp, graphPtr, objv[i], &elemPtr) != TCL_OK) { - return TCL_ERROR; /* Can't find named element */ - } - elemPtr->flags |= DELETE_PENDING; - Tcl_EventuallyFree(elemPtr, FreeElement); - } + elemPtr->flags |= DELETE_PENDING; + Tcl_EventuallyFree(elemPtr, FreeElement); Blt_EventuallyRedrawGraph(graphPtr); + return TCL_OK; } @@ -755,7 +757,8 @@ static int NamesOp(Graph* graphPtr, Tcl_Interp* interp, objPtr = Tcl_NewStringObj(elemPtr->obj.name, -1); Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } - } else { + } + else { Tcl_HashEntry *hPtr; Tcl_HashSearch iter; @@ -939,7 +942,7 @@ static int GetPenStyleFromObj(Tcl_Interp* interp, Graph* graphPtr, Tcl_AppendResult(interp, "bad style entry \"", Tcl_GetString(objPtr), "\": should be \"penName\" or \"penName min max\"", - (char *)NULL); + NULL); } return TCL_ERROR; } @@ -981,7 +984,7 @@ static int FetchVectorValues(Tcl_Interp* interp, ElemValues *valuesPtr, } if (array == NULL) { if (interp) { - Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL); + Tcl_AppendResult(interp, "can't allocate new vector", NULL); } return TCL_ERROR; } @@ -1061,7 +1064,7 @@ static int ParseValues(Tcl_Interp* interp, Tcl_Obj *objPtr, int *nValuesPtr, array = malloc(sizeof(double) * objc); if (array == NULL) { - Tcl_AppendResult(interp, "can't allocate new vector", (char *)NULL); + Tcl_AppendResult(interp, "can't allocate new vector", NULL); return TCL_ERROR; } for (p = array, i = 0; i < objc; i++, p++) { @@ -1248,7 +1251,7 @@ int Blt_GetElement(Tcl_Interp* interp, Graph* graphPtr, Tcl_Obj *objPtr, if (interp) { Tcl_AppendResult(interp, "can't find element \"", name, "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", - (char *)NULL); + NULL); } return TCL_ERROR; } diff --git a/src/bltGrMarker.C b/src/bltGrMarker.C index 83cbcbd..1a97ac2 100644 --- a/src/bltGrMarker.C +++ b/src/bltGrMarker.C @@ -49,6 +49,13 @@ typedef int (GraphMarkerProc)(Graph* graphPtr, Tcl_Interp* interp, int objc, static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr, int objc, Tcl_Obj* const objv[]); static Tcl_Obj* PrintCoordinate(double x); +static int MarkerObjConfigure( Tcl_Interp* interp, Graph* graphPtr, + Marker* markerPtr, + int objc, Tcl_Obj* const objv[]); +static void DestroyMarker(Marker *markerPtr); +static int GetMarkerFromObj(Tcl_Interp* interp, Graph* graphPtr, + Tcl_Obj* objPtr, Marker** markerPtrPtr); +static int IsElementHidden(Marker *markerPtr); // OptionSpecs @@ -124,614 +131,275 @@ static Tcl_Obj* CapStyleGetProc(ClientData clientData, Tk_Window tkwin, return Tcl_NewStringObj(Tk_NameOfCapStyle(*ptr), -1); } -static Blt_OptionParseProc ObjToCoordsProc; -static Blt_OptionPrintProc CoordsToObjProc; -static Blt_OptionFreeProc FreeCoordsProc; -Blt_CustomOption coordsOption = +static Tk_CustomOptionSetProc JoinStyleSetProc; +static Tk_CustomOptionGetProc JoinStyleGetProc; +Tk_ObjCustomOption joinStyleObjOption = { - ObjToCoordsProc, CoordsToObjProc, FreeCoordsProc, NULL + "joinStyle", JoinStyleSetProc, JoinStyleGetProc, NULL, NULL, NULL }; -static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr) +static int JoinStyleSetProc(ClientData clientData, Tcl_Interp* interp, + Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec, + int offset, char* save, int flags) { - char c; - const char* expr; - - expr = Tcl_GetString(objPtr); - c = expr[0]; - if ((c == 'I') && (strcmp(expr, "Inf") == 0)) { - *valuePtr = DBL_MAX; /* Elastic upper bound */ - } else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0)) { - *valuePtr = -DBL_MAX; /* Elastic lower bound */ - } else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0)) { - *valuePtr = DBL_MAX; /* Elastic upper bound */ - } else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK) { + int* ptr = (int*)(widgRec + offset); + + Tk_Uid uid = Tk_GetUid(Tcl_GetString(*objPtr)); + int join; + if (Tk_GetJoinStyle(interp, uid, &join) != TCL_OK) return TCL_ERROR; - } + *ptr = join; + return TCL_OK; } -static Tcl_Obj* PrintCoordinate(double x) +static Tcl_Obj* JoinStyleGetProc(ClientData clientData, Tk_Window tkwin, + char *widgRec, int offset) { - if (x == DBL_MAX) - return Tcl_NewStringObj("+Inf", -1); - else if (x == -DBL_MAX) - return Tcl_NewStringObj("-Inf", -1); - else - return Tcl_NewDoubleObj(x); + int* ptr = (int*)(widgRec + offset); + return Tcl_NewStringObj(Tk_NameOfJoinStyle(*ptr), -1); } -static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr, - int objc, Tcl_Obj* const objv[]) -{ - int nWorldPts; - int minArgs, maxArgs; - Point2d *worldPts; - int i; +// Create - if (objc == 0) { - return TCL_OK; - } - if (objc & 1) { - Tcl_AppendResult(interp, "odd number of marker coordinates specified", - (char*)NULL); - return TCL_ERROR; +static int CreateMarker(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + char* name = Tcl_GetString(objv[4]); + int offset = 5; + char ident[128]; + // name given? + if (name[0] == '-') { + sprintf_s(ident, 128, "marker%d", graphPtr->nextMarkerId++); + name = ident; + offset = 4; } - switch (markerPtr->obj.classId) { - case CID_MARKER_LINE: - minArgs = 4, maxArgs = 0; - break; - case CID_MARKER_POLYGON: - minArgs = 6, maxArgs = 0; - break; - case CID_MARKER_WINDOW: - case CID_MARKER_TEXT: - minArgs = 2, maxArgs = 2; - break; - case CID_MARKER_IMAGE: - case CID_MARKER_BITMAP: - minArgs = 2, maxArgs = 4; - break; - default: - Tcl_AppendResult(interp, "unknown marker type", (char*)NULL); + + int isNew; + Tcl_HashEntry* hPtr = + Tcl_CreateHashEntry(&graphPtr->markers.table, name, &isNew); + if (!isNew) { + Tcl_AppendResult(graphPtr->interp, "marker \"", name, + "\" already exists in \"", Tcl_GetString(objv[0]), + "\"", NULL); return TCL_ERROR; } - if (objc < minArgs) { - Tcl_AppendResult(interp, "too few marker coordinates specified", - (char*)NULL); - return TCL_ERROR; + const char* type = Tcl_GetString(objv[3]); + Marker *markerPtr; + if (!strcmp(type, "text")) { + markerPtr = Blt_CreateTextProc(graphPtr); + Blt_GraphSetObjectClass(&markerPtr->obj, CID_MARKER_TEXT); } - if ((maxArgs > 0) && (objc > maxArgs)) { - Tcl_AppendResult(interp, "too many marker coordinates specified", - (char*)NULL); - return TCL_ERROR; + else if (!strcmp(type, "line")) { + markerPtr = Blt_CreateLineProc(graphPtr); + Blt_GraphSetObjectClass(&markerPtr->obj, CID_MARKER_LINE); } - nWorldPts = objc / 2; - worldPts = malloc(nWorldPts * sizeof(Point2d)); - if (worldPts == NULL) { - Tcl_AppendResult(interp, "can't allocate new coordinate array", - (char*)NULL); + else if (!strcmp(type, "polygon")) { + markerPtr = Blt_CreatePolygonProc(graphPtr); + Blt_GraphSetObjectClass(&markerPtr->obj, CID_MARKER_POLYGON); + } + else if (!strcmp(type, "bitmap")) { + markerPtr = Blt_CreateBitmapProc(graphPtr); + Blt_GraphSetObjectClass(&markerPtr->obj, CID_MARKER_BITMAP); + } + else if (!strcmp(type, "window")) { + markerPtr = Blt_CreateWindowProc(graphPtr); + Blt_GraphSetObjectClass(&markerPtr->obj, CID_MARKER_WINDOW); + } + else { + Tcl_AppendResult(interp, "unknown marker type ", type, NULL); return TCL_ERROR; } - { - Point2d *pp; + markerPtr->obj.name = Blt_Strdup(name); + markerPtr->obj.graphPtr = graphPtr; + markerPtr->drawUnder = FALSE; - pp = worldPts; - for (i = 0; i < objc; i += 2) { - double x, y; - - if ((GetCoordinate(interp, objv[i], &x) != TCL_OK) || - (GetCoordinate(interp, objv[i + 1], &y) != TCL_OK)) { - free(worldPts); - return TCL_ERROR; - } - pp->x = x, pp->y = y, pp++; - } - } - /* Don't free the old coordinate array until we've parsed the new - * coordinates without errors. */ - if (markerPtr->worldPts != NULL) { - free(markerPtr->worldPts); + markerPtr->hashPtr = hPtr; + Tcl_SetHashValue(hPtr, markerPtr); + + if ((Tk_InitOptions(graphPtr->interp, (char*)markerPtr, markerPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (MarkerObjConfigure(interp, graphPtr, markerPtr, objc-offset, objv+offset) != TCL_OK)) { + DestroyMarker(markerPtr); + return TCL_ERROR; } - markerPtr->worldPts = worldPts; - markerPtr->nWorldPts = nWorldPts; - markerPtr->flags |= MAP_ITEM; + + // Unlike elements, new markers are drawn on top of old markers + markerPtr->link = + Blt_Chain_Prepend(graphPtr->markers.displayList,markerPtr); + + Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); return TCL_OK; } -static void FreeCoordsProc(ClientData clientData, Display *display, - char* widgRec, int offset) +static void DestroyMarker(Marker *markerPtr) { - Marker *markerPtr = (Marker *)widgRec; - Point2d **pointsPtr = (Point2d **)(widgRec + offset); + Graph* graphPtr = markerPtr->obj.graphPtr; - if (*pointsPtr != NULL) { - free(*pointsPtr); - *pointsPtr = NULL; - } - markerPtr->nWorldPts = 0; + // If the marker to be deleted is currently displayed below the + // elements, then backing store needs to be repaired. + if (markerPtr->drawUnder) + graphPtr->flags |= CACHE_DIRTY; + + // Call the marker's type-specific deallocation routine. We do it first + // while all the marker fields are still valid. + (*markerPtr->classPtr->freeProc)(markerPtr); + + Blt_DeleteBindings(graphPtr->bindTable, markerPtr); + + if (markerPtr->hashPtr) + Tcl_DeleteHashEntry(markerPtr->hashPtr); + + if (markerPtr->link) + Blt_Chain_DeleteLink(graphPtr->markers.displayList, markerPtr->link); + + // will be freed via Tk_FreeConfigOptions + // if (markerPtr->obj.name) + // free((void*)(markerPtr->obj.name)); + + Tk_FreeConfigOptions((char*)markerPtr, markerPtr->optionTable, + graphPtr->tkwin); + + free(markerPtr); } -static int ObjToCoordsProc(ClientData clientData, Tcl_Interp* interp, - Tk_Window tkwin, Tcl_Obj *objPtr, - char* widgRec, int offset, int flags) -{ - Marker *markerPtr = (Marker *)widgRec; - int objc; - Tcl_Obj **objv; +// Configure - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { +static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "cget option"); return TCL_ERROR; } - if (objc == 0) { - return TCL_OK; - } - return ParseCoordinates(interp, markerPtr, objc, objv); + + Marker *markerPtr; + if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) + return TCL_ERROR; + + Tcl_Obj* objPtr = Tk_GetOptionValue(interp, (char*)markerPtr, + markerPtr->optionTable, + objv[4], graphPtr->tkwin); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; } -static Tcl_Obj* CoordsToObjProc(ClientData clientData, Tcl_Interp* interp, - Tk_Window tkwin, char* widgRec, - int offset, int flags) +static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { - Marker *markerPtr = (Marker *)widgRec; - Tcl_Obj *listObjPtr; - Point2d *pp, *pend; + Marker* markerPtr; + if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) + return TCL_ERROR; - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; pp < pend; - pp++) { - Tcl_ListObjAppendElement(interp, listObjPtr, PrintCoordinate(pp->x)); - Tcl_ListObjAppendElement(interp, listObjPtr, PrintCoordinate(pp->y)); - } - return listObjPtr; + if (objc <= 5) { + Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)markerPtr, + markerPtr->optionTable, + (objc == 5) ? objv[4] : NULL, + graphPtr->tkwin); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + else + return MarkerObjConfigure(interp, graphPtr, markerPtr, objc-4, objv+4); } -static int IsElementHidden(Marker *markerPtr) +static int MarkerObjConfigure( Tcl_Interp* interp, Graph* graphPtr, + Marker* markerPtr, + int objc, Tcl_Obj* const objv[]) { - Tcl_HashEntry *hPtr; - Graph* graphPtr = markerPtr->obj.graphPtr; + Tk_SavedOptions savedOptions; + int mask =0; + int error; + Tcl_Obj* errorResult; - /* Look up the named element and see if it's hidden */ - hPtr = Tcl_FindHashEntry(&graphPtr->elements.table, markerPtr->elemName); - if (hPtr != NULL) { - Element* elemPtr; - - elemPtr = Tcl_GetHashValue(hPtr); - if ((elemPtr->link == NULL) || (elemPtr->flags & HIDE)) { - return TRUE; + for (error=0; error<=1; error++) { + if (!error) { + if (Tk_SetOptions(interp, (char*)markerPtr, markerPtr->optionTable, + objc, objv, graphPtr->tkwin, &savedOptions, &mask) + != TCL_OK) + continue; + } + else { + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); } + + markerPtr->flags |= mask; + markerPtr->flags |= MAP_ITEM; + graphPtr->flags |= CACHE_DIRTY; + if ((*markerPtr->classPtr->configProc)(markerPtr) != TCL_OK) + return TCL_ERROR; + Blt_EventuallyRedrawGraph(graphPtr); + + break; } - return FALSE; -} -static double HMap(Axis *axisPtr, double x) -{ - if (x == DBL_MAX) { - x = 1.0; - } else if (x == -DBL_MAX) { - x = 0.0; - } else { - if (axisPtr->logScale) { - if (x > 0.0) { - x = log10(x); - } else if (x < 0.0) { - x = 0.0; - } - } - x = NORMALIZE(axisPtr, x); + if (!error) { + Tk_FreeSavedOptions(&savedOptions); + return TCL_OK; } - if (axisPtr->descending) { - x = 1.0 - x; + else { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); + return TCL_ERROR; } - /* Horizontal transformation */ - return (x * axisPtr->screenRange + axisPtr->screenMin); } -static double VMap(Axis *axisPtr, double y) +// Ops + +static int BindOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { - if (y == DBL_MAX) { - y = 1.0; - } else if (y == -DBL_MAX) { - y = 0.0; - } else { - if (axisPtr->logScale) { - if (y > 0.0) { - y = log10(y); - } else if (y < 0.0) { - y = 0.0; - } + if (objc == 3) { + Tcl_HashEntry *hp; + Tcl_HashSearch iter; + Tcl_Obj *listObjPtr; + + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + for (hp = Tcl_FirstHashEntry(&graphPtr->markers.tagTable, &iter); + hp; hp = Tcl_NextHashEntry(&iter)) { + const char* tag; + Tcl_Obj *objPtr; + + tag = Tcl_GetHashKey(&graphPtr->markers.tagTable, hp); + objPtr = Tcl_NewStringObj(tag, -1); + Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); } - y = NORMALIZE(axisPtr, y); - } - if (axisPtr->descending) { - y = 1.0 - y; + Tcl_SetObjResult(interp, listObjPtr); + return TCL_OK; } - /* Vertical transformation. */ - return (((1.0 - y) * axisPtr->screenRange) + axisPtr->screenMin); + return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, Blt_MakeMarkerTag(graphPtr, Tcl_GetString(objv[3])), objc - 4, objv + 4); } -Point2d Blt_MapPoint(Point2d *pointPtr, Axis2d *axesPtr) +static int CreateOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { - Point2d result; - Graph* graphPtr = axesPtr->y->obj.graphPtr; + if (CreateMarker(graphPtr, interp, objc, objv) != TCL_OK) + return TCL_ERROR; + // set in CreateMarker + // Tcl_SetObjResult(interp, objv[3]); - if (graphPtr->inverted) { - result.x = HMap(axesPtr->y, pointPtr->y); - result.y = VMap(axesPtr->x, pointPtr->x); - } else { - result.x = HMap(axesPtr->x, pointPtr->x); - result.y = VMap(axesPtr->y, pointPtr->y); - } - return result; + return TCL_OK; } -static Marker* CreateMarker(Graph* graphPtr, const char* name, ClassId classId) -{ +static int DeleteOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ Marker *markerPtr; - switch (classId) { - case CID_MARKER_BITMAP: - markerPtr = Blt_CreateBitmapProc(); /* bitmap */ - break; - case CID_MARKER_LINE: - markerPtr = Blt_CreateLineProc(); /* line */ - break; - case CID_MARKER_IMAGE: - return NULL; /* not supported */ - break; - case CID_MARKER_TEXT: - markerPtr = Blt_CreateTextProc(); /* text */ - break; - case CID_MARKER_POLYGON: - markerPtr = Blt_CreatePolygonProc(); /* polygon */ - break; - case CID_MARKER_WINDOW: - markerPtr = Blt_CreateWindowProc(); /* window */ - break; - default: - return NULL; - } - markerPtr->obj.graphPtr = graphPtr; - markerPtr->drawUnder = FALSE; - markerPtr->flags |= MAP_ITEM; - markerPtr->obj.name = Blt_Strdup(name); - Blt_GraphSetObjectClass(&markerPtr->obj, classId); - return markerPtr; -} + if (GetMarkerFromObj(NULL, graphPtr, objv[3], &markerPtr) != TCL_OK) + return TCL_ERROR; -static void DestroyMarker(Marker *markerPtr) -{ - Graph* graphPtr = markerPtr->obj.graphPtr; - - if (markerPtr->drawUnder) { - /* If the marker to be deleted is currently displayed below the - * elements, then backing store needs to be repaired. */ - graphPtr->flags |= CACHE_DIRTY; - } - /* - * Call the marker's type-specific deallocation routine. We do it first - * while all the marker fields are still valid. - */ - (*markerPtr->classPtr->freeProc)(markerPtr); - - /* Dump any bindings that might be registered for the marker. */ - Blt_DeleteBindings(graphPtr->bindTable, markerPtr); - - /* Release all the X resources associated with the marker. */ - Blt_FreeOptions(markerPtr->classPtr->configSpecs, (char*)markerPtr, - graphPtr->display, 0); - - if (markerPtr->hashPtr != NULL) { - Tcl_DeleteHashEntry(markerPtr->hashPtr); - } - if (markerPtr->link != NULL) { - Blt_Chain_DeleteLink(graphPtr->markers.displayList, markerPtr->link); - } - if (markerPtr->obj.name != NULL) { - free((void*)(markerPtr->obj.name)); - } - free(markerPtr); -} - -static int GetMarkerFromObj(Tcl_Interp* interp, Graph* graphPtr, - Tcl_Obj *objPtr, Marker **markerPtrPtr) -{ - Tcl_HashEntry *hPtr; - const char* string; - - string = Tcl_GetString(objPtr); - hPtr = Tcl_FindHashEntry(&graphPtr->markers.table, string); - if (hPtr != NULL) { - *markerPtrPtr = Tcl_GetHashValue(hPtr); - return TCL_OK; - } - if (interp != NULL) { - Tcl_AppendResult(interp, "can't find marker \"", string, - "\" in \"", Tk_PathName(graphPtr->tkwin), (char*)NULL); - } - return TCL_ERROR; -} - -static int RenameMarker(Graph* graphPtr, Marker *markerPtr, - const char* oldName, const char* newName) -{ - int isNew; - Tcl_HashEntry *hPtr; - - /* Rename the marker only if no marker already exists by that name */ - hPtr = Tcl_CreateHashEntry(&graphPtr->markers.table, newName, &isNew); - if (!isNew) { - Tcl_AppendResult(graphPtr->interp, "can't rename marker: \"", newName, - "\" already exists", (char*)NULL); - return TCL_ERROR; - } - markerPtr->obj.name = Blt_Strdup(newName); - markerPtr->hashPtr = hPtr; - Tcl_SetHashValue(hPtr, (char*)markerPtr); - - /* Delete the old hash entry */ - hPtr = Tcl_FindHashEntry(&graphPtr->markers.table, oldName); - Tcl_DeleteHashEntry(hPtr); - if (oldName != NULL) { - free((void*)oldName); - } - return TCL_OK; -} - -static int NamesOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Tcl_Obj *listObjPtr; - - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - if (objc == 3) { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { - Marker *markerPtr; - - markerPtr = Blt_Chain_GetValue(link); - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj(markerPtr->obj.name, -1)); - } - } else { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { - Marker *markerPtr; - int i; - - markerPtr = Blt_Chain_GetValue(link); - for (i = 3; i < objc; i++) { - const char* pattern; - - pattern = Tcl_GetString(objv[i]); - if (Tcl_StringMatch(markerPtr->obj.name, pattern)) { - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj(markerPtr->obj.name, -1)); - break; - } - } - } - } - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; -} - -static int BindOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - if (objc == 3) { - Tcl_HashEntry *hp; - Tcl_HashSearch iter; - Tcl_Obj *listObjPtr; - - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - for (hp = Tcl_FirstHashEntry(&graphPtr->markers.tagTable, &iter); - hp != NULL; hp = Tcl_NextHashEntry(&iter)) { - const char* tag; - Tcl_Obj *objPtr; - - tag = Tcl_GetHashKey(&graphPtr->markers.tagTable, hp); - objPtr = Tcl_NewStringObj(tag, -1); - Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); - } - Tcl_SetObjResult(interp, listObjPtr); - return TCL_OK; - } - return Blt_ConfigureBindingsFromObj(interp, graphPtr->bindTable, - Blt_MakeMarkerTag(graphPtr, Tcl_GetString(objv[3])), - objc - 4, objv + 4); -} - -static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Marker *markerPtr; - - if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { - return TCL_ERROR; - } - if (Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, - markerPtr->classPtr->configSpecs, (char*)markerPtr, objv[4], 0) - != TCL_OK) { - return TCL_ERROR; - } - return TCL_OK; -} - -static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Marker *markerPtr; - Tcl_Obj *const *options; - const char* oldName; - const char* string; - int flags = BLT_CONFIG_OBJV_ONLY; - int nNames, nOpts; - int i; - int under; - - markerPtr = NULL; /* Suppress compiler warning. */ - - /* Figure out where the option value pairs begin */ - objc -= 3; - objv += 3; - for (i = 0; i < objc; i++) { - string = Tcl_GetString(objv[i]); - if (string[0] == '-') { - break; - } - if (GetMarkerFromObj(interp, graphPtr, objv[i], &markerPtr) != TCL_OK) { - return TCL_ERROR; - } - } - nNames = i; /* # of element names specified */ - nOpts = objc - i; /* # of options specified */ - options = objv + nNames; /* Start of options in objv */ - - for (i = 0; i < nNames; i++) { - GetMarkerFromObj(interp, graphPtr, objv[i], &markerPtr); - if (nOpts == 0) { - return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, - markerPtr->classPtr->configSpecs, (char*)markerPtr, - (Tcl_Obj *)NULL, flags); - } else if (nOpts == 1) { - return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, - markerPtr->classPtr->configSpecs, (char*)markerPtr, - options[0], flags); - } - /* Save the old marker name. */ - oldName = markerPtr->obj.name; - under = markerPtr->drawUnder; - if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, - markerPtr->classPtr->configSpecs, nOpts, options, - (char*)markerPtr, flags) != TCL_OK) { - return TCL_ERROR; - } - if (oldName != markerPtr->obj.name) { - if (RenameMarker(graphPtr, markerPtr, oldName, markerPtr->obj.name) - != TCL_OK) { - markerPtr->obj.name = oldName; - return TCL_ERROR; - } - } - if ((*markerPtr->classPtr->configProc) (markerPtr) != TCL_OK) { - - return TCL_ERROR; - } - if (markerPtr->drawUnder != under) { - graphPtr->flags |= CACHE_DIRTY; - } - } - return TCL_OK; -} - -static int CreateOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Marker *markerPtr; - Tcl_HashEntry *hPtr; - int isNew; - ClassId classId; - int i; - const char* name; - char ident[200]; - const char* string; - char c; - - string = Tcl_GetString(objv[3]); - c = string[0]; - /* Create the new marker based upon the given type */ - if ((c == 't') && (strcmp(string, "text") == 0)) { - classId = CID_MARKER_TEXT; - } else if ((c == 'l') && (strcmp(string, "line") == 0)) { - classId = CID_MARKER_LINE; - } else if ((c == 'p') && (strcmp(string, "polygon") == 0)) { - classId = CID_MARKER_POLYGON; - } else if ((c == 'i') && (strcmp(string, "image") == 0)) { - classId = CID_MARKER_IMAGE; - } else if ((c == 'b') && (strcmp(string, "bitmap") == 0)) { - classId = CID_MARKER_BITMAP; - } else if ((c == 'w') && (strcmp(string, "window") == 0)) { - classId = CID_MARKER_WINDOW; - } else { - Tcl_AppendResult(interp, "unknown marker type \"", string, - "\": should be \"text\", \"line\", \"polygon\", \"bitmap\", \"image\", or \ -\"window\"", (char*)NULL); - return TCL_ERROR; - } - /* Scan for "-name" option. We need it for the component name */ - name = NULL; - for (i = 4; i < objc; i += 2) { - int length; - - string = Tcl_GetStringFromObj(objv[i], &length); - if ((length > 1) && (strncmp(string, "-name", length) == 0)) { - name = Tcl_GetString(objv[i + 1]); - break; - } - } - /* If no name was given for the marker, make up one. */ - if (name == NULL) { - sprintf_s(ident, 200, "marker%d", graphPtr->nextMarkerId++); - name = ident; - } else if (name[0] == '-') { - Tcl_AppendResult(interp, "name of marker \"", name, - "\" can't start with a '-'", (char*)NULL); - return TCL_ERROR; - } - markerPtr = CreateMarker(graphPtr, name, classId); - if (Blt_ConfigureComponentFromObj(interp, graphPtr->tkwin, name, - markerPtr->obj.className, markerPtr->classPtr->configSpecs, - objc - 4, objv + 4, (char*)markerPtr, 0) != TCL_OK) { - DestroyMarker(markerPtr); - return TCL_ERROR; - } - if ((*markerPtr->classPtr->configProc) (markerPtr) != TCL_OK) { - DestroyMarker(markerPtr); - return TCL_ERROR; - } - hPtr = Tcl_CreateHashEntry(&graphPtr->markers.table, name, &isNew); - if (!isNew) { - Marker *oldPtr; - /* - * Marker by the same name already exists. Delete the old marker and - * it's list entry. But save the hash entry. - */ - oldPtr = Tcl_GetHashValue(hPtr); - oldPtr->hashPtr = NULL; - DestroyMarker(oldPtr); - } - Tcl_SetHashValue(hPtr, markerPtr); - markerPtr->hashPtr = hPtr; - /* Unlike elements, new markers are drawn on top of old markers. */ - markerPtr->link = Blt_Chain_Prepend(graphPtr->markers.displayList,markerPtr); - if (markerPtr->drawUnder) { - graphPtr->flags |= CACHE_DIRTY; - } + markerPtr->flags |= DELETE_PENDING; + Tcl_EventuallyFree(markerPtr, Blt_FreeMarker); Blt_EventuallyRedrawGraph(graphPtr); - Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); - return TCL_OK; -} -static int DeleteOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - int i; - - for (i = 3; i < objc; i++) { - Marker *markerPtr; - - if (GetMarkerFromObj(NULL, graphPtr, objv[i], &markerPtr) == TCL_OK) { - markerPtr->flags |= DELETE_PENDING; - Tcl_EventuallyFree(markerPtr, Blt_FreeMarker); - } - } - Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } @@ -757,41 +425,12 @@ static int GetOp(Graph* graphPtr, Tcl_Interp* interp, return TCL_OK; } -static int RelinkOp(Graph* graphPtr, Tcl_Interp* interp, +static int ExistsOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { - Blt_ChainLink link, place; - Marker *markerPtr; - const char* string; - - /* Find the marker to be raised or lowered. */ - if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { - return TCL_ERROR; - } - /* Right now it's assumed that all markers are always in the display - list. */ - link = markerPtr->link; - Blt_Chain_UnlinkLink(graphPtr->markers.displayList, markerPtr->link); - - place = NULL; - if (objc == 5) { - if (GetMarkerFromObj(interp, graphPtr, objv[4], &markerPtr) != TCL_OK) { - return TCL_ERROR; - } - place = markerPtr->link; - } - - /* Link the marker at its new position. */ - string = Tcl_GetString(objv[2]); - if (string[0] == 'l') { - Blt_Chain_LinkAfter(graphPtr->markers.displayList, link, place); - } else { - Blt_Chain_LinkBefore(graphPtr->markers.displayList, link, place); - } - if (markerPtr->drawUnder) { - graphPtr->flags |= CACHE_DIRTY; - } - Blt_EventuallyRedrawGraph(graphPtr); + Tcl_HashEntry* hPtr = + Tcl_FindHashEntry(&graphPtr->markers.table, Tcl_GetString(objv[3])); + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr)); return TCL_OK; } @@ -840,16 +479,16 @@ static int FindOp(Graph* graphPtr, Tcl_Interp* interp, } enclosed = (mode == FIND_ENCLOSED); for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { + link; link = Blt_Chain_NextLink(link)) { Marker *markerPtr; markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->flags & DELETE_PENDING) || markerPtr->hide) { continue; } - if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { + if (IsElementHidden(markerPtr)) continue; - } + if ((*markerPtr->classPtr->regionProc)(markerPtr, &extents, enclosed)) { Tcl_Obj *objPtr; @@ -862,13 +501,83 @@ static int FindOp(Graph* graphPtr, Tcl_Interp* interp, return TCL_OK; } -static int ExistsOp(Graph* graphPtr, Tcl_Interp* interp, +static int NamesOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + Tcl_Obj *listObjPtr; + + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + if (objc == 3) { + Blt_ChainLink link; + + for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); + link; link = Blt_Chain_NextLink(link)) { + Marker *markerPtr; + + markerPtr = Blt_Chain_GetValue(link); + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj(markerPtr->obj.name, -1)); + } + } else { + Blt_ChainLink link; + + for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); + link; link = Blt_Chain_NextLink(link)) { + Marker *markerPtr; + int i; + + markerPtr = Blt_Chain_GetValue(link); + for (i = 3; i < objc; i++) { + const char* pattern; + + pattern = Tcl_GetString(objv[i]); + if (Tcl_StringMatch(markerPtr->obj.name, pattern)) { + Tcl_ListObjAppendElement(interp, listObjPtr, + Tcl_NewStringObj(markerPtr->obj.name, -1)); + break; + } + } + } + } + Tcl_SetObjResult(interp, listObjPtr); + return TCL_OK; +} + +static int RelinkOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { - Tcl_HashEntry *hPtr; + Blt_ChainLink link, place; + Marker *markerPtr; + const char* string; + + /* Find the marker to be raised or lowered. */ + if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { + return TCL_ERROR; + } + /* Right now it's assumed that all markers are always in the display + list. */ + link = markerPtr->link; + Blt_Chain_UnlinkLink(graphPtr->markers.displayList, markerPtr->link); + + place = NULL; + if (objc == 5) { + if (GetMarkerFromObj(interp, graphPtr, objv[4], &markerPtr) != TCL_OK) { + return TCL_ERROR; + } + place = markerPtr->link; + } - hPtr = Tcl_FindHashEntry(&graphPtr->markers.table, Tcl_GetString(objv[3])); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr != NULL)); + /* Link the marker at its new position. */ + string = Tcl_GetString(objv[2]); + if (string[0] == 'l') { + Blt_Chain_LinkAfter(graphPtr->markers.displayList, link, place); + } else { + Blt_Chain_LinkBefore(graphPtr->markers.displayList, link, place); + } + if (markerPtr->drawUnder) { + graphPtr->flags |= CACHE_DIRTY; + } + Blt_EventuallyRedrawGraph(graphPtr); return TCL_OK; } @@ -876,22 +585,29 @@ static int TypeOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { Marker *markerPtr; - const char* type; - - if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) { + if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) return TCL_ERROR; - } + switch (markerPtr->obj.classId) { - case CID_MARKER_BITMAP: type = "bitmap"; break; - case CID_MARKER_IMAGE: type = "image"; break; - case CID_MARKER_LINE: type = "line"; break; - case CID_MARKER_POLYGON: type = "polygon"; break; - case CID_MARKER_TEXT: type = "text"; break; - case CID_MARKER_WINDOW: type = "window"; break; - default: type = "???"; break; + case CID_MARKER_BITMAP: + Tcl_SetStringObj(Tcl_GetObjResult(interp), "bitmap", -1); + return TCL_OK; + case CID_MARKER_LINE: + Tcl_SetStringObj(Tcl_GetObjResult(interp), "line", -1); + return TCL_OK; + case CID_MARKER_POLYGON: + Tcl_SetStringObj(Tcl_GetObjResult(interp), "polygon", -1); + return TCL_OK; + case CID_MARKER_TEXT: + Tcl_SetStringObj(Tcl_GetObjResult(interp), "text", -1); + return TCL_OK; + case CID_MARKER_WINDOW: + Tcl_SetStringObj(Tcl_GetObjResult(interp), "window", -1); + return TCL_OK; + default: + Tcl_SetStringObj(Tcl_GetObjResult(interp), "unknown", -1); + return TCL_OK; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), type, -1); - return TCL_OK; } static Blt_OpSpec markerOps[] = @@ -914,40 +630,237 @@ static int nMarkerOps = sizeof(markerOps) / sizeof(Blt_OpSpec); int Blt_MarkerOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { - GraphMarkerProc *proc; - int result; + GraphMarkerProc* proc = + Blt_GetOpFromObj(interp, nMarkerOps, markerOps, BLT_OP_ARG2, objc, objv,0); + if (proc == NULL) + return TCL_ERROR; + + return (*proc) (graphPtr, interp, objc, objv); +} + +// Support + +static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr) +{ + char c; + const char* expr; + + expr = Tcl_GetString(objPtr); + c = expr[0]; + if ((c == 'I') && (strcmp(expr, "Inf") == 0)) { + *valuePtr = DBL_MAX; /* Elastic upper bound */ + } else if ((c == '-') && (expr[1] == 'I') && (strcmp(expr, "-Inf") == 0)) { + *valuePtr = -DBL_MAX; /* Elastic lower bound */ + } else if ((c == '+') && (expr[1] == 'I') && (strcmp(expr, "+Inf") == 0)) { + *valuePtr = DBL_MAX; /* Elastic upper bound */ + } else if (Blt_ExprDoubleFromObj(interp, objPtr, valuePtr) != TCL_OK) { + return TCL_ERROR; + } + return TCL_OK; +} + +static Tcl_Obj* PrintCoordinate(double x) +{ + if (x == DBL_MAX) + return Tcl_NewStringObj("+Inf", -1); + else if (x == -DBL_MAX) + return Tcl_NewStringObj("-Inf", -1); + else + return Tcl_NewDoubleObj(x); +} + +static int ParseCoordinates(Tcl_Interp* interp, Marker *markerPtr, + int objc, Tcl_Obj* const objv[]) +{ + int nWorldPts; + int minArgs, maxArgs; + Point2d *worldPts; + int i; + + if (objc == 0) { + return TCL_OK; + } + if (objc & 1) { + Tcl_AppendResult(interp, "odd number of marker coordinates specified", + (char*)NULL); + return TCL_ERROR; + } + switch (markerPtr->obj.classId) { + case CID_MARKER_LINE: + minArgs = 4, maxArgs = 0; + break; + case CID_MARKER_POLYGON: + minArgs = 6, maxArgs = 0; + break; + case CID_MARKER_WINDOW: + case CID_MARKER_TEXT: + minArgs = 2, maxArgs = 2; + break; + case CID_MARKER_IMAGE: + case CID_MARKER_BITMAP: + minArgs = 2, maxArgs = 4; + break; + default: + Tcl_AppendResult(interp, "unknown marker type", (char*)NULL); + return TCL_ERROR; + } - proc = Blt_GetOpFromObj(interp, nMarkerOps, markerOps, BLT_OP_ARG2, - objc, objv,0); - if (proc == NULL) { + if (objc < minArgs) { + Tcl_AppendResult(interp, "too few marker coordinates specified", + (char*)NULL); + return TCL_ERROR; + } + if ((maxArgs > 0) && (objc > maxArgs)) { + Tcl_AppendResult(interp, "too many marker coordinates specified", + (char*)NULL); return TCL_ERROR; } - result = (*proc) (graphPtr, interp, objc, objv); + nWorldPts = objc / 2; + worldPts = malloc(nWorldPts * sizeof(Point2d)); + if (worldPts == NULL) { + Tcl_AppendResult(interp, "can't allocate new coordinate array", + (char*)NULL); + return TCL_ERROR; + } + + { + Point2d *pp; + + pp = worldPts; + for (i = 0; i < objc; i += 2) { + double x, y; + + if ((GetCoordinate(interp, objv[i], &x) != TCL_OK) || + (GetCoordinate(interp, objv[i + 1], &y) != TCL_OK)) { + free(worldPts); + return TCL_ERROR; + } + pp->x = x, pp->y = y, pp++; + } + } + /* Don't free the old coordinate array until we've parsed the new + * coordinates without errors. */ + if (markerPtr->worldPts) { + free(markerPtr->worldPts); + } + markerPtr->worldPts = worldPts; + markerPtr->nWorldPts = nWorldPts; + markerPtr->flags |= MAP_ITEM; + return TCL_OK; +} + +static int IsElementHidden(Marker *markerPtr) +{ + Tcl_HashEntry *hPtr; + Graph* graphPtr = markerPtr->obj.graphPtr; + + if (markerPtr->elemName) { + hPtr = Tcl_FindHashEntry(&graphPtr->elements.table, markerPtr->elemName); + if (hPtr) { + Element* elemPtr = Tcl_GetHashValue(hPtr); + if ((elemPtr->link == NULL) || (elemPtr->flags & HIDE)) + return TRUE; + } + } + return FALSE; +} + +static double HMap(Axis *axisPtr, double x) +{ + if (x == DBL_MAX) + x = 1.0; + else if (x == -DBL_MAX) + x = 0.0; + else { + if (axisPtr->logScale) { + if (x > 0.0) + x = log10(x); + else if (x < 0.0) + x = 0.0; + } + x = NORMALIZE(axisPtr, x); + } + if (axisPtr->descending) + x = 1.0 - x; + + /* Horizontal transformation */ + return (x * axisPtr->screenRange + axisPtr->screenMin); +} + +static double VMap(Axis *axisPtr, double y) +{ + if (y == DBL_MAX) + y = 1.0; + else if (y == -DBL_MAX) + y = 0.0; + else { + if (axisPtr->logScale) { + if (y > 0.0) + y = log10(y); + else if (y < 0.0) + y = 0.0; + } + y = NORMALIZE(axisPtr, y); + } + if (axisPtr->descending) { + y = 1.0 - y; + } + /* Vertical transformation. */ + return (((1.0 - y) * axisPtr->screenRange) + axisPtr->screenMin); +} + +Point2d Blt_MapPoint(Point2d *pointPtr, Axis2d *axesPtr) +{ + Point2d result; + Graph* graphPtr = axesPtr->y->obj.graphPtr; + + if (graphPtr->inverted) { + result.x = HMap(axesPtr->y, pointPtr->y); + result.y = VMap(axesPtr->x, pointPtr->x); + } else { + result.x = HMap(axesPtr->x, pointPtr->x); + result.y = VMap(axesPtr->y, pointPtr->y); + } return result; } -void Blt_MarkersToPostScript(Graph* graphPtr, Blt_Ps ps, int under) +static int GetMarkerFromObj(Tcl_Interp* interp, Graph* graphPtr, + Tcl_Obj *objPtr, Marker **markerPtrPtr) { - Blt_ChainLink link; + Tcl_HashEntry *hPtr; + const char* string; - for (link = Blt_Chain_LastLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_PrevLink(link)) { - Marker *markerPtr; + string = Tcl_GetString(objPtr); + hPtr = Tcl_FindHashEntry(&graphPtr->markers.table, string); + if (hPtr) { + *markerPtrPtr = Tcl_GetHashValue(hPtr); + return TCL_OK; + } + if (interp) { + Tcl_AppendResult(interp, "can't find marker \"", string, + "\" in \"", Tk_PathName(graphPtr->tkwin), (char*)NULL); + } + return TCL_ERROR; +} - markerPtr = Blt_Chain_GetValue(link); +void Blt_MarkersToPostScript(Graph* graphPtr, Blt_Ps ps, int under) +{ + for (Blt_ChainLink link = Blt_Chain_LastLink(graphPtr->markers.displayList); + link; link = Blt_Chain_PrevLink(link)) { + Marker* markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->classPtr->postscriptProc == NULL) || - (markerPtr->nWorldPts == 0)) { + (markerPtr->nWorldPts == 0)) continue; - } - if (markerPtr->drawUnder != under) { + + if (markerPtr->drawUnder != under) continue; - } - if ((markerPtr->flags & DELETE_PENDING) || markerPtr->hide) { + + if ((markerPtr->flags & DELETE_PENDING) || markerPtr->hide) continue; - } - if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { + + if (IsElementHidden(markerPtr)) continue; - } + Blt_Ps_VarAppend(ps, "\n% Marker \"", markerPtr->obj.name, "\" is a ", markerPtr->obj.className, ".\n", (char*)NULL); (*markerPtr->classPtr->postscriptProc) (markerPtr, ps); @@ -956,57 +869,44 @@ void Blt_MarkersToPostScript(Graph* graphPtr, Blt_Ps ps, int under) void Blt_DrawMarkers(Graph* graphPtr, Drawable drawable, int under) { - Blt_ChainLink link; - - for (link = Blt_Chain_LastLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_PrevLink(link)) { - Marker *markerPtr; - - markerPtr = Blt_Chain_GetValue(link); + for (Blt_ChainLink link = Blt_Chain_LastLink(graphPtr->markers.displayList); + link; link = Blt_Chain_PrevLink(link)) { + Marker* markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->nWorldPts == 0) || (markerPtr->drawUnder != under) || (markerPtr->clipped) || (markerPtr->flags & DELETE_PENDING) || - (markerPtr->hide)) { + (markerPtr->hide)) continue; - } - if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { + + if (IsElementHidden(markerPtr)) continue; - } + (*markerPtr->classPtr->drawProc) (markerPtr, drawable); } } -void -Blt_ConfigureMarkers(Graph* graphPtr) +void Blt_ConfigureMarkers(Graph* graphPtr) { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { - Marker *markerPtr; - - markerPtr = Blt_Chain_GetValue(link); + for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); + link; link = Blt_Chain_NextLink(link)) { + Marker* markerPtr = Blt_Chain_GetValue(link); (*markerPtr->classPtr->configProc) (markerPtr); } } void Blt_MapMarkers(Graph* graphPtr) { - Blt_ChainLink link; - - for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { - Marker *markerPtr; - - markerPtr = Blt_Chain_GetValue(link); - if (markerPtr->nWorldPts == 0) { + for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); + link; link = Blt_Chain_NextLink(link)) { + Marker *markerPtr = Blt_Chain_GetValue(link); + if (markerPtr->nWorldPts == 0) continue; - } - if ((markerPtr->flags & DELETE_PENDING) || markerPtr->hide) { + + if ((markerPtr->flags & DELETE_PENDING) || markerPtr->hide) continue; - } + if ((graphPtr->flags & MAP_ALL) || (markerPtr->flags & MAP_ITEM)) { (*markerPtr->classPtr->mapProc) (markerPtr); markerPtr->flags &= ~MAP_ITEM; @@ -1016,14 +916,10 @@ void Blt_MapMarkers(Graph* graphPtr) void Blt_DestroyMarkers(Graph* graphPtr) { - Tcl_HashEntry *hPtr; Tcl_HashSearch iter; - - for (hPtr = Tcl_FirstHashEntry(&graphPtr->markers.table, &iter); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&iter)) { - Marker *markerPtr; - - markerPtr = Tcl_GetHashValue(hPtr); + for (Tcl_HashEntry* hPtr=Tcl_FirstHashEntry(&graphPtr->markers.table, &iter); + hPtr; hPtr = Tcl_NextHashEntry(&iter)) { + Marker* markerPtr = Tcl_GetHashValue(hPtr); /* * Dereferencing the pointer to the hash table prevents the hash table * entry from being automatically deleted. @@ -1038,19 +934,15 @@ void Blt_DestroyMarkers(Graph* graphPtr) Marker* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under) { - Blt_ChainLink link; Point2d point; - point.x = (double)x; point.y = (double)y; - for (link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link != NULL; link = Blt_Chain_NextLink(link)) { - Marker *markerPtr; - - markerPtr = Blt_Chain_GetValue(link); + for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); + link; link = Blt_Chain_NextLink(link)) { + Marker* markerPtr = Blt_Chain_GetValue(link); if ((markerPtr->nWorldPts == 0) || (markerPtr->flags & (DELETE_PENDING|MAP_ITEM)) || - (markerPtr->hide)) { + (markerPtr->hide)) continue; /* Don't consider markers that are * pending to be mapped. Even if the * marker has already been mapped, the @@ -1058,32 +950,28 @@ Marker* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under) * Better to pick no marker than the * wrong marker. */ - } - if ((markerPtr->elemName != NULL) && (IsElementHidden(markerPtr))) { + if (IsElementHidden(markerPtr)) continue; - } + if ((markerPtr->drawUnder == under) && - (markerPtr->state == BLT_STATE_NORMAL)) { - if ((*markerPtr->classPtr->pointProc) (markerPtr, &point)) { + (markerPtr->state == BLT_STATE_NORMAL)) + if ((*markerPtr->classPtr->pointProc) (markerPtr, &point)) return markerPtr; - } - } } return NULL; } ClientData Blt_MakeMarkerTag(Graph* graphPtr, const char* tagName) { - Tcl_HashEntry *hPtr; int isNew; - - hPtr = Tcl_CreateHashEntry(&graphPtr->markers.tagTable, tagName, &isNew); + Tcl_HashEntry *hPtr = + Tcl_CreateHashEntry(&graphPtr->markers.tagTable, tagName, &isNew); return Tcl_GetHashKey(&graphPtr->markers.tagTable, hPtr); } void Blt_FreeMarker(char* dataPtr) { - Marker *markerPtr = (Marker *)dataPtr; + Marker* markerPtr = (Marker*)dataPtr; DestroyMarker(markerPtr); } diff --git a/src/bltGrMarker.h b/src/bltGrMarker.h index 5ae42bb..ce5c496 100644 --- a/src/bltGrMarker.h +++ b/src/bltGrMarker.h @@ -32,23 +32,20 @@ #define MAX_OUTLINE_POINTS 12 -extern Blt_CustomOption coordsOption; extern Blt_CustomOption bltXAxisOption; extern Blt_CustomOption bltYAxisOption; -typedef Marker *(MarkerCreateProc)(void); -typedef void (MarkerDrawProc)(Marker *markerPtr, Drawable drawable); -typedef void (MarkerFreeProc)(Marker *markerPtr); -typedef int (MarkerConfigProc)(Marker *markerPtr); -typedef void (MarkerMapProc)(Marker *markerPtr); -typedef void (MarkerPostscriptProc)(Marker *markerPtr, Blt_Ps ps); -typedef int (MarkerPointProc)(Marker *markerPtr, Point2d *samplePtr); -typedef int (MarkerRegionProc)(Marker *markerPtr, Region2d *extsPtr, - int enclosed); +typedef Marker *(MarkerCreateProc)(Graph*); +typedef void (MarkerDrawProc)(Marker *markerPtr, Drawable drawable); +typedef void (MarkerFreeProc)(Marker *markerPtr); +typedef int (MarkerConfigProc)(Marker *markerPtr); +typedef void (MarkerMapProc)(Marker *markerPtr); +typedef void (MarkerPostscriptProc)(Marker *markerPtr, Blt_Ps ps); +typedef int (MarkerPointProc)(Marker *markerPtr, Point2d *samplePtr); +typedef int (MarkerRegionProc)(Marker *markerPtr, Region2d *extsPtr, int enclosed); typedef struct { - Blt_ConfigSpec *configSpecs; /* Marker configuration - * specifications */ + Tk_OptionSpec *optionSpecs; MarkerConfigProc *configProc; MarkerDrawProc *drawProc; MarkerFreeProc *freeProc; @@ -56,7 +53,6 @@ typedef struct { MarkerPointProc *pointProc; MarkerRegionProc *regionProc; MarkerPostscriptProc *postscriptProc; - } MarkerClass; struct _Marker { @@ -64,6 +60,7 @@ struct _Marker { MarkerClass *classPtr; + Tk_OptionTable optionTable; /* Configuration specifications */ Tcl_HashEntry *hashPtr; Blt_ChainLink link; @@ -96,6 +93,7 @@ struct _Marker { extern Tk_ObjCustomOption coordsObjOption; extern Tk_ObjCustomOption capStyleObjOption; +extern Tk_ObjCustomOption joinStyleObjOption; extern Tk_ObjCustomOption xAxisObjOption; extern Tk_ObjCustomOption yAxisObjOption; diff --git a/src/bltGrMarkerLine.C b/src/bltGrMarkerLine.C index 68d2495..21736a6 100644 --- a/src/bltGrMarkerLine.C +++ b/src/bltGrMarkerLine.C @@ -30,7 +30,7 @@ #include "bltGraph.h" #include "bltGrMarkerLine.h" -static Tk_OptionSpec lineOptionSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_CUSTOM, "-bindtags", "bindTags", "BindTags", "Line all", -1, Tk_Offset(LineMarker, obj.tags), TK_OPTION_NULL_OK, &listObjOption, 0}, @@ -49,7 +49,7 @@ static Tk_OptionSpec lineOptionSpecs[] = { {TK_OPTION_COLOR, "-fill", "fill", "Fill", NULL, -1, Tk_Offset(LineMarker, fillColor), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_CUSTOM, "-join", "join", "Join", - "miter", -1, Tk_Offset(LineMarker, joinStyle), 0, &capStyleObjOption, 0}, + "miter", -1, Tk_Offset(LineMarker, joinStyle), 0, &joinStyleObjOption, 0}, {TK_OPTION_PIXELS, "-linewidth", "lineWidth", "LineWidth", "1", -1, Tk_Offset(LineMarker, lineWidth), 0, NULL, 0}, {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide", @@ -58,12 +58,10 @@ static Tk_OptionSpec lineOptionSpecs[] = { "x", -1, Tk_Offset(LineMarker, axes.x), 0, &xAxisObjOption, 0}, {TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY", "y", -1, Tk_Offset(LineMarker, axes.y), 0, &yAxisObjOption, 0}, - {TK_OPTION_STRING, "-name", "name", "Name", - NULL, -1, Tk_Offset(LineMarker, obj.name), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-outline", "outline", "Outline", "black", -1, Tk_Offset(LineMarker, outlineColor), TK_OPTION_NULL_OK, NULL, 0}, - {TK_OPTION_CUSTOM, "-state", "state", "State", + {TK_OPTION_STRING_TABLE, "-state", "state", "State", "normal", -1, Tk_Offset(LineMarker, state), 0, &stateObjOption, 0}, {TK_OPTION_BOOLEAN, "-under", "under", "Under", "no", -1, Tk_Offset(LineMarker, drawUnder), 0, NULL, 0}, @@ -76,52 +74,6 @@ static Tk_OptionSpec lineOptionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static Blt_ConfigSpec lineConfigSpecs[] = { - {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Line all", - Tk_Offset(LineMarker, obj.tags), BLT_CONFIG_NULL_OK, - &listOption}, - {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", "butt", - Tk_Offset(LineMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL, - Tk_Offset(LineMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, - {BLT_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes", NULL, - Tk_Offset(LineMarker, dashes), BLT_CONFIG_NULL_OK, &dashesOption}, - {BLT_CONFIG_PIXELS, "-dashoffset", "dashOffset", "DashOffset", - "0", Tk_Offset(LineMarker, dashes.offset), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_STRING, "-element", "element", "Element", NULL, - Tk_Offset(LineMarker, elemName), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", (char*)NULL, - Tk_Offset(LineMarker, fillColor), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", "miter", - Tk_Offset(LineMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-linewidth", "lineWidth", "LineWidth", - "1", Tk_Offset(LineMarker, lineWidth), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no", - Tk_Offset(LineMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x", - Tk_Offset(LineMarker, axes.x), 0, &bltXAxisOption}, - {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y", - Tk_Offset(LineMarker, axes.y), 0, &bltYAxisOption}, - {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL, - Tk_Offset(LineMarker, obj.name), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", - "black", Tk_Offset(LineMarker, outlineColor), - BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal", - Tk_Offset(LineMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, - {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no", - Tk_Offset(LineMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0", - Tk_Offset(LineMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", "no", - Tk_Offset(LineMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0", - Tk_Offset(LineMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} -}; - MarkerCreateProc Blt_CreateLineProc; static MarkerConfigProc ConfigureLineProc; static MarkerDrawProc DrawLineProc; @@ -132,7 +84,7 @@ static MarkerPostscriptProc LineToPostscriptProc; static MarkerRegionProc RegionInLineProc; static MarkerClass lineMarkerClass = { - lineConfigSpecs, + optionSpecs, ConfigureLineProc, DrawLineProc, FreeLineProc, @@ -142,16 +94,16 @@ static MarkerClass lineMarkerClass = { LineToPostscriptProc, }; -Marker* Blt_CreateLineProc(void) +Marker* Blt_CreateLineProc(Graph* graphPtr) { - LineMarker *lmPtr; - - lmPtr = calloc(1, sizeof(LineMarker)); + LineMarker* lmPtr = calloc(1, sizeof(LineMarker)); lmPtr->classPtr = &lineMarkerClass; lmPtr->xor = FALSE; lmPtr->capStyle = CapButt; lmPtr->joinStyle = JoinMiter; - return (Marker *)lmPtr; + lmPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + + return (Marker*)lmPtr; } static int PointInLineProc(Marker *markerPtr, Point2d *samplePtr) diff --git a/src/bltGrMarkerLine.h b/src/bltGrMarkerLine.h index c2b4bf3..f6e8718 100644 --- a/src/bltGrMarkerLine.h +++ b/src/bltGrMarkerLine.h @@ -37,6 +37,7 @@ typedef struct { MarkerClass *classPtr; + Tk_OptionTable optionTable; /* Configuration specifications */ Tcl_HashEntry *hashPtr; Blt_ChainLink link; diff --git a/src/bltGrMarkerPolygon.C b/src/bltGrMarkerPolygon.C index fea7a07..a5c0ca4 100644 --- a/src/bltGrMarkerPolygon.C +++ b/src/bltGrMarkerPolygon.C @@ -30,7 +30,7 @@ #include "bltGraph.h" #include "bltGrMarkerPolygon.h" -static Tk_OptionSpec polygonOptionSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_CUSTOM, "-bindtags", "bindTags", "BindTags", "Polygon all", -1, Tk_Offset(PolygonMarker, obj.tags), TK_OPTION_NULL_OK, &listObjOption, 0}, @@ -49,7 +49,7 @@ static Tk_OptionSpec polygonOptionSpecs[] = { {TK_OPTION_COLOR, "-fillbg", "fillbg", "FillBg", NULL, -1, Tk_Offset(PolygonMarker, fillBg), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_CUSTOM, "-join", "join", "Join", - "miter", -1, Tk_Offset(PolygonMarker, joinStyle), 0, &capStyleObjOption, 0}, + "miter", -1, Tk_Offset(PolygonMarker, joinStyle), 0, &joinStyleObjOption, 0}, {TK_OPTION_PIXELS, "-polygonwidth", "polygonWidth", "PolygonWidth", "1", -1, Tk_Offset(PolygonMarker, lineWidth), 0, NULL, 0}, {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide", @@ -58,15 +58,13 @@ static Tk_OptionSpec polygonOptionSpecs[] = { "x", -1, Tk_Offset(PolygonMarker, axes.x), 0, &xAxisObjOption, 0}, {TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY", "y", -1, Tk_Offset(PolygonMarker, axes.y), 0, &yAxisObjOption, 0}, - {TK_OPTION_STRING, "-name", "name", "Name", - NULL, -1, Tk_Offset(PolygonMarker, obj.name), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-outline", "outline", "Outline", "black", -1, Tk_Offset(PolygonMarker, outline), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-outlinebg", "outlinebg", "OutlineBg", NULL, -1, Tk_Offset(PolygonMarker, outlineBg), TK_OPTION_NULL_OK, NULL, 0}, - {TK_OPTION_CUSTOM, "-state", "state", "State", + {TK_OPTION_STRING_TABLE, "-state", "state", "State", "normal", -1, Tk_Offset(PolygonMarker, state), 0, &stateObjOption, 0}, {TK_OPTION_BITMAP, "-stipple", "stipple", "Stipple", NULL, -1, Tk_Offset(PolygonMarker, stipple), TK_OPTION_NULL_OK, NULL, 0}, @@ -81,55 +79,6 @@ static Tk_OptionSpec polygonOptionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static Blt_ConfigSpec polygonConfigSpecs[] = { - {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Polygon all", - Tk_Offset(PolygonMarker, obj.tags), BLT_CONFIG_NULL_OK, - &listOption}, - {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", "butt", - Tk_Offset(PolygonMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL, - Tk_Offset(PolygonMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, - {BLT_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes", NULL, - Tk_Offset(PolygonMarker, dashes), BLT_CONFIG_NULL_OK, &dashesOption}, - {BLT_CONFIG_STRING, "-element", "element", "Element", NULL, - Tk_Offset(PolygonMarker, elemName), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", "rred", - Tk_Offset(PolygonMarker, fill), BLT_CONFIG_NULL_OK, NULL}, - {BLT_CONFIG_COLOR, "-fillbg", "fillbg", "FillBg", NULL, - Tk_Offset(PolygonMarker, fillBg), BLT_CONFIG_NULL_OK, NULL}, - {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", "miter", - Tk_Offset(PolygonMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-linewidth", "lineWidth", "LineWidth", - "1", Tk_Offset(PolygonMarker, lineWidth), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no", - Tk_Offset(PolygonMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x", - Tk_Offset(PolygonMarker, axes.x), 0, &bltXAxisOption}, - {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y", - Tk_Offset(PolygonMarker, axes.y), 0, &bltYAxisOption}, - {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL, - Tk_Offset(PolygonMarker, obj.name), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", - "black", Tk_Offset(PolygonMarker, outline), BLT_CONFIG_NULL_OK, NULL}, - {BLT_CONFIG_COLOR, "-outlinebg", "outlinebg", "OutlineBg", NULL, - Tk_Offset(PolygonMarker, outlineBg), BLT_CONFIG_NULL_OK, NULL}, - {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal", - Tk_Offset(PolygonMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, - {BLT_CONFIG_BITMAP, "-stipple", "stipple", "Stipple", NULL, - Tk_Offset(PolygonMarker, stipple), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no", - Tk_Offset(PolygonMarker, drawUnder), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0", - Tk_Offset(PolygonMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", "no", - Tk_Offset(PolygonMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0", - Tk_Offset(PolygonMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} -}; - MarkerCreateProc Blt_CreatePolygonProc; static MarkerConfigProc ConfigurePolygonProc; static MarkerDrawProc DrawPolygonProc; @@ -140,7 +89,7 @@ static MarkerPostscriptProc PolygonToPostscriptProc; static MarkerRegionProc RegionInPolygonProc; static MarkerClass polygonMarkerClass = { - polygonConfigSpecs, + optionSpecs, ConfigurePolygonProc, DrawPolygonProc, FreePolygonProc, @@ -150,15 +99,15 @@ static MarkerClass polygonMarkerClass = { PolygonToPostscriptProc, }; -Marker* Blt_CreatePolygonProc(void) +Marker* Blt_CreatePolygonProc(Graph* graphPtr) { - PolygonMarker *pmPtr; - - pmPtr = calloc(1, sizeof(PolygonMarker)); + PolygonMarker* pmPtr = calloc(1, sizeof(PolygonMarker)); pmPtr->classPtr = &polygonMarkerClass; pmPtr->capStyle = CapButt; pmPtr->joinStyle = JoinMiter; - return (Marker *)pmPtr; + pmPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + + return (Marker*)pmPtr; } static int PointInPolygonProc(Marker *markerPtr, Point2d *samplePtr) diff --git a/src/bltGrMarkerPolygon.h b/src/bltGrMarkerPolygon.h index dbc13ff..30b77f0 100644 --- a/src/bltGrMarkerPolygon.h +++ b/src/bltGrMarkerPolygon.h @@ -37,6 +37,7 @@ typedef struct { MarkerClass *classPtr; + Tk_OptionTable optionTable; /* Configuration specifications */ Tcl_HashEntry *hashPtr; Blt_ChainLink link; diff --git a/src/bltGrMarkerText.C b/src/bltGrMarkerText.C index 8ccdac4..da047e4 100644 --- a/src/bltGrMarkerText.C +++ b/src/bltGrMarkerText.C @@ -31,7 +31,7 @@ #include "bltGrMarkerText.h" #include "bltMath.h" -static Tk_OptionSpec textOptionSpecs[] = { +static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "center", -1, Tk_Offset(TextMarker, anchor), 0, NULL, 0}, {TK_OPTION_COLOR, "-background", "background", "Background", @@ -60,8 +60,6 @@ static Tk_OptionSpec textOptionSpecs[] = { "x", -1, Tk_Offset(TextMarker, axes.x), 0, &xAxisObjOption, 0}, {TK_OPTION_CUSTOM, "-mapy", "mapY", "MapY", "y", -1, Tk_Offset(TextMarker, axes.y), 0, &yAxisObjOption, 0}, - {TK_OPTION_STRING, "-name", "name", "Name", - NULL, -1, Tk_Offset(TextMarker, obj.name), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_SYNONYM, "-outline", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0}, {TK_OPTION_PIXELS, "-padx", "padX", "PadX", "4", -1, Tk_Offset(TextMarker, style.xPad), 0, NULL, 0}, @@ -69,7 +67,7 @@ static Tk_OptionSpec textOptionSpecs[] = { "4", -1, Tk_Offset(TextMarker, style.yPad), 0, NULL, 0}, {TK_OPTION_DOUBLE, "-rotate", "rotate", "Rotate", "0", -1, Tk_Offset(TextMarker, style.angle), 0, NULL, 0}, - {TK_OPTION_CUSTOM, "-state", "state", "State", + {TK_OPTION_STRING_TABLE, "-state", "state", "State", "normal", -1, Tk_Offset(TextMarker, state), 0, &stateObjOption, 0}, {TK_OPTION_STRING, "-text", "text", "Text", NULL, -1, Tk_Offset(TextMarker, string), TK_OPTION_NULL_OK, NULL, 0}, @@ -82,60 +80,6 @@ static Tk_OptionSpec textOptionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static Blt_ConfigSpec textConfigSpecs[] = { - {BLT_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", "center", - Tk_Offset(TextMarker, anchor), 0}, - {BLT_CONFIG_COLOR, "-background", "background", "MarkerBackground", - (char*)NULL, Tk_Offset(TextMarker, fillColor), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_SYNONYM, "-bg", "background", "Background", (char*)NULL, 0, 0}, - {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Text all", - Tk_Offset(TextMarker, obj.tags), BLT_CONFIG_NULL_OK, - &listOption}, - {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL, - Tk_Offset(TextMarker, worldPts), BLT_CONFIG_NULL_OK, - &coordsOption}, - {BLT_CONFIG_STRING, "-element", "element", "Element", - NULL, Tk_Offset(TextMarker, elemName), - BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_SYNONYM, "-fg", "foreground", "Foreground", (char*)NULL, 0, 0}, - {BLT_CONFIG_SYNONYM, "-fill", "background", (char*)NULL, (char*)NULL, - 0, 0}, - {BLT_CONFIG_FONT, "-font", "font", "Font", STD_FONT_NORMAL, - Tk_Offset(TextMarker, style.font), 0}, - {BLT_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - "black", Tk_Offset(TextMarker, style.color), 0}, - {BLT_CONFIG_JUSTIFY, "-justify", "justify", "Justify", - "left", Tk_Offset(TextMarker, style.justify), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no", - Tk_Offset(TextMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x", - Tk_Offset(TextMarker, axes.x), 0, &bltXAxisOption}, - {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y", - Tk_Offset(TextMarker, axes.y), 0, &bltYAxisOption}, - {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL, - Tk_Offset(TextMarker, obj.name), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_SYNONYM, "-outline", "foreground", (char*)NULL, (char*)NULL, - 0, 0}, - {BLT_CONFIG_PIXELS, "-padx", "padX", "PadX", "4", - Tk_Offset(TextMarker, style.xPad), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-pady", "padY", "PadY", "4", - Tk_Offset(TextMarker, style.yPad), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_DOUBLE, "-rotate", "rotate", "Rotate", "0", - Tk_Offset(TextMarker, style.angle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal", - Tk_Offset(TextMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, - {BLT_CONFIG_STRING, "-text", "text", "Text", NULL, - Tk_Offset(TextMarker, string), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no", - Tk_Offset(TextMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0", - Tk_Offset(TextMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0", - Tk_Offset(TextMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} -}; - MarkerCreateProc Blt_CreateTextProc; static MarkerConfigProc ConfigureTextProc; static MarkerDrawProc DrawTextProc; @@ -146,7 +90,7 @@ static MarkerPostscriptProc TextToPostscriptProc; static MarkerRegionProc RegionInTextProc; static MarkerClass textMarkerClass = { - textConfigSpecs, + optionSpecs, ConfigureTextProc, DrawTextProc, FreeTextProc, @@ -156,16 +100,16 @@ static MarkerClass textMarkerClass = { TextToPostscriptProc, }; -Marker* Blt_CreateTextProc(void) +Marker* Blt_CreateTextProc(Graph* graphPtr) { - TextMarker *tmPtr; - - tmPtr = calloc(1, sizeof(TextMarker)); + TextMarker* tmPtr = calloc(1, sizeof(TextMarker)); tmPtr->classPtr = &textMarkerClass; Blt_Ts_InitStyle(tmPtr->style); tmPtr->style.anchor = TK_ANCHOR_NW; tmPtr->style.xPad = 4; tmPtr->style.yPad = 4; + tmPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + return (Marker *)tmPtr; } diff --git a/src/bltGrMarkerText.h b/src/bltGrMarkerText.h index 2b73469..c826a21 100644 --- a/src/bltGrMarkerText.h +++ b/src/bltGrMarkerText.h @@ -35,6 +35,8 @@ typedef struct { GraphObj obj; /* Must be first field in marker. */ MarkerClass *classPtr; + + Tk_OptionTable optionTable; /* Configuration specifications */ Tcl_HashEntry *hashPtr; Blt_ChainLink link; const char* elemName; /* Element associated with marker. Let's diff --git a/src/bltGrPenOp.C b/src/bltGrPenOp.C index ce2be55..4be0a95 100644 --- a/src/bltGrPenOp.C +++ b/src/bltGrPenOp.C @@ -107,7 +107,6 @@ int Blt_CreatePen(Graph* graphPtr, Tcl_Interp* interp, const char* penName, ClassId classId, int objc, Tcl_Obj* const objv[]) { - Pen* penPtr; int isNew; Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&graphPtr->penTable, penName, &isNew); @@ -118,6 +117,7 @@ int Blt_CreatePen(Graph* graphPtr, Tcl_Interp* interp, return TCL_ERROR; } + Pen* penPtr; switch (classId) { case CID_ELEM_BAR: penPtr = Blt_BarPen(graphPtr, penName); @@ -232,7 +232,7 @@ static int PenObjConfigure(Tcl_Interp* interp, Graph* graphPtr, Pen* penPtr, graphPtr->flags |= mask; graphPtr->flags |= CACHE_DIRTY; - if ((*penPtr->configProc) (graphPtr, penPtr) != TCL_OK) + if ((*penPtr->configProc)(graphPtr, penPtr) != TCL_OK) return TCL_ERROR; Blt_EventuallyRedrawGraph(graphPtr); @@ -255,9 +255,11 @@ static int PenObjConfigure(Tcl_Interp* interp, Graph* graphPtr, Pen* penPtr, static int CreateOp(Tcl_Interp* interp, Graph* graphPtr, int objc, Tcl_Obj* const objv[]) { - if (Blt_CreatePen(graphPtr, interp, Tcl_GetString(objv[3]), graphPtr->classId, objc, objv) != TCL_OK) + if (Blt_CreatePen(graphPtr, interp, Tcl_GetString(objv[3]), + graphPtr->classId, objc, objv) != TCL_OK) return TCL_ERROR; Tcl_SetObjResult(interp, objv[3]); + return TCL_OK; } diff --git a/src/bltGraph.h b/src/bltGraph.h index f69beae..ae53fae 100644 --- a/src/bltGraph.h +++ b/src/bltGraph.h @@ -607,7 +607,7 @@ extern int Blt_ElementOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[], ClassId classId); extern int Blt_CrosshairsOp(Graph* graphPtr, Tcl_Interp* interp, int objc, - Tcl_Obj* const objv[]); + Tcl_Obj* const objv[]); extern int Blt_MarkerOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]); @@ -640,6 +640,7 @@ extern Marker *Blt_NearestMarker(Graph* graphPtr, int x, int y, int under); extern Axis *Blt_NearestAxis(Graph* graphPtr, int x, int y); typedef ClientData (MakeTagProc)(Graph* graphPtr, const char *tagName); + extern MakeTagProc Blt_MakeElementTag; extern MakeTagProc Blt_MakeMarkerTag; extern MakeTagProc Blt_MakeAxisTag; @@ -656,11 +657,8 @@ extern void Blt_ActiveElementsToPostScript(Graph* graphPtr, Blt_Ps ps); extern void Blt_LegendToPostScript(Graph* graphPtr, Blt_Ps ps); extern void Blt_AxesToPostScript(Graph* graphPtr, Blt_Ps ps); extern void Blt_AxisLimitsToPostScript(Graph* graphPtr, Blt_Ps ps); - -extern Element *Blt_LineElement(Graph* graphPtr, const char *name, - ClassId classId); -extern Element *Blt_BarElement(Graph* graphPtr, const char *name, - ClassId classId); +extern Element *Blt_LineElement(Graph* graphPtr); +extern Element *Blt_BarElement(Graph* graphPtr); extern void Blt_DrawGrids(Graph* graphPtr, Drawable drawable); @@ -668,9 +666,6 @@ extern void Blt_GridsToPostScript(Graph* graphPtr, Blt_Ps ps); extern void Blt_InitBarSetTable(Graph* graphPtr); extern void Blt_DestroyBarSets(Graph* graphPtr); -/* ---------------------- Global declarations ------------------------ */ - extern const char *Blt_GraphClassName(ClassId classId); - #endif diff --git a/src/bltVector.C b/src/bltVector.C index bf69143..50fac01 100644 --- a/src/bltVector.C +++ b/src/bltVector.C @@ -1616,12 +1616,8 @@ VectorCreate2( *--------------------------------------------------------------------------- */ /*ARGSUSED*/ -static int -VectorCreateOp( - ClientData clientData, - Tcl_Interp* interp, - int objc, - Tcl_Obj* const objv[]) +static int VectorCreateOp(ClientData clientData, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { return VectorCreate2(clientData, interp, 2, objc, objv); } -- cgit v0.12