diff options
Diffstat (limited to 'src/bltGrMarker.C')
-rw-r--r-- | src/bltGrMarker.C | 806 |
1 files changed, 13 insertions, 793 deletions
diff --git a/src/bltGrMarker.C b/src/bltGrMarker.C index f00ac6d..2e26fed 100644 --- a/src/bltGrMarker.C +++ b/src/bltGrMarker.C @@ -27,27 +27,15 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltC.h" -#include "bltMath.h" - extern "C" { #include "bltGraph.h" -#include "bltOp.h" }; -#include "bltConfig.h" -#include "bltGrElem.h" #include "bltGrMarker.h" -#include "bltGrMarkerBitmap.h" -#include "bltGrMarkerLine.h" -#include "bltGrMarkerPolygon.h" -#include "bltGrMarkerText.h" using namespace Blt; -#define NORMALIZE(A,x) (((x) - (A)->axisRange.min) * (A)->axisRange.scale) - -Marker::Marker(Graph* graphPtr, const char* name) +Marker::Marker(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr) { obj.classId =CID_NONE; obj.name = dupstr(name); @@ -55,11 +43,11 @@ Marker::Marker(Graph* graphPtr, const char* name) obj.graphPtr =graphPtr; obj.tags = NULL; - classPtr =NULL; - optionTable =NULL; - hashPtr =NULL; + optionTable_ =NULL; + clipped_ =0; + + hashPtr_ = hPtr; link =NULL; - clipped =0; flags =0; } @@ -69,7 +57,7 @@ Marker::~Marker() // If the marker to be deleted is currently displayed below the // elements, then backing store needs to be repaired. - if (((MarkerOptions*)ops)->drawUnder) + if (((MarkerOptions*)ops_)->drawUnder) graphPtr->flags |= CACHE_DIRTY; Blt_DeleteBindings(graphPtr->bindTable, this); @@ -80,16 +68,16 @@ Marker::~Marker() if (obj.name) delete [] obj.name; - if (hashPtr) - Tcl_DeleteHashEntry(hashPtr); + if (hashPtr_) + Tcl_DeleteHashEntry(hashPtr_); if (link) Blt_Chain_DeleteLink(graphPtr->markers.displayList, link); - Tk_FreeConfigOptions((char*)ops, optionTable, graphPtr->tkwin); + Tk_FreeConfigOptions((char*)ops_, optionTable_, graphPtr->tkwin); - if (ops) - free(ops); + if (ops_) + free(ops_); } double Marker::HMap(Axis *axisPtr, double x) @@ -105,7 +93,7 @@ double Marker::HMap(Axis *axisPtr, double x) else if (x < 0.0) x = 0.0; } - x = NORMALIZE(axisPtr, x); + x = (x - axisPtr->axisRange.min) * axisPtr->axisRange.scale; } if (axisPtr->descending) x = 1.0 - x; @@ -127,7 +115,7 @@ double Marker::VMap(Axis *axisPtr, double y) else if (y < 0.0) y = 0.0; } - y = NORMALIZE(axisPtr, y); + y = (y - axisPtr->axisRange.min) * axisPtr->axisRange.scale; } if (axisPtr->descending) y = 1.0 - y; @@ -160,771 +148,3 @@ int Marker::boxesDontOverlap(Graph* graphPtr, Region2d *extsPtr) (extsPtr->right < (double)graphPtr->left) || (extsPtr->bottom < (double)graphPtr->top)); } - -// Defs - -static int GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr); -static Tcl_Obj* PrintCoordinate(double x); - -typedef int (GraphMarkerProc)(Graph* graphPtr, Tcl_Interp* interp, int objc, - Tcl_Obj* const objv[]); - -static int MarkerObjConfigure( Tcl_Interp* interp, Graph* graphPtr, - Marker* markerPtr, - int objc, Tcl_Obj* const objv[]); -static int GetMarkerFromObj(Tcl_Interp* interp, Graph* graphPtr, - Tcl_Obj* objPtr, Marker** markerPtrPtr); -static int IsElementHidden(Marker* markerPtr); - -extern "C" { - void Blt_DestroyMarkers(Graph* graphPtr); - void Blt_DrawMarkers(Graph* graphPtr, Drawable drawable, int under); - ClientData Blt_MakeMarkerTag(Graph* graphPtr, const char* tagName); - void Blt_MapMarkers(Graph* graphPtr); - int Blt_MarkerOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]); - void Blt_MarkersToPostScript(Graph* graphPtr, Blt_Ps ps, int under); - void* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under); -}; - -// OptionSpecs - -static Tk_CustomOptionSetProc CoordsSetProc; -static Tk_CustomOptionGetProc CoordsGetProc; -static Tk_CustomOptionFreeProc CoordsFreeProc; -Tk_ObjCustomOption coordsObjOption = - { - "coords", CoordsSetProc, CoordsGetProc, RestoreProc, CoordsFreeProc, NULL - }; - -static int CoordsSetProc(ClientData clientData, Tcl_Interp* interp, - Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec, - int offset, char* savePtr, int flags) -{ - Coords** coordsPtrPtr = (Coords**)(widgRec + offset); - *(double*)savePtr = *(double*)coordsPtrPtr; - - if (!coordsPtrPtr) - return TCL_OK; - - int objc; - Tcl_Obj** objv; - if (Tcl_ListObjGetElements(interp, *objPtr, &objc, &objv) != TCL_OK) - return TCL_ERROR; - - if (objc == 0) { - *coordsPtrPtr = NULL; - return TCL_OK; - } - - if (objc & 1) { - Tcl_AppendResult(interp, "odd number of marker coordinates specified",NULL); - return TCL_ERROR; - } - - Coords* coordsPtr = (Coords*)calloc(1,sizeof(Coords)); - coordsPtr->num = objc/2; - coordsPtr->points = (Point2d*)calloc(coordsPtr->num, sizeof(Point2d)); - - Point2d* pp = coordsPtr->points; - for (int ii=0; ii<objc; ii+=2) { - double x, y; - if ((GetCoordinate(interp, objv[ii], &x) != TCL_OK) || - (GetCoordinate(interp, objv[ii+1], &y) != TCL_OK)) - return TCL_ERROR; - pp->x = x; - pp->y = y; - pp++; - } - - *coordsPtrPtr = coordsPtr; - return TCL_OK; -} - -static Tcl_Obj* CoordsGetProc(ClientData clientData, Tk_Window tkwin, - char *widgRec, int offset) -{ - Coords* coordsPtr = *(Coords**)(widgRec + offset); - - if (!coordsPtr) - return Tcl_NewListObj(0, NULL); - - int cnt = coordsPtr->num*2; - Tcl_Obj** ll = (Tcl_Obj**)calloc(cnt, sizeof(Tcl_Obj*)); - - Point2d* pp = coordsPtr->points; - for (int ii=0; ii<cnt; pp++) { - ll[ii++] = PrintCoordinate(pp->x); - ll[ii++] = PrintCoordinate(pp->y); - } - - Tcl_Obj* listObjPtr = Tcl_NewListObj(cnt, ll); - free(ll); - return listObjPtr; -} - -static void CoordsFreeProc(ClientData clientData, Tk_Window tkwin, - char *ptr) -{ - Coords* coordsPtr = *(Coords**)ptr; - if (coordsPtr) { - if (coordsPtr->points) - free(coordsPtr->points); - free(coordsPtr); - } -} - -static Tk_CustomOptionSetProc CapStyleSetProc; -static Tk_CustomOptionGetProc CapStyleGetProc; -Tk_ObjCustomOption capStyleObjOption = - { - "capStyle", CapStyleSetProc, CapStyleGetProc, NULL, NULL, NULL - }; - -static int CapStyleSetProc(ClientData clientData, Tcl_Interp* interp, - Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec, - int offset, char* save, int flags) -{ - int* ptr = (int*)(widgRec + offset); - - Tk_Uid uid = Tk_GetUid(Tcl_GetString(*objPtr)); - int cap; - if (Tk_GetCapStyle(interp, uid, &cap) != TCL_OK) - return TCL_ERROR; - *ptr = cap; - - return TCL_OK; -} - -static Tcl_Obj* CapStyleGetProc(ClientData clientData, Tk_Window tkwin, - char *widgRec, int offset) -{ - int* ptr = (int*)(widgRec + offset); - return Tcl_NewStringObj(Tk_NameOfCapStyle(*ptr), -1); -} - -static Tk_CustomOptionSetProc JoinStyleSetProc; -static Tk_CustomOptionGetProc JoinStyleGetProc; -Tk_ObjCustomOption joinStyleObjOption = - { - "joinStyle", JoinStyleSetProc, JoinStyleGetProc, NULL, NULL, NULL - }; - -static int JoinStyleSetProc(ClientData clientData, Tcl_Interp* interp, - Tk_Window tkwin, Tcl_Obj** objPtr, char* widgRec, - int offset, char* save, int flags) -{ - 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* JoinStyleGetProc(ClientData clientData, Tk_Window tkwin, - char *widgRec, int offset) -{ - int* ptr = (int*)(widgRec + offset); - return Tcl_NewStringObj(Tk_NameOfJoinStyle(*ptr), -1); -} - -// Create - -static int CreateMarker(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - int offset = 5; - char* name =NULL; - char ident[128]; - if (objc == 4) { - offset = 4; - sprintf_s(ident, 128, "marker%d", graphPtr->nextMarkerId++); - name = ident; - } - else { - name = Tcl_GetString(objv[4]); - if (name[0] == '-') { - offset = 4; - sprintf_s(ident, 128, "marker%d", graphPtr->nextMarkerId++); - name = ident; - } - } - - 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; - } - - const char* type = Tcl_GetString(objv[3]); - Marker* markerPtr; - if (!strcmp(type, "bitmap")) - markerPtr = new BitmapMarker(graphPtr, name); - else if (!strcmp(type, "line")) - markerPtr = new LineMarker(graphPtr, name); - else if (!strcmp(type, "polygon")) - markerPtr = new PolygonMarker(graphPtr, name); - else if (!strcmp(type, "text")) - markerPtr = new TextMarker(graphPtr, name); - else { - Tcl_AppendResult(interp, "unknown marker type ", type, NULL); - return TCL_ERROR; - } - - markerPtr->hashPtr = hPtr; - Tcl_SetHashValue(hPtr, markerPtr); - - if ((Tk_InitOptions(graphPtr->interp, (char*)markerPtr->ops, markerPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (MarkerObjConfigure(interp, graphPtr, markerPtr, objc-offset, objv+offset) != TCL_OK)) { - delete markerPtr; - return TCL_ERROR; - } - - // 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; -} - -// Configure - -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; - - Tcl_Obj* objPtr = Tk_GetOptionValue(interp, (char*)markerPtr->ops, - markerPtr->optionTable, - objv[4], graphPtr->tkwin); - if (objPtr == NULL) - return TCL_ERROR; - else - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; -} - -static int ConfigureOp(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 (objc <= 5) { - Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)markerPtr->ops, - 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 MarkerObjConfigure( Tcl_Interp* interp, Graph* graphPtr, - Marker* markerPtr, - int objc, Tcl_Obj* const objv[]) -{ - Tk_SavedOptions savedOptions; - int mask =0; - int error; - Tcl_Obj* errorResult; - - for (error=0; error<=1; error++) { - if (!error) { - if (Tk_SetOptions(interp, (char*)markerPtr->ops, 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->configure() != TCL_OK) - return TCL_ERROR; - Blt_EventuallyRedrawGraph(graphPtr); - - break; - } - - if (!error) { - Tk_FreeSavedOptions(&savedOptions); - return TCL_OK; - } - else { - Tcl_SetObjResult(interp, errorResult); - Tcl_DecrRefCount(errorResult); - return TCL_ERROR; - } -} - -// Ops - -static int BindOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - if (objc == 3) { - Tcl_Obj *listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - Tcl_HashSearch iter; - for (Tcl_HashEntry* hp = - Tcl_FirstHashEntry(&graphPtr->markers.tagTable, &iter); - hp; hp = Tcl_NextHashEntry(&iter)) { - - const char* tag = - (const char*)Tcl_GetHashKey(&graphPtr->markers.tagTable, hp); - Tcl_Obj* 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 CreateOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - if (CreateMarker(graphPtr, interp, objc, objv) != TCL_OK) - return TCL_ERROR; - // set in CreateMarker - // Tcl_SetObjResult(interp, objv[3]); - - return TCL_OK; -} - -static int DeleteOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - for (int ii=3; ii<objc; ii++) { - Marker* markerPtr; - if (GetMarkerFromObj(NULL, graphPtr, objv[ii], &markerPtr) != TCL_OK) { - Tcl_AppendResult(interp, "can't find marker \"", - Tcl_GetString(objv[ii]), "\" in \"", - Tk_PathName(graphPtr->tkwin), "\"", NULL); - return TCL_ERROR; - } - markerPtr->flags |= DELETE_PENDING; - Tcl_EventuallyFree(markerPtr, Blt_FreeMarker); - } - - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; -} - -static int ExistsOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Tcl_HashEntry* hPtr = - Tcl_FindHashEntry(&graphPtr->markers.table, Tcl_GetString(objv[3])); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (hPtr)); - - return TCL_OK; -} - -static int FindOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ -#define FIND_ENCLOSED (1<<0) -#define FIND_OVERLAPPING (1<<1) - const char* string = Tcl_GetString(objv[3]); - int mode; - if (strcmp(string, "enclosed") == 0) - mode = FIND_ENCLOSED; - else if (strcmp(string, "overlapping") == 0) - mode = FIND_OVERLAPPING; - else { - Tcl_AppendResult(interp, "bad search type \"", string, - ": should be \"enclosed\", or \"overlapping\"", - NULL); - return TCL_ERROR; - } - - int left, right, top, bottom; - if ((Tcl_GetIntFromObj(interp, objv[4], &left) != TCL_OK) || - (Tcl_GetIntFromObj(interp, objv[5], &top) != TCL_OK) || - (Tcl_GetIntFromObj(interp, objv[6], &right) != TCL_OK) || - (Tcl_GetIntFromObj(interp, objv[7], &bottom) != TCL_OK)) { - return TCL_ERROR; - } - - Region2d extents; - if (left < right) { - extents.left = (double)left; - extents.right = (double)right; - } - else { - extents.left = (double)right; - extents.right = (double)left; - } - if (top < bottom) { - extents.top = (double)top; - extents.bottom = (double)bottom; - } - else { - extents.top = (double)bottom; - extents.bottom = (double)top; - } - - int enclosed = (mode == FIND_ENCLOSED); - for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link; link = Blt_Chain_NextLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - if ((markerPtr->flags & DELETE_PENDING) || ops->hide) { - continue; - } - if (IsElementHidden(markerPtr)) - continue; - - if (markerPtr->regionIn(&extents, enclosed)) { - Tcl_Obj* objPtr = Tcl_GetObjResult(interp); - Tcl_SetStringObj(objPtr, markerPtr->obj.name, -1); - return TCL_OK; - } - } - - Tcl_SetStringObj(Tcl_GetObjResult(interp), "", -1); - return TCL_OK; -} - -static int GetOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - const char* string = Tcl_GetString(objv[3]); - if (!strcmp(string, "current")) { - Marker* markerPtr = (Marker*)Blt_GetCurrentItem(graphPtr->bindTable); - - if (markerPtr == NULL) - return TCL_OK; - - // Report only on markers - if ((markerPtr->obj.classId >= CID_MARKER_BITMAP) && - (markerPtr->obj.classId <= CID_MARKER_WINDOW)) - Tcl_SetStringObj(Tcl_GetObjResult(interp), markerPtr->obj.name, -1); - } - - return TCL_OK; -} - -static int NamesOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Tcl_Obj* listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **)NULL); - if (objc == 3) { - for (Blt_ChainLink link=Blt_Chain_FirstLink(graphPtr->markers.displayList); - link; link = Blt_Chain_NextLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - Tcl_ListObjAppendElement(interp, listObjPtr, - Tcl_NewStringObj(markerPtr->obj.name, -1)); - } - } - else { - for (Blt_ChainLink link=Blt_Chain_FirstLink(graphPtr->markers.displayList); - link; link = Blt_Chain_NextLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - for (int ii = 3; ii<objc; ii++) { - const char* pattern = (const char*)Tcl_GetString(objv[ii]); - 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[]) -{ - Marker* markerPtr; - if (GetMarkerFromObj(interp, graphPtr, objv[3], &markerPtr) != TCL_OK) - return TCL_ERROR; - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - - Marker* placePtr =NULL; - if (objc == 5) - if (GetMarkerFromObj(interp, graphPtr, objv[4], &placePtr) != TCL_OK) - return TCL_ERROR; - - Blt_ChainLink link = markerPtr->link; - Blt_Chain_UnlinkLink(graphPtr->markers.displayList, markerPtr->link); - - Blt_ChainLink place = placePtr ? placePtr->link : NULL; - - const char* 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 (ops->drawUnder) - graphPtr->flags |= CACHE_DIRTY; - - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; -} - -static int TypeOp(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; - - switch (markerPtr->obj.classId) { - 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; - } -} - -static Blt_OpSpec markerOps[] = - { - {"bind", 1, (void*)BindOp, 3, 6, "marker sequence command",}, - {"cget", 2, (void*)CgetOp, 5, 5, "marker option",}, - {"configure", 2, (void*)ConfigureOp, 4, 0,"marker ?option value?...",}, - {"create", 2, (void*)CreateOp, 4, 0, "type ?option value?...",}, - {"delete", 1, (void*)DeleteOp, 3, 0, "?marker?...",}, - {"exists", 1, (void*)ExistsOp, 4, 4, "marker",}, - {"find", 1, (void*)FindOp, 8, 8, "option x1 y1 x2 y2",}, - {"get", 1, (void*)GetOp, 5, 5, "current",}, - {"lower", 1, (void*)RelinkOp, 4, 5, "marker ?afterMarker?",}, - {"names", 1, (void*)NamesOp, 3, 0, "?pattern?...",}, - {"raise", 1, (void*)RelinkOp, 4, 5, "marker ?beforeMarker?",}, - {"type", 1, (void*)TypeOp, 4, 4, "marker",}, - }; -static int nMarkerOps = sizeof(markerOps) / sizeof(Blt_OpSpec); - -int Blt_MarkerOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - GraphMarkerProc* proc = (GraphMarkerProc*)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 IsElementHidden(Marker* markerPtr) -{ - Tcl_HashEntry *hPtr; - Graph* graphPtr = markerPtr->obj.graphPtr; - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - - if (ops->elemName) { - hPtr = Tcl_FindHashEntry(&graphPtr->elements.table, ops->elemName); - if (hPtr) { - Element* elemPtr = (Element*)Tcl_GetHashValue(hPtr); - if (!elemPtr->link || elemPtr->hide) - return TRUE; - } - } - return FALSE; -} - -static int GetMarkerFromObj(Tcl_Interp* interp, Graph* graphPtr, - Tcl_Obj *objPtr, Marker** markerPtrPtr) -{ - const char* string = Tcl_GetString(objPtr); - Tcl_HashEntry* hPtr = Tcl_FindHashEntry(&graphPtr->markers.table, string); - if (hPtr) { - *markerPtrPtr = (Marker*)Tcl_GetHashValue(hPtr); - return TCL_OK; - } - if (interp) { - Tcl_AppendResult(interp, "can't find marker \"", string, - "\" in \"", Tk_PathName(graphPtr->tkwin), NULL); - } - - return TCL_ERROR; -} - -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 = (Marker*)Blt_Chain_GetValue(link); - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - if (ops->drawUnder != under) - continue; - - if ((markerPtr->flags & DELETE_PENDING) || ops->hide) - continue; - - if (IsElementHidden(markerPtr)) - continue; - - Blt_Ps_VarAppend(ps, "\n% Marker \"", markerPtr->obj.name, - "\" is a ", markerPtr->obj.className, ".\n", (char*)NULL); - markerPtr->postscript(ps); - } -} - -void Blt_DrawMarkers(Graph* graphPtr, Drawable drawable, int under) -{ - for (Blt_ChainLink link = Blt_Chain_LastLink(graphPtr->markers.displayList); - link; link = Blt_Chain_PrevLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - - if ((ops->drawUnder != under) || - (markerPtr->clipped) || - (markerPtr->flags & DELETE_PENDING) || - (ops->hide)) - continue; - - if (IsElementHidden(markerPtr)) - continue; - - markerPtr->draw(drawable); - } -} - -void Blt_ConfigureMarkers(Graph* graphPtr) -{ - for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link; link = Blt_Chain_NextLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - markerPtr->configure(); - } -} - -void Blt_MapMarkers(Graph* graphPtr) -{ - for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link; link = Blt_Chain_NextLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - - if ((markerPtr->flags & DELETE_PENDING) || ops->hide) - continue; - - if ((graphPtr->flags & MAP_ALL) || (markerPtr->flags & MAP_ITEM)) { - markerPtr->map(); - markerPtr->flags &= ~MAP_ITEM; - } - } -} - -void Blt_DestroyMarkers(Graph* graphPtr) -{ - Tcl_HashSearch iter; - for (Tcl_HashEntry* hPtr=Tcl_FirstHashEntry(&graphPtr->markers.table, &iter); - hPtr; hPtr = Tcl_NextHashEntry(&iter)) { - Marker* markerPtr = (Marker*)Tcl_GetHashValue(hPtr); - - // Dereferencing the pointer to the hash table prevents the hash table - // entry from being automatically deleted. - markerPtr->hashPtr = NULL; - delete markerPtr; - } - Tcl_DeleteHashTable(&graphPtr->markers.table); - Tcl_DeleteHashTable(&graphPtr->markers.tagTable); - Blt_Chain_Destroy(graphPtr->markers.displayList); -} - -void* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under) -{ - Point2d point; - point.x = (double)x; - point.y = (double)y; - for (Blt_ChainLink link = Blt_Chain_FirstLink(graphPtr->markers.displayList); - link; link = Blt_Chain_NextLink(link)) { - Marker* markerPtr = (Marker*)Blt_Chain_GetValue(link); - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; - - if ((markerPtr->flags & (DELETE_PENDING|MAP_ITEM)) || - (ops->hide)) - continue; - - if (IsElementHidden(markerPtr)) - continue; - - if ((ops->drawUnder == under) && (ops->state == BLT_STATE_NORMAL)) - if (markerPtr->pointIn(&point)) - return markerPtr; - } - return NULL; -} - -ClientData Blt_MakeMarkerTag(Graph* graphPtr, const char* tagName) -{ - int 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; - delete markerPtr; -} - -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 GetCoordinate(Tcl_Interp* interp, Tcl_Obj *objPtr, double *valuePtr) -{ - const char* expr = Tcl_GetString(objPtr); - char 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; -} |