From ca63a61f80cd85fcfc861eb095d461ed1d56cb41 Mon Sep 17 00:00:00 2001 From: joye Date: Fri, 28 Mar 2014 15:53:33 +0000 Subject: *** empty log message *** --- bltGrMarkerBitmap.C | 80 +++-- bltGrMarkerBitmap.h | 7 +- configure | 1 + configure.in | 1 + src/bltGrMarker.C | 806 +--------------------------------------------- src/bltGrMarker.h | 65 +--- src/bltGrMarkerLine.C | 95 +++--- src/bltGrMarkerLine.h | 6 +- src/bltGrMarkerOp.C | 810 +++++++++++++++++++++++++++++++++++++++++++++++ src/bltGrMarkerOp.h | 60 ++++ src/bltGrMarkerPolygon.C | 132 ++++---- src/bltGrMarkerPolygon.h | 6 +- src/bltGrMarkerText.C | 88 +++-- src/bltGrMarkerText.h | 6 +- src/bltGraph.C | 2 +- 15 files changed, 1100 insertions(+), 1065 deletions(-) create mode 100644 src/bltGrMarkerOp.C create mode 100644 src/bltGrMarkerOp.h diff --git a/bltGrMarkerBitmap.C b/bltGrMarkerBitmap.C index 210b8a0..6c59f6f 100644 --- a/bltGrMarkerBitmap.C +++ b/bltGrMarkerBitmap.C @@ -27,8 +27,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltC.h" - extern "C" { #include "bltGraph.h" }; @@ -81,18 +79,14 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static MarkerClass bitmapMarkerClass = { - optionSpecs, -}; - -BitmapMarker::BitmapMarker(Graph* graphPtr, const char* name) - : Marker(graphPtr, name) +BitmapMarker::BitmapMarker(Graph* graphPtr, const char* name, + Tcl_HashEntry* hPtr) + : Marker(graphPtr, name, hPtr) { obj.classId = CID_MARKER_BITMAP; obj.className = dupstr("BitmapMarker"); - classPtr = &bitmapMarkerClass; - ops = (BitmapMarkerOptions*)calloc(1, sizeof(BitmapMarkerOptions)); - optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + ops_ = (BitmapMarkerOptions*)calloc(1, sizeof(BitmapMarkerOptions)); + optionTable_ = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); anchorPt.x =0; anchorPt.y =0; @@ -116,26 +110,26 @@ BitmapMarker::~BitmapMarker() int BitmapMarker::configure() { Graph* graphPtr = obj.graphPtr; - BitmapMarkerOptions* opp = (BitmapMarkerOptions*)ops; + BitmapMarkerOptions* ops = (BitmapMarkerOptions*)ops_; - if (opp->bitmap == None) + if (ops->bitmap == None) return TCL_OK; XGCValues gcValues; unsigned long gcMask = 0; - if (opp->outlineColor) { + if (ops->outlineColor) { gcMask |= GCForeground; - gcValues.foreground = opp->outlineColor->pixel; + gcValues.foreground = ops->outlineColor->pixel; } - if (opp->fillColor) { + if (ops->fillColor) { // Opaque bitmap: both foreground and background (fill) colors are used - gcValues.background = opp->fillColor->pixel; + gcValues.background = ops->fillColor->pixel; gcMask |= GCBackground; } else { // Transparent bitmap: set the clip mask to the current bitmap - gcValues.clip_mask = opp->bitmap; + gcValues.clip_mask = ops->bitmap; gcMask |= GCClipMask; } @@ -149,8 +143,8 @@ int BitmapMarker::configure() gc = newGC; // Create the background GC containing the fill color - if (opp->fillColor) { - gcValues.foreground = opp->fillColor->pixel; + if (ops->fillColor) { + gcValues.foreground = ops->fillColor->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); if (fillGC) Tk_FreeGC(graphPtr->display, fillGC); @@ -163,52 +157,52 @@ int BitmapMarker::configure() void BitmapMarker::draw(Drawable drawable) { Graph* graphPtr = obj.graphPtr; - BitmapMarkerOptions* opp = (BitmapMarkerOptions*)ops; + BitmapMarkerOptions* ops = (BitmapMarkerOptions*)ops_; - if ((opp->bitmap == None) || (width < 1) || (height < 1)) + if ((ops->bitmap == None) || (width < 1) || (height < 1)) return; - if (opp->fillColor == NULL) { - XSetClipMask(graphPtr->display, gc, opp->bitmap); + if (ops->fillColor == NULL) { + XSetClipMask(graphPtr->display, gc, ops->bitmap); XSetClipOrigin(graphPtr->display, gc, anchorPt.x, anchorPt.y); } else { XSetClipMask(graphPtr->display, gc, None); XSetClipOrigin(graphPtr->display, gc, 0, 0); } - XCopyPlane(graphPtr->display, opp->bitmap, drawable, gc, 0, 0, + XCopyPlane(graphPtr->display, ops->bitmap, drawable, gc, 0, 0, width, height, anchorPt.x, anchorPt.y, 1); } void BitmapMarker::map() { Graph* graphPtr = obj.graphPtr; - BitmapMarkerOptions* opp = (BitmapMarkerOptions*)ops; + BitmapMarkerOptions* ops = (BitmapMarkerOptions*)ops_; - if (opp->bitmap == None) + if (ops->bitmap == None) return; - if (!opp->worldPts || (opp->worldPts->num < 1)) + if (!ops->worldPts || (ops->worldPts->num < 1)) return; int lwidth; int lheight; - Tk_SizeOfBitmap(graphPtr->display, opp->bitmap, &lwidth, &lheight); + Tk_SizeOfBitmap(graphPtr->display, ops->bitmap, &lwidth, &lheight); - Point2d lanchorPt = mapPoint(opp->worldPts->points, &opp->axes); + Point2d lanchorPt = mapPoint(ops->worldPts->points, &ops->axes); lanchorPt = - Blt_AnchorPoint(lanchorPt.x, lanchorPt.y, lwidth, lheight, opp->anchor); - lanchorPt.x += opp->xOffset; - lanchorPt.y += opp->yOffset; + Blt_AnchorPoint(lanchorPt.x, lanchorPt.y, lwidth, lheight, ops->anchor); + lanchorPt.x += ops->xOffset; + lanchorPt.y += ops->yOffset; Region2d extents; extents.left = lanchorPt.x; extents.top = lanchorPt.y; extents.right = lanchorPt.x + lwidth - 1; extents.bottom = lanchorPt.y + lheight - 1; - clipped = boxesDontOverlap(graphPtr, &extents); + clipped_ = boxesDontOverlap(graphPtr, &extents); - if (clipped) + if (clipped_) return; width = lwidth; @@ -241,9 +235,9 @@ void BitmapMarker::map() int BitmapMarker::pointIn(Point2d *samplePtr) { - BitmapMarkerOptions* opp = (BitmapMarkerOptions*)ops; + BitmapMarkerOptions* ops = (BitmapMarkerOptions*)ops_; - if (opp->bitmap == None) + if (ops->bitmap == None) return 0; return ((samplePtr->x >= anchorPt.x) && @@ -270,21 +264,21 @@ int BitmapMarker::regionIn(Region2d *extsPtr, int enclosed) void BitmapMarker::postscript(Blt_Ps ps) { Graph* graphPtr = obj.graphPtr; - BitmapMarkerOptions* opp = (BitmapMarkerOptions*)ops; + BitmapMarkerOptions* ops = (BitmapMarkerOptions*)ops_; - if ((opp->bitmap == None) || (width < 1) || (height < 1)) + if ((ops->bitmap == None) || (width < 1) || (height < 1)) return; - if (opp->fillColor) { - Blt_Ps_XSetBackground(ps, opp->fillColor); + if (ops->fillColor) { + Blt_Ps_XSetBackground(ps, ops->fillColor); Blt_Ps_XFillPolygon(ps, outline, 4); } - Blt_Ps_XSetForeground(ps, opp->outlineColor); + Blt_Ps_XSetForeground(ps, ops->outlineColor); Blt_Ps_Format(ps, " gsave\n %g %g translate\n %d %d scale\n", anchorPt.x, anchorPt.y + height, width, -height); Blt_Ps_Format(ps, " %d %d true [%d 0 0 %d 0 %d] {", width, height, width, -height, height); - Blt_Ps_XSetBitmapData(ps, graphPtr->display, opp->bitmap, width, height); + Blt_Ps_XSetBitmapData(ps, graphPtr->display, ops->bitmap, width, height); Blt_Ps_VarAppend(ps, " } imagemask\n", "grestore\n", (char*)NULL); } diff --git a/bltGrMarkerBitmap.h b/bltGrMarkerBitmap.h index 7f56f4f..fbe4564 100644 --- a/bltGrMarkerBitmap.h +++ b/bltGrMarkerBitmap.h @@ -27,10 +27,11 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _BLT_GR_MARKER_BITMAP_H -#define _BLT_GR_MARKER_BITMAP_H +#ifndef __bltgrmarkerbitmap_h__ +#define __bltgrmarkerbitmap_h__ #include "bltGrMarker.h" +#define MAX_OUTLINE_POINTS 12 namespace Blt { @@ -70,7 +71,7 @@ class BitmapMarker : public Marker { void postscript(Blt_Ps); public: - BitmapMarker(Graph*, const char*); + BitmapMarker(Graph*, const char*, Tcl_HashEntry*); virtual ~BitmapMarker(); }; diff --git a/configure b/configure index d8fed61..7e8c5bb 100755 --- a/configure +++ b/configure @@ -5538,6 +5538,7 @@ done bltGrMarker.C bltGrMarkerBitmap.C bltGrMarkerLine.C + bltGrMarkerOp.C bltGrMarkerPolygon.C bltGrMarkerText.C bltGrMisc.C diff --git a/configure.in b/configure.in index 7b550dc..f7f5fc3 100755 --- a/configure.in +++ b/configure.in @@ -83,6 +83,7 @@ TEA_ADD_SOURCES([ bltGrMarker.C bltGrMarkerBitmap.C bltGrMarkerLine.C + bltGrMarkerOp.C bltGrMarkerPolygon.C bltGrMarkerText.C bltGrMisc.C 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; iix = 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; iix); - 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; iitkwin), "\"", 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; iiobj.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; -} diff --git a/src/bltGrMarker.h b/src/bltGrMarker.h index 97e0b4e..50f0660 100644 --- a/src/bltGrMarker.h +++ b/src/bltGrMarker.h @@ -27,57 +27,30 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _BLT_GR_MARKER_H -#define _BLT_GR_MARKER_H +#ifndef __bltgrmarker_h__ +#define __bltgrmarker_h__ -#define MAX_OUTLINE_POINTS 12 +#include "bltGrMarkerOp.h" -namespace Blt { - class Marker; - -typedef Marker* (MarkerCreateProc)(Graph*); -typedef void (MarkerDrawProc)(Marker* markerPtr, Drawable drawable); -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 { - Tk_OptionSpec *optionSpecs; -} MarkerClass; +#include +#include +#include +using namespace std; -typedef struct { - Point2d* points; - int num; -} Coords; - -typedef struct { - const char** tags; - Coords* worldPts; - const char* elemName; - Axis2d axes; - int hide; - int state; - int drawUnder; - int xOffset; - int yOffset; -} MarkerOptions; +namespace Blt { class Marker { protected: + int clipped_; + Tk_OptionTable optionTable_; + Tcl_HashEntry* hashPtr_; + void* ops_; public: GraphObj obj; - MarkerClass *classPtr; - Tk_OptionTable optionTable; - Tcl_HashEntry* hashPtr; Blt_ChainLink link; - int clipped; unsigned int flags; - void* ops; - private: double HMap(Axis*, double); double VMap(Axis*, double); @@ -87,7 +60,7 @@ typedef struct { int boxesDontOverlap(Graph*, Region2d*); public: - Marker(Graph*, const char*); + Marker(Graph*, const char*, Tcl_HashEntry*); virtual ~Marker(); virtual int configure() =0; @@ -96,16 +69,12 @@ typedef struct { virtual int pointIn(Point2d*) =0; virtual int regionIn(Region2d*, int) =0; virtual void postscript(Blt_Ps) =0; + + int clipped() {return clipped_;} + Tk_OptionTable optionTable() {return optionTable_;} + MarkerOptions* ops() {return (MarkerOptions*)ops_;} }; }; -void Blt_FreeMarker(char*); - -extern Tk_ObjCustomOption coordsObjOption; -extern Tk_ObjCustomOption capStyleObjOption; -extern Tk_ObjCustomOption joinStyleObjOption; -extern Tk_ObjCustomOption xAxisObjOption; -extern Tk_ObjCustomOption yAxisObjOption; - #endif diff --git a/src/bltGrMarkerLine.C b/src/bltGrMarkerLine.C index 68adb8f..a90d578 100644 --- a/src/bltGrMarkerLine.C +++ b/src/bltGrMarkerLine.C @@ -27,8 +27,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltC.h" - extern "C" { #include "bltGraph.h" }; @@ -87,19 +85,14 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static MarkerClass lineMarkerClass = { - optionSpecs, -}; - -LineMarker::LineMarker(Graph* graphPtr, const char* name) - : Marker(graphPtr, name) +LineMarker::LineMarker(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr) + : Marker(graphPtr, name, hPtr) { obj.classId = CID_MARKER_LINE; obj.className = dupstr("LineMarker"); - classPtr = &lineMarkerClass; - ops = (LineMarkerOptions*)calloc(1, sizeof(LineMarkerOptions)); - ((LineMarkerOptions*)ops)->xorr = FALSE; - optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + ops_ = (LineMarkerOptions*)calloc(1, sizeof(LineMarkerOptions)); + ((LineMarkerOptions*)ops_)->xorr = FALSE; + optionTable_ = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); gc =NULL; segments =NULL; @@ -120,28 +113,28 @@ LineMarker::~LineMarker() int LineMarker::configure() { Graph* graphPtr = obj.graphPtr; - LineMarkerOptions* opp = (LineMarkerOptions*)ops; + LineMarkerOptions* ops = (LineMarkerOptions*)ops_; Drawable drawable = Tk_WindowId(graphPtr->tkwin); unsigned long gcMask = (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle); XGCValues gcValues; - if (opp->outlineColor) { + if (ops->outlineColor) { gcMask |= GCForeground; - gcValues.foreground = opp->outlineColor->pixel; + gcValues.foreground = ops->outlineColor->pixel; } - if (opp->fillColor) { + if (ops->fillColor) { gcMask |= GCBackground; - gcValues.background = opp->fillColor->pixel; + gcValues.background = ops->fillColor->pixel; } - gcValues.cap_style = opp->capStyle; - gcValues.join_style = opp->joinStyle; - gcValues.line_width = LineWidth(opp->lineWidth); + gcValues.cap_style = ops->capStyle; + gcValues.join_style = ops->joinStyle; + gcValues.line_width = LineWidth(ops->lineWidth); gcValues.line_style = LineSolid; - if (LineIsDashed(opp->dashes)) { + if (LineIsDashed(ops->dashes)) { gcValues.line_style = (gcMask & GCBackground) ? LineDoubleDash : LineOnOffDash; } - if (opp->xorr) { + if (ops->xorr) { unsigned long pixel; gcValues.function = GXxor; @@ -159,11 +152,11 @@ int LineMarker::configure() if (gc) Blt_FreePrivateGC(graphPtr->display, gc); - if (LineIsDashed(opp->dashes)) - Blt_SetDashes(graphPtr->display, newGC, &opp->dashes); + if (LineIsDashed(ops->dashes)) + Blt_SetDashes(graphPtr->display, newGC, &ops->dashes); gc = newGC; - if (opp->xorr) { + if (ops->xorr) { if (drawable != None) { map(); draw(drawable); @@ -177,11 +170,11 @@ int LineMarker::configure() void LineMarker::draw(Drawable drawable) { Graph* graphPtr = obj.graphPtr; - LineMarkerOptions* opp = (LineMarkerOptions*)ops; + LineMarkerOptions* ops = (LineMarkerOptions*)ops_; if (nSegments > 0) { Blt_Draw2DSegments(graphPtr->display, drawable, gc, segments, nSegments); - if (opp->xorr) + if (ops->xorr) xorState = (xorState == 0); } } @@ -189,13 +182,13 @@ void LineMarker::draw(Drawable drawable) void LineMarker::map() { Graph* graphPtr = obj.graphPtr; - LineMarkerOptions* opp = (LineMarkerOptions*)ops; + LineMarkerOptions* ops = (LineMarkerOptions*)ops_; nSegments = 0; if (segments) free(segments); - if (!opp->worldPts || (opp->worldPts->num < 2)) + if (!ops->worldPts || (ops->worldPts->num < 2)) return; Region2d extents; @@ -205,19 +198,19 @@ void LineMarker::map() // as series of line segments, not one continous polyline. This is // because clipping against the plot area may chop the line into several // disconnected segments. - Segment2d* lsegments = (Segment2d*)malloc(opp->worldPts->num * sizeof(Segment2d)); - Point2d* srcPtr = opp->worldPts->points; - Point2d p = mapPoint(srcPtr, &opp->axes); - p.x += opp->xOffset; - p.y += opp->yOffset; + Segment2d* lsegments = (Segment2d*)malloc(ops->worldPts->num * sizeof(Segment2d)); + Point2d* srcPtr = ops->worldPts->points; + Point2d p = mapPoint(srcPtr, &ops->axes); + p.x += ops->xOffset; + p.y += ops->yOffset; Segment2d* segPtr = lsegments; Point2d* pend; - for (srcPtr++, pend = opp->worldPts->points + opp->worldPts->num; + for (srcPtr++, pend = ops->worldPts->points + ops->worldPts->num; srcPtr < pend; srcPtr++) { - Point2d next = mapPoint(srcPtr, &opp->axes); - next.x += opp->xOffset; - next.y += opp->yOffset; + Point2d next = mapPoint(srcPtr, &ops->axes); + next.x += ops->xOffset; + next.y += ops->yOffset; Point2d q = next; if (Blt_LineRectClip(&extents, &p, &q)) { @@ -229,7 +222,7 @@ void LineMarker::map() } nSegments = segPtr - lsegments; segments = lsegments; - clipped = (nSegments == 0); + clipped_ = (nSegments == 0); } int LineMarker::pointIn(Point2d *samplePtr) @@ -240,17 +233,17 @@ int LineMarker::pointIn(Point2d *samplePtr) int LineMarker::regionIn(Region2d *extsPtr, int enclosed) { - LineMarkerOptions* opp = (LineMarkerOptions*)ops; + LineMarkerOptions* ops = (LineMarkerOptions*)ops_; - if (!opp->worldPts || opp->worldPts->num < 2) + if (!ops->worldPts || ops->worldPts->num < 2) return FALSE; if (enclosed) { Point2d *pp, *pend; - for (pp = opp->worldPts->points, pend = pp + opp->worldPts->num; + for (pp = ops->worldPts->points, pend = pp + ops->worldPts->num; pp < pend; pp++) { - Point2d p = mapPoint(pp, &opp->axes); + Point2d p = mapPoint(pp, &ops->axes); if ((p.x < extsPtr->left) && (p.x > extsPtr->right) && (p.y < extsPtr->top) && (p.y > extsPtr->bottom)) { return FALSE; @@ -261,10 +254,10 @@ int LineMarker::regionIn(Region2d *extsPtr, int enclosed) else { Point2d *pp, *pend; int count = 0; - for (pp = opp->worldPts->points, pend = pp + (opp->worldPts->num - 1); + for (pp = ops->worldPts->points, pend = pp + (ops->worldPts->num - 1); pp < pend; pp++) { - Point2d p = mapPoint(pp, &opp->axes); - Point2d q = mapPoint(pp + 1, &opp->axes); + Point2d p = mapPoint(pp, &ops->axes); + Point2d q = mapPoint(pp + 1, &ops->axes); if (Blt_LineRectClip(extsPtr, &p, &q)) count++; } @@ -275,14 +268,14 @@ int LineMarker::regionIn(Region2d *extsPtr, int enclosed) void LineMarker::postscript(Blt_Ps ps) { - LineMarkerOptions* opp = (LineMarkerOptions*)ops; + LineMarkerOptions* ops = (LineMarkerOptions*)ops_; if (nSegments > 0) { - Blt_Ps_XSetLineAttributes(ps, opp->outlineColor, opp->lineWidth, - &opp->dashes, opp->capStyle, opp->joinStyle); - if ((LineIsDashed(opp->dashes)) && (opp->fillColor)) { + Blt_Ps_XSetLineAttributes(ps, ops->outlineColor, ops->lineWidth, + &ops->dashes, ops->capStyle, ops->joinStyle); + if ((LineIsDashed(ops->dashes)) && (ops->fillColor)) { Blt_Ps_Append(ps, "/DashesProc {\n gsave\n "); - Blt_Ps_XSetBackground(ps, opp->fillColor); + Blt_Ps_XSetBackground(ps, ops->fillColor); Blt_Ps_Append(ps, " "); Blt_Ps_XSetDashes(ps, (Blt_Dashes*)NULL); Blt_Ps_VarAppend(ps, "stroke\n", " grestore\n", "} def\n", (char*)NULL); diff --git a/src/bltGrMarkerLine.h b/src/bltGrMarkerLine.h index dd18191..a876cb9 100644 --- a/src/bltGrMarkerLine.h +++ b/src/bltGrMarkerLine.h @@ -27,8 +27,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _BLT_GR_MARKER_LINE_H -#define _BLT_GR_MARKER_LINE_H +#ifndef __bltgrmarkerline_h__ +#define __bltgrmarkerline_h__ #include "bltGrMarker.h" @@ -70,7 +70,7 @@ class LineMarker : public Marker { void postscript(Blt_Ps); public: - LineMarker(Graph*, const char*); + LineMarker(Graph*, const char*, Tcl_HashEntry*); virtual ~LineMarker(); }; diff --git a/src/bltGrMarkerOp.C b/src/bltGrMarkerOp.C new file mode 100644 index 0000000..6f42f8b --- /dev/null +++ b/src/bltGrMarkerOp.C @@ -0,0 +1,810 @@ +/* + * Smithsonian Astrophysical Observatory, Cambridge, MA, USA + * This code has been modified under the terms listed below and is made + * available under the same terms. + */ + +/* + * Copyright 1993-2004 George A Howlett. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "bltC.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; + +// Defs + +void Blt_FreeMarker(char* dataPtr); +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; iix = 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; iix); + 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, hPtr); + else if (!strcmp(type, "line")) + markerPtr = new LineMarker(graphPtr, name, hPtr); + else if (!strcmp(type, "polygon")) + markerPtr = new PolygonMarker(graphPtr, name, hPtr); + else if (!strcmp(type, "text")) + markerPtr = new TextMarker(graphPtr, name, hPtr); + else { + Tcl_AppendResult(interp, "unknown marker type ", type, NULL); + return TCL_ERROR; + } + + 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; iitkwin), "\"", 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 = 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; iiobj.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 = 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 = 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 = 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 = 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 = 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. + 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 = 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; +} diff --git a/src/bltGrMarkerOp.h b/src/bltGrMarkerOp.h new file mode 100644 index 0000000..825d125 --- /dev/null +++ b/src/bltGrMarkerOp.h @@ -0,0 +1,60 @@ +/* + * Smithsonian Astrophysical Observatory, Cambridge, MA, USA + * This code has been modified under the terms listed below and is made + * available under the same terms. + */ + +/* + * Copyright 1993-2004 George A Howlett. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __blt_grmarkerop_h__ +#define __blt_grmarkerop_h__ + +namespace Blt { + +typedef struct { + Point2d* points; + int num; +} Coords; + +typedef struct { + const char** tags; + Coords* worldPts; + const char* elemName; + Axis2d axes; + int hide; + int state; + int drawUnder; + int xOffset; + int yOffset; +} MarkerOptions; + +}; + +extern Tk_ObjCustomOption coordsObjOption; +extern Tk_ObjCustomOption capStyleObjOption; +extern Tk_ObjCustomOption joinStyleObjOption; +extern Tk_ObjCustomOption xAxisObjOption; +extern Tk_ObjCustomOption yAxisObjOption; + +#endif diff --git a/src/bltGrMarkerPolygon.C b/src/bltGrMarkerPolygon.C index 026457f..e8c0cb4 100644 --- a/src/bltGrMarkerPolygon.C +++ b/src/bltGrMarkerPolygon.C @@ -27,8 +27,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltC.h" - extern "C" { #include "bltGraph.h" }; @@ -95,18 +93,14 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static MarkerClass polygonMarkerClass = { - optionSpecs, -}; - -PolygonMarker::PolygonMarker(Graph* graphPtr, const char* name) - : Marker(graphPtr, name) +PolygonMarker::PolygonMarker(Graph* graphPtr, const char* name, + Tcl_HashEntry* hPtr) + : Marker(graphPtr, name, hPtr) { obj.classId = CID_MARKER_POLYGON; obj.className = dupstr("PolygonMarker"); - classPtr = &polygonMarkerClass; - ops = (PolygonMarkerOptions*)calloc(1, sizeof(PolygonMarkerOptions)); - optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + ops_ = (PolygonMarkerOptions*)calloc(1, sizeof(PolygonMarkerOptions)); + optionTable_ = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); screenPts =NULL; outlineGC =NULL; @@ -137,7 +131,7 @@ PolygonMarker::~PolygonMarker() int PolygonMarker::configure() { Graph* graphPtr = obj.graphPtr; - PolygonMarkerOptions* opp = (PolygonMarkerOptions*)ops; + PolygonMarkerOptions* ops = (PolygonMarkerOptions*)ops_; GC newGC; XGCValues gcValues; @@ -146,25 +140,25 @@ int PolygonMarker::configure() drawable = Tk_WindowId(graphPtr->tkwin); gcMask = (GCLineWidth | GCLineStyle); - if (opp->outline) { + if (ops->outline) { gcMask |= GCForeground; - gcValues.foreground = opp->outline->pixel; + gcValues.foreground = ops->outline->pixel; } - if (opp->outlineBg) { + if (ops->outlineBg) { gcMask |= GCBackground; - gcValues.background = opp->outlineBg->pixel; + gcValues.background = ops->outlineBg->pixel; } gcMask |= (GCCapStyle | GCJoinStyle); - gcValues.cap_style = opp->capStyle; - gcValues.join_style = opp->joinStyle; + gcValues.cap_style = ops->capStyle; + gcValues.join_style = ops->joinStyle; gcValues.line_style = LineSolid; gcValues.dash_offset = 0; - gcValues.line_width = LineWidth(opp->lineWidth); - if (LineIsDashed(opp->dashes)) { - gcValues.line_style = (opp->outlineBg == NULL) + gcValues.line_width = LineWidth(ops->lineWidth); + if (LineIsDashed(ops->dashes)) { + gcValues.line_style = (ops->outlineBg == NULL) ? LineOnOffDash : LineDoubleDash; } - if (opp->xorr) { + if (ops->xorr) { unsigned long pixel; gcValues.function = GXxor; @@ -179,8 +173,8 @@ int PolygonMarker::configure() } } newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); - if (LineIsDashed(opp->dashes)) { - Blt_SetDashes(graphPtr->display, newGC, &opp->dashes); + if (LineIsDashed(ops->dashes)) { + Blt_SetDashes(graphPtr->display, newGC, &ops->dashes); } if (outlineGC) { Blt_FreePrivateGC(graphPtr->display, outlineGC); @@ -188,17 +182,17 @@ int PolygonMarker::configure() outlineGC = newGC; gcMask = 0; - if (opp->fill) { + if (ops->fill) { gcMask |= GCForeground; - gcValues.foreground = opp->fill->pixel; + gcValues.foreground = ops->fill->pixel; } - if (opp->fillBg) { + if (ops->fillBg) { gcMask |= GCBackground; - gcValues.background = opp->fillBg->pixel; + gcValues.background = ops->fillBg->pixel; } - if (opp->stipple != None) { - gcValues.stipple = opp->stipple; - gcValues.fill_style = (opp->fillBg) + if (ops->stipple != None) { + gcValues.stipple = ops->stipple; + gcValues.fill_style = (ops->fillBg) ? FillOpaqueStippled : FillStippled; gcMask |= (GCStipple | GCFillStyle); } @@ -208,7 +202,7 @@ int PolygonMarker::configure() } fillGC = newGC; - if ((gcMask == 0) && !(graphPtr->flags & RESET_AXES) && (opp->xorr)) { + if ((gcMask == 0) && !(graphPtr->flags & RESET_AXES) && (ops->xorr)) { if (drawable != None) { map(); draw(drawable); @@ -222,10 +216,10 @@ int PolygonMarker::configure() void PolygonMarker::draw(Drawable drawable) { Graph* graphPtr = obj.graphPtr; - PolygonMarkerOptions* opp = (PolygonMarkerOptions*)ops; + PolygonMarkerOptions* ops = (PolygonMarkerOptions*)ops_; // fill region - if ((nFillPts > 0) && (opp->fill)) { + if ((nFillPts > 0) && (ops->fill)) { XPoint* points = (XPoint*)malloc(nFillPts * sizeof(XPoint)); if (!points) return; @@ -244,8 +238,8 @@ void PolygonMarker::draw(Drawable drawable) } // outline - if ((nOutlinePts > 0) && (opp->lineWidth > 0) && - (opp->outline)) { + if ((nOutlinePts > 0) && (ops->lineWidth > 0) && + (ops->outline)) { Blt_Draw2DSegments(graphPtr->display, drawable, outlineGC, outlinePts, nOutlinePts); } @@ -254,7 +248,7 @@ void PolygonMarker::draw(Drawable drawable) void PolygonMarker::map() { Graph* graphPtr = obj.graphPtr; - PolygonMarkerOptions* opp = (PolygonMarkerOptions*)ops; + PolygonMarkerOptions* ops = (PolygonMarkerOptions*)ops_; if (outlinePts) { free(outlinePts); @@ -273,43 +267,43 @@ void PolygonMarker::map() screenPts = NULL; } - if (!opp->worldPts || opp->worldPts->num < 3) + if (!ops->worldPts || ops->worldPts->num < 3) return; // Allocate and fill a temporary array to hold the screen coordinates of // the polygon. - int nScreenPts = opp->worldPts->num + 1; + int nScreenPts = ops->worldPts->num + 1; Point2d* lscreenPts = (Point2d*)malloc((nScreenPts + 1) * sizeof(Point2d)); { Point2d *sp, *dp, *send; dp = lscreenPts; - for (sp = opp->worldPts->points, send = sp + opp->worldPts->num; + for (sp = ops->worldPts->points, send = sp + ops->worldPts->num; sp < send; sp++) { - *dp = mapPoint(sp, &opp->axes); - dp->x += opp->xOffset; - dp->y += opp->yOffset; + *dp = mapPoint(sp, &ops->axes); + dp->x += ops->xOffset; + dp->y += ops->yOffset; dp++; } *dp = lscreenPts[0]; } Region2d extents; Blt_GraphExtents(graphPtr, &extents); - clipped = TRUE; - if (opp->fill) { + clipped_ = TRUE; + if (ops->fill) { Point2d* lfillPts = (Point2d*)malloc(sizeof(Point2d) * nScreenPts * 3); int n = - Blt_PolyRectClip(&extents, lscreenPts, opp->worldPts->num,lfillPts); + Blt_PolyRectClip(&extents, lscreenPts, ops->worldPts->num,lfillPts); if (n < 3) free(lfillPts); else { nFillPts = n; fillPts = lfillPts; - clipped = FALSE; + clipped_ = FALSE; } } - if ((opp->outline) && (opp->lineWidth > 0)) { + if ((ops->outline) && (ops->lineWidth > 0)) { Segment2d *segPtr; Point2d *sp, *send; @@ -334,7 +328,7 @@ void PolygonMarker::map() nOutlinePts = segPtr - loutlinePts; outlinePts = loutlinePts; if (nOutlinePts > 0) { - clipped = FALSE; + clipped_ = FALSE; } } @@ -343,26 +337,26 @@ void PolygonMarker::map() int PolygonMarker::pointIn(Point2d *samplePtr) { - PolygonMarkerOptions* opp = (PolygonMarkerOptions*)ops; + PolygonMarkerOptions* ops = (PolygonMarkerOptions*)ops_; - if (opp->worldPts && - (opp->worldPts->num >= 3) && + if (ops->worldPts && + (ops->worldPts->num >= 3) && (screenPts)) return Blt_PointInPolygon(samplePtr, screenPts, - opp->worldPts->num + 1); + ops->worldPts->num + 1); return FALSE; } int PolygonMarker::regionIn(Region2d *extsPtr, int enclosed) { - PolygonMarkerOptions* opp = (PolygonMarkerOptions*)ops; + PolygonMarkerOptions* ops = (PolygonMarkerOptions*)ops_; - if (opp->worldPts && - (opp->worldPts->num >= 3) && + if (ops->worldPts && + (ops->worldPts->num >= 3) && (screenPts)) return Blt_RegionInPolygon(extsPtr, screenPts, - opp->worldPts->num, enclosed); + ops->worldPts->num, enclosed); return FALSE; } @@ -370,30 +364,30 @@ int PolygonMarker::regionIn(Region2d *extsPtr, int enclosed) void PolygonMarker::postscript(Blt_Ps ps) { Graph* graphPtr = obj.graphPtr; - PolygonMarkerOptions* opp = (PolygonMarkerOptions*)ops; + PolygonMarkerOptions* ops = (PolygonMarkerOptions*)ops_; - if (opp->fill) { + if (ops->fill) { Blt_Ps_Polyline(ps, fillPts, nFillPts); - if (opp->fillBg) { - Blt_Ps_XSetBackground(ps, opp->fillBg); + if (ops->fillBg) { + Blt_Ps_XSetBackground(ps, ops->fillBg); Blt_Ps_Append(ps, "gsave fill grestore\n"); } - Blt_Ps_XSetForeground(ps, opp->fill); - if (opp->stipple != None) { - Blt_Ps_XSetStipple(ps, graphPtr->display, opp->stipple); + Blt_Ps_XSetForeground(ps, ops->fill); + if (ops->stipple != None) { + Blt_Ps_XSetStipple(ps, graphPtr->display, ops->stipple); } else { Blt_Ps_Append(ps, "fill\n"); } } - if ((opp->lineWidth > 0) && (opp->outline)) { + if ((ops->lineWidth > 0) && (ops->outline)) { - Blt_Ps_XSetLineAttributes(ps, opp->outline, opp->lineWidth, &opp->dashes, - opp->capStyle, opp->joinStyle); + Blt_Ps_XSetLineAttributes(ps, ops->outline, ops->lineWidth, &ops->dashes, + ops->capStyle, ops->joinStyle); - if ((opp->outlineBg) && (LineIsDashed(opp->dashes))) { + if ((ops->outlineBg) && (LineIsDashed(ops->dashes))) { Blt_Ps_Append(ps, "/DashesProc {\ngsave\n "); - Blt_Ps_XSetBackground(ps, opp->outlineBg); + Blt_Ps_XSetBackground(ps, ops->outlineBg); Blt_Ps_Append(ps, " "); Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); Blt_Ps_Append(ps, "stroke\n grestore\n} def\n"); diff --git a/src/bltGrMarkerPolygon.h b/src/bltGrMarkerPolygon.h index f9bd6f4..0b9eaee 100644 --- a/src/bltGrMarkerPolygon.h +++ b/src/bltGrMarkerPolygon.h @@ -27,8 +27,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _BLT_GR_MARKER_POLYGON_H -#define _BLT_GR_MARKER_POLYGON_H +#ifndef __bltgrmarkerpolygon_h__ +#define __bltgrmarkerpolygon_h__ #include "bltGrMarker.h" @@ -77,7 +77,7 @@ class PolygonMarker : public Marker { void postscript(Blt_Ps); public: - PolygonMarker(Graph*, const char*); + PolygonMarker(Graph*, const char*, Tcl_HashEntry*); virtual ~PolygonMarker(); }; diff --git a/src/bltGrMarkerText.C b/src/bltGrMarkerText.C index 03d541a..94bae34 100644 --- a/src/bltGrMarkerText.C +++ b/src/bltGrMarkerText.C @@ -27,9 +27,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltC.h" -#include "bltMath.h" - extern "C" { #include "bltGraph.h" }; @@ -85,19 +82,14 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static MarkerClass textMarkerClass = { - optionSpecs, -}; - -TextMarker::TextMarker(Graph* graphPtr, const char* name) - : Marker(graphPtr, name) +TextMarker::TextMarker(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr) + : Marker(graphPtr, name, hPtr) { obj.classId = CID_MARKER_TEXT; obj.className = dupstr("TextMarker"); - classPtr = &textMarkerClass; - ops = (TextMarkerOptions*)calloc(1, sizeof(TextMarkerOptions)); - Blt_Ts_InitStyle(((TextMarkerOptions*)ops)->style); - optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + ops_ = (TextMarkerOptions*)calloc(1, sizeof(TextMarkerOptions)); + Blt_Ts_InitStyle(((TextMarkerOptions*)ops_)->style); + optionTable_ = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); anchorPt.x =0; anchorPt.y =0; @@ -110,24 +102,24 @@ TextMarker::~TextMarker() { Graph* graphPtr = obj.graphPtr; - Blt_Ts_FreeStyle(graphPtr->display, &((TextMarkerOptions*)ops)->style); + Blt_Ts_FreeStyle(graphPtr->display, &((TextMarkerOptions*)ops_)->style); } int TextMarker::configure() { Graph* graphPtr = obj.graphPtr; - TextMarkerOptions* opp = (TextMarkerOptions*)ops; + TextMarkerOptions* ops = (TextMarkerOptions*)ops_; - opp->style.angle = (float)fmod(opp->style.angle, 360.0); - if (opp->style.angle < 0.0f) - opp->style.angle += 360.0f; + ops->style.angle = (float)fmod(ops->style.angle, 360.0); + if (ops->style.angle < 0.0f) + ops->style.angle += 360.0f; GC newGC = NULL; XGCValues gcValues; unsigned long gcMask; - if (opp->fillColor) { + if (ops->fillColor) { gcMask = GCForeground; - gcValues.foreground = opp->fillColor->pixel; + gcValues.foreground = ops->fillColor->pixel; newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues); } if (fillGC) @@ -140,9 +132,9 @@ int TextMarker::configure() void TextMarker::draw(Drawable drawable) { Graph* graphPtr = obj.graphPtr; - TextMarkerOptions* opp = (TextMarkerOptions*)ops; + TextMarkerOptions* ops = (TextMarkerOptions*)ops_; - if (!opp->string) + if (!ops->string) return; if (fillGC) { @@ -158,20 +150,20 @@ void TextMarker::draw(Drawable drawable) } // be sure to update style->gc, things might have changed - opp->style.flags |= UPDATE_GC; - Blt_Ts_DrawText(graphPtr->tkwin, drawable, opp->string, -1, - &opp->style, anchorPt.x, anchorPt.y); + ops->style.flags |= UPDATE_GC; + Blt_Ts_DrawText(graphPtr->tkwin, drawable, ops->string, -1, + &ops->style, anchorPt.x, anchorPt.y); } void TextMarker::map() { Graph* graphPtr = obj.graphPtr; - TextMarkerOptions* opp = (TextMarkerOptions*)ops; + TextMarkerOptions* ops = (TextMarkerOptions*)ops_; - if (!opp->string) + if (!ops->string) return; - if (!opp->worldPts || (opp->worldPts->num < 1)) + if (!ops->worldPts || (ops->worldPts->num < 1)) return; width =0; @@ -179,44 +171,44 @@ void TextMarker::map() unsigned int w; unsigned int h; - Blt_Ts_GetExtents(&opp->style, opp->string, &w, &h); + Blt_Ts_GetExtents(&ops->style, ops->string, &w, &h); double rw; double rh; - Blt_GetBoundingBox(w, h, opp->style.angle, &rw, &rh, outline); - width = ROUND(rw); - height = ROUND(rh); + Blt_GetBoundingBox(w, h, ops->style.angle, &rw, &rh, outline); + width = rw; + height = rh; for (int ii=0; ii<4; ii++) { - outline[ii].x += ROUND(rw * 0.5); - outline[ii].y += ROUND(rh * 0.5); + outline[ii].x += rw * 0.5; + outline[ii].y += rh * 0.5; } outline[4].x = outline[0].x; outline[4].y = outline[0].y; - Point2d lanchorPtr = mapPoint(opp->worldPts->points, &opp->axes); + Point2d lanchorPtr = mapPoint(ops->worldPts->points, &ops->axes); lanchorPtr = Blt_AnchorPoint(lanchorPtr.x, lanchorPtr.y, width, - height, opp->anchor); - lanchorPtr.x += opp->xOffset; - lanchorPtr.y += opp->yOffset; + height, ops->anchor); + lanchorPtr.x += ops->xOffset; + lanchorPtr.y += ops->yOffset; Region2d extents; extents.left = lanchorPtr.x; extents.top = lanchorPtr.y; extents.right = lanchorPtr.x + width - 1; extents.bottom = lanchorPtr.y + height - 1; - clipped = boxesDontOverlap(graphPtr, &extents); + clipped_ = boxesDontOverlap(graphPtr, &extents); anchorPt = lanchorPtr; } int TextMarker::pointIn(Point2d *samplePtr) { - TextMarkerOptions* opp = (TextMarkerOptions*)ops; + TextMarkerOptions* ops = (TextMarkerOptions*)ops_; - if (!opp->string) + if (!ops->string) return 0; - if (opp->style.angle != 0.0f) { + if (ops->style.angle != 0.0f) { Point2d points[5]; // Figure out the bounding polygon (isolateral) for the text and see @@ -236,9 +228,9 @@ int TextMarker::pointIn(Point2d *samplePtr) int TextMarker::regionIn(Region2d *extsPtr, int enclosed) { - TextMarkerOptions* opp = (TextMarkerOptions*)ops; + TextMarkerOptions* ops = (TextMarkerOptions*)ops_; - if (opp->style.angle != 0.0f) { + if (ops->style.angle != 0.0f) { // Generate the bounding polygon (isolateral) for the bitmap and see // if the point is inside of it. Point2d points[5]; @@ -263,9 +255,9 @@ int TextMarker::regionIn(Region2d *extsPtr, int enclosed) void TextMarker::postscript(Blt_Ps ps) { - TextMarkerOptions* opp = (TextMarkerOptions*)ops; + TextMarkerOptions* ops = (TextMarkerOptions*)ops_; - if (!opp->string) + if (!ops->string) return; if (fillGC) { @@ -276,9 +268,9 @@ void TextMarker::postscript(Blt_Ps ps) points[ii].x = outline[ii].x + anchorPt.x; points[ii].y = outline[ii].y + anchorPt.y; } - Blt_Ps_XSetBackground(ps, opp->fillColor); + Blt_Ps_XSetBackground(ps, ops->fillColor); Blt_Ps_XFillPolygon(ps, points, 4); } - Blt_Ps_DrawText(ps, opp->string, &opp->style, anchorPt.x, anchorPt.y); + Blt_Ps_DrawText(ps, ops->string, &ops->style, anchorPt.x, anchorPt.y); } diff --git a/src/bltGrMarkerText.h b/src/bltGrMarkerText.h index 979518e..ea8bfcc 100644 --- a/src/bltGrMarkerText.h +++ b/src/bltGrMarkerText.h @@ -27,8 +27,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _BLT_GR_MARKER_TEXT_H -#define _BLT_GR_MARKER_TEXT_H +#ifndef __bltgrmarkertext_h__ +#define __bltgrmarkertext_h__ #include "bltGrMarker.h" @@ -68,7 +68,7 @@ class TextMarker : public Marker { void postscript(Blt_Ps); public: - TextMarker(Graph*, const char*); + TextMarker(Graph*, const char*, Tcl_HashEntry*); virtual ~TextMarker(); }; diff --git a/src/bltGraph.C b/src/bltGraph.C index f959994..a189fa0 100644 --- a/src/bltGraph.C +++ b/src/bltGraph.C @@ -986,7 +986,7 @@ void Blt_GraphTags(Blt_BindTable table, ClientData object, ClientData context, case CID_MARKER_WINDOW: { Marker* markerPtr = (Marker*)object; - MarkerOptions* ops = (MarkerOptions*)markerPtr->ops; + MarkerOptions* ops = markerPtr->ops(); MakeTagProc* tagProc = Blt_MakeMarkerTag; Blt_List_Append(list, (const char*)(*tagProc)(graphPtr, markerPtr->obj.name), 0); Blt_List_Append(list, (const char*)(*tagProc)(graphPtr, markerPtr->obj.className), 0); -- cgit v0.12