diff options
-rw-r--r-- | bltGrMarkerBitmap.C | 7 | ||||
-rwxr-xr-x | configure | 1 | ||||
-rwxr-xr-x | configure.in | 1 | ||||
-rw-r--r-- | src/bltGrMarker.C | 357 | ||||
-rw-r--r-- | src/bltGrMarkerLine.C | 324 | ||||
-rw-r--r-- | src/bltGrMarkerLine.h | 96 |
6 files changed, 425 insertions, 361 deletions
diff --git a/bltGrMarkerBitmap.C b/bltGrMarkerBitmap.C index 4976a8d..a560ae7 100644 --- a/bltGrMarkerBitmap.C +++ b/bltGrMarkerBitmap.C @@ -27,13 +27,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltInt.h" -#include "bltMath.h" #include "bltGraph.h" -#include "bltOp.h" -#include "bltGrElem.h" #include "bltBitmap.h" -#include "bltConfig.h" #include "bltGrMarkerBitmap.h" #define GETBITMAP(b) (((b)->destBitmap == None) ? (b)->srcBitmap : (b)->destBitmap) @@ -84,8 +79,8 @@ static Blt_ConfigSpec bitmapConfigSpecs[] = { {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} }; -static MarkerConfigProc ConfigureBitmapProc; MarkerCreateProc Blt_CreateBitmapProc; +static MarkerConfigProc ConfigureBitmapProc; static MarkerDrawProc DrawBitmapProc; static MarkerFreeProc FreeBitmapProc; static MarkerMapProc MapBitmapProc; @@ -5538,6 +5538,7 @@ done bltGrLine.c bltGrMarker.c bltGrMarkerBitmap.c + bltGrMarkerLine.c bltGrMisc.c bltGrPen.c bltGrPs.c diff --git a/configure.in b/configure.in index bdbe39a..e5cd63f 100755 --- a/configure.in +++ b/configure.in @@ -83,6 +83,7 @@ TEA_ADD_SOURCES([ bltGrLine.c bltGrMarker.c bltGrMarkerBitmap.c + bltGrMarkerLine.c bltGrMisc.c bltGrPen.c bltGrPs.c diff --git a/src/bltGrMarker.C b/src/bltGrMarker.C index 816637b..f0ed514 100644 --- a/src/bltGrMarker.C +++ b/src/bltGrMarker.C @@ -27,15 +27,14 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "bltInt.h" #include "bltMath.h" #include "bltGraph.h" #include "bltOp.h" #include "bltGrElem.h" -#include "bltBitmap.h" #include "bltConfig.h" #include "bltGrMarker.h" #include "bltGrMarkerBitmap.h" +#include "bltGrMarkerLine.h" typedef int (GraphMarkerProc)(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]); @@ -97,131 +96,6 @@ typedef struct { int state; - XColor* fillColor; - XColor* outlineColor; /* Foreground and background colors */ - - int lineWidth; /* Line width. */ - int capStyle; /* Cap style. */ - int joinStyle; /* Join style.*/ - Blt_Dashes dashes; /* Dash list values (max 11) */ - - GC gc; /* Private graphic context */ - - Segment2d *segments; /* Malloc'ed array of points. - * Represents individual line segments - * (2 points per segment) comprising the - * mapped line. The segments may not - * necessarily be connected after - * clipping. */ - int nSegments; /* # segments in the above array. */ - int xor; - int xorState; /* State of the XOR drawing. Indicates - * if the marker is currently drawn. */ -} LineMarker; - -static Blt_ConfigSpec lineConfigSpecs[] = { - {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Line all", - Tk_Offset(LineMarker, obj.tags), BLT_CONFIG_NULL_OK, - &listOption}, - {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", "butt", - Tk_Offset(LineMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL, - Tk_Offset(LineMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, - {BLT_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes", NULL, - Tk_Offset(LineMarker, dashes), BLT_CONFIG_NULL_OK, &dashesOption}, - {BLT_CONFIG_PIXELS, "-dashoffset", "dashOffset", "DashOffset", - "0", Tk_Offset(LineMarker, dashes.offset), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_STRING, "-element", "element", "Element", NULL, - Tk_Offset(LineMarker, elemName), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", (char*)NULL, - Tk_Offset(LineMarker, fillColor), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", "miter", - Tk_Offset(LineMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-linewidth", "lineWidth", "LineWidth", - "1", Tk_Offset(LineMarker, lineWidth), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no", - Tk_Offset(LineMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x", - Tk_Offset(LineMarker, axes.x), 0, &bltXAxisOption}, - {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y", - Tk_Offset(LineMarker, axes.y), 0, &bltYAxisOption}, - {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL, - Tk_Offset(LineMarker, obj.name), BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", - "black", Tk_Offset(LineMarker, outlineColor), - BLT_CONFIG_NULL_OK}, - {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal", - Tk_Offset(LineMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, - {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no", - Tk_Offset(LineMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0", - Tk_Offset(LineMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", "no", - Tk_Offset(LineMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0", - Tk_Offset(LineMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} -}; - -static MarkerConfigProc ConfigureLineProc; -static MarkerCreateProc CreateLineProc; -static MarkerDrawProc DrawLineProc; -static MarkerFreeProc FreeLineProc; -static MarkerMapProc MapLineProc; -static MarkerPointProc PointInLineProc; -static MarkerPostscriptProc LineToPostscriptProc; -static MarkerRegionProc RegionInLineProc; - -static MarkerClass lineMarkerClass = { - lineConfigSpecs, - ConfigureLineProc, - DrawLineProc, - FreeLineProc, - MapLineProc, - PointInLineProc, - RegionInLineProc, - LineToPostscriptProc, -}; - -typedef struct { - GraphObj obj; /* Must be first field in marker. */ - - MarkerClass *classPtr; - - Tcl_HashEntry *hashPtr; - - Blt_ChainLink link; - - const char* elemName; /* Element associated with marker. Let's - * you link a marker to an element. The - * marker is drawn only if the element - * is also visible. */ - Axis2d axes; - - Point2d *worldPts; /* Coordinate array to position - * marker. */ - - int nWorldPts; /* Number of points in above array */ - - int drawUnder; /* If non-zero, draw the marker - * underneath any elements. This can be - * a performance penalty because the - * graph must be redraw entirely each - * time the marker is redrawn. */ - - int clipped; /* Indicates if the marker is totally - * clipped by the plotting area. */ - - int hide; - unsigned int flags; - - - int xOffset, yOffset; /* Pixel offset from graph position */ - - int state; - Point2d *screenPts; /* Array of points representing the * polygon in screen coordinates. It's * not used for drawing, but to generate @@ -941,7 +815,7 @@ static Marker* CreateMarker(Graph* graphPtr, const char* name, ClassId classId) markerPtr = Blt_CreateBitmapProc(); /* bitmap */ break; case CID_MARKER_LINE: - markerPtr = CreateLineProc(); /* line */ + markerPtr = Blt_CreateLineProc(); /* line */ break; case CID_MARKER_IMAGE: return NULL; /* not supported */ @@ -1426,233 +1300,6 @@ static void ChildCustodyProc(ClientData clientData, Tk_Window tkwin) Blt_EventuallyRedrawGraph(graphPtr); } -static void MapLineProc(Marker *markerPtr) -{ - Graph* graphPtr = markerPtr->obj.graphPtr; - LineMarker *lmPtr = (LineMarker *)markerPtr; - Point2d *srcPtr, *pend; - Segment2d *segments, *segPtr; - Point2d p, q; - Region2d extents; - - lmPtr->nSegments = 0; - if (lmPtr->segments != NULL) { - free(lmPtr->segments); - } - if (markerPtr->nWorldPts < 2) { - return; /* Too few points */ - } - Blt_GraphExtents(graphPtr, &extents); - - /* - * Allow twice the number of world coordinates. The line will represented - * 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. - */ - segments = malloc(markerPtr->nWorldPts * sizeof(Segment2d)); - srcPtr = markerPtr->worldPts; - p = Blt_MapPoint(srcPtr, &markerPtr->axes); - p.x += markerPtr->xOffset; - p.y += markerPtr->yOffset; - - segPtr = segments; - for (srcPtr++, pend = markerPtr->worldPts + markerPtr->nWorldPts; - srcPtr < pend; srcPtr++) { - Point2d next; - - next = Blt_MapPoint(srcPtr, &markerPtr->axes); - next.x += markerPtr->xOffset; - next.y += markerPtr->yOffset; - q = next; - if (Blt_LineRectClip(&extents, &p, &q)) { - segPtr->p = p; - segPtr->q = q; - segPtr++; - } - p = next; - } - lmPtr->nSegments = segPtr - segments; - lmPtr->segments = segments; - markerPtr->clipped = (lmPtr->nSegments == 0); -} - -static int -PointInLineProc(Marker *markerPtr, Point2d *samplePtr) -{ - LineMarker *lmPtr = (LineMarker *)markerPtr; - - return Blt_PointInSegments(samplePtr, lmPtr->segments, lmPtr->nSegments, - (double)markerPtr->obj.graphPtr->search.halo); -} - -static int RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) -{ - if (markerPtr->nWorldPts < 2) { - return FALSE; - } - if (enclosed) { - Point2d *pp, *pend; - - for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; - pp < pend; pp++) { - Point2d p; - - p = Blt_MapPoint(pp, &markerPtr->axes); - if ((p.x < extsPtr->left) && (p.x > extsPtr->right) && - (p.y < extsPtr->top) && (p.y > extsPtr->bottom)) { - return FALSE; - } - } - return TRUE; /* All points inside bounding box. */ - } else { - int count; - Point2d *pp, *pend; - - count = 0; - for (pp = markerPtr->worldPts, pend = pp + (markerPtr->nWorldPts - 1); - pp < pend; pp++) { - Point2d p, q; - - p = Blt_MapPoint(pp, &markerPtr->axes); - q = Blt_MapPoint(pp + 1, &markerPtr->axes); - if (Blt_LineRectClip(extsPtr, &p, &q)) { - count++; - } - } - return (count > 0); /* At least 1 segment passes through - * region. */ - } -} - -static void DrawLineProc(Marker *markerPtr, Drawable drawable) -{ - LineMarker *lmPtr = (LineMarker *)markerPtr; - - if (lmPtr->nSegments > 0) { - Graph* graphPtr = markerPtr->obj.graphPtr; - - Blt_Draw2DSegments(graphPtr->display, drawable, lmPtr->gc, - lmPtr->segments, lmPtr->nSegments); - if (lmPtr->xor) { /* Toggle the drawing state */ - lmPtr->xorState = (lmPtr->xorState == 0); - } - } -} - -static int ConfigureLineProc(Marker *markerPtr) -{ - Graph* graphPtr = markerPtr->obj.graphPtr; - LineMarker *lmPtr = (LineMarker *)markerPtr; - GC newGC; - XGCValues gcValues; - unsigned long gcMask; - Drawable drawable; - - drawable = Tk_WindowId(graphPtr->tkwin); - gcMask = (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle); - if (lmPtr->outlineColor != NULL) { - gcMask |= GCForeground; - gcValues.foreground = lmPtr->outlineColor->pixel; - } - if (lmPtr->fillColor != NULL) { - gcMask |= GCBackground; - gcValues.background = lmPtr->fillColor->pixel; - } - gcValues.cap_style = lmPtr->capStyle; - gcValues.join_style = lmPtr->joinStyle; - gcValues.line_width = LineWidth(lmPtr->lineWidth); - gcValues.line_style = LineSolid; - if (LineIsDashed(lmPtr->dashes)) { - gcValues.line_style = - (gcMask & GCBackground) ? LineDoubleDash : LineOnOffDash; - } - if (lmPtr->xor) { - unsigned long pixel; - gcValues.function = GXxor; - - gcMask |= GCFunction; - pixel = Tk_3DBorderColor(graphPtr->plotBg)->pixel; - if (gcMask & GCBackground) { - gcValues.background ^= pixel; - } - gcValues.foreground ^= pixel; - if (drawable != None) { - DrawLineProc(markerPtr, drawable); - } - } - newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); - if (lmPtr->gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, lmPtr->gc); - } - if (LineIsDashed(lmPtr->dashes)) { - Blt_SetDashes(graphPtr->display, newGC, &lmPtr->dashes); - } - lmPtr->gc = newGC; - if (lmPtr->xor) { - if (drawable != None) { - MapLineProc(markerPtr); - DrawLineProc(markerPtr, drawable); - } - return TCL_OK; - } - markerPtr->flags |= MAP_ITEM; - if (markerPtr->drawUnder) { - graphPtr->flags |= CACHE_DIRTY; - } - Blt_EventuallyRedrawGraph(graphPtr); - return TCL_OK; -} - -static void LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps) -{ - LineMarker *lmPtr = (LineMarker *)markerPtr; - - if (lmPtr->nSegments > 0) { - Blt_Ps_XSetLineAttributes(ps, lmPtr->outlineColor, - lmPtr->lineWidth, &lmPtr->dashes, lmPtr->capStyle, - lmPtr->joinStyle); - if ((LineIsDashed(lmPtr->dashes)) && (lmPtr->fillColor != NULL)) { - Blt_Ps_Append(ps, "/DashesProc {\n gsave\n "); - Blt_Ps_XSetBackground(ps, lmPtr->fillColor); - Blt_Ps_Append(ps, " "); - Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); - Blt_Ps_VarAppend(ps, - "stroke\n", - " grestore\n", - "} def\n", (char*)NULL); - } else { - Blt_Ps_Append(ps, "/DashesProc {} def\n"); - } - Blt_Ps_Draw2DSegments(ps, lmPtr->segments, lmPtr->nSegments); - } -} - -static void FreeLineProc(Marker *markerPtr) -{ - LineMarker *lmPtr = (LineMarker *)markerPtr; - Graph* graphPtr = markerPtr->obj.graphPtr; - - if (lmPtr->gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, lmPtr->gc); - } - if (lmPtr->segments != NULL) { - free(lmPtr->segments); - } -} - -static Marker* CreateLineProc(void) -{ - LineMarker *lmPtr; - - lmPtr = calloc(1, sizeof(LineMarker)); - lmPtr->classPtr = &lineMarkerClass; - lmPtr->xor = FALSE; - lmPtr->capStyle = CapButt; - lmPtr->joinStyle = JoinMiter; - return (Marker *)lmPtr; -} - static void MapPolygonProc(Marker *markerPtr) { Graph* graphPtr = markerPtr->obj.graphPtr; diff --git a/src/bltGrMarkerLine.C b/src/bltGrMarkerLine.C new file mode 100644 index 0000000..f464dc8 --- /dev/null +++ b/src/bltGrMarkerLine.C @@ -0,0 +1,324 @@ +/* + * 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 "bltGraph.h" +#include "bltGrMarkerLine.h" + +static Blt_ConfigSpec lineConfigSpecs[] = { + {BLT_CONFIG_CUSTOM, "-bindtags", "bindTags", "BindTags", "Line all", + Tk_Offset(LineMarker, obj.tags), BLT_CONFIG_NULL_OK, + &listOption}, + {BLT_CONFIG_CAP_STYLE, "-cap", "cap", "Cap", "butt", + Tk_Offset(LineMarker, capStyle), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_CUSTOM, "-coords", "coords", "Coords", NULL, + Tk_Offset(LineMarker, worldPts), BLT_CONFIG_NULL_OK, &coordsOption}, + {BLT_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes", NULL, + Tk_Offset(LineMarker, dashes), BLT_CONFIG_NULL_OK, &dashesOption}, + {BLT_CONFIG_PIXELS, "-dashoffset", "dashOffset", "DashOffset", + "0", Tk_Offset(LineMarker, dashes.offset), + BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_STRING, "-element", "element", "Element", NULL, + Tk_Offset(LineMarker, elemName), BLT_CONFIG_NULL_OK}, + {BLT_CONFIG_COLOR, "-fill", "fill", "Fill", (char*)NULL, + Tk_Offset(LineMarker, fillColor), BLT_CONFIG_NULL_OK}, + {BLT_CONFIG_JOIN_STYLE, "-join", "join", "Join", "miter", + Tk_Offset(LineMarker, joinStyle), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_PIXELS, "-linewidth", "lineWidth", "LineWidth", + "1", Tk_Offset(LineMarker, lineWidth), + BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", "no", + Tk_Offset(LineMarker, hide), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_CUSTOM, "-mapx", "mapX", "MapX", "x", + Tk_Offset(LineMarker, axes.x), 0, &bltXAxisOption}, + {BLT_CONFIG_CUSTOM, "-mapy", "mapY", "MapY", "y", + Tk_Offset(LineMarker, axes.y), 0, &bltYAxisOption}, + {BLT_CONFIG_STRING, "-name", (char*)NULL, (char*)NULL, NULL, + Tk_Offset(LineMarker, obj.name), BLT_CONFIG_NULL_OK}, + {BLT_CONFIG_COLOR, "-outline", "outline", "Outline", + "black", Tk_Offset(LineMarker, outlineColor), + BLT_CONFIG_NULL_OK}, + {BLT_CONFIG_CUSTOM, "-state", "state", "State", "normal", + Tk_Offset(LineMarker, state), BLT_CONFIG_DONT_SET_DEFAULT, &stateOption}, + {BLT_CONFIG_BOOLEAN, "-under", "under", "Under", "no", + Tk_Offset(LineMarker, drawUnder), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_PIXELS, "-xoffset", "xOffset", "XOffset", "0", + Tk_Offset(LineMarker, xOffset), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_BOOLEAN, "-xor", "xor", "Xor", "no", + Tk_Offset(LineMarker, xor), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_PIXELS, "-yoffset", "yOffset", "YOffset", "0", + Tk_Offset(LineMarker, yOffset), BLT_CONFIG_DONT_SET_DEFAULT}, + {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} +}; + +MarkerCreateProc Blt_CreateLineProc; +static MarkerConfigProc ConfigureLineProc; +static MarkerDrawProc DrawLineProc; +static MarkerFreeProc FreeLineProc; +static MarkerMapProc MapLineProc; +static MarkerPointProc PointInLineProc; +static MarkerPostscriptProc LineToPostscriptProc; +static MarkerRegionProc RegionInLineProc; + +static MarkerClass lineMarkerClass = { + lineConfigSpecs, + ConfigureLineProc, + DrawLineProc, + FreeLineProc, + MapLineProc, + PointInLineProc, + RegionInLineProc, + LineToPostscriptProc, +}; + +Marker* Blt_CreateLineProc(void) +{ + LineMarker *lmPtr; + + lmPtr = calloc(1, sizeof(LineMarker)); + lmPtr->classPtr = &lineMarkerClass; + lmPtr->xor = FALSE; + lmPtr->capStyle = CapButt; + lmPtr->joinStyle = JoinMiter; + return (Marker *)lmPtr; +} + +static int PointInLineProc(Marker *markerPtr, Point2d *samplePtr) +{ + LineMarker *lmPtr = (LineMarker *)markerPtr; + + return Blt_PointInSegments(samplePtr, lmPtr->segments, lmPtr->nSegments, + (double)markerPtr->obj.graphPtr->search.halo); +} + +static int RegionInLineProc(Marker *markerPtr, Region2d *extsPtr, int enclosed) +{ + if (markerPtr->nWorldPts < 2) { + return FALSE; + } + if (enclosed) { + Point2d *pp, *pend; + + for (pp = markerPtr->worldPts, pend = pp + markerPtr->nWorldPts; + pp < pend; pp++) { + Point2d p; + + p = Blt_MapPoint(pp, &markerPtr->axes); + if ((p.x < extsPtr->left) && (p.x > extsPtr->right) && + (p.y < extsPtr->top) && (p.y > extsPtr->bottom)) { + return FALSE; + } + } + return TRUE; /* All points inside bounding box. */ + } else { + int count; + Point2d *pp, *pend; + + count = 0; + for (pp = markerPtr->worldPts, pend = pp + (markerPtr->nWorldPts - 1); + pp < pend; pp++) { + Point2d p, q; + + p = Blt_MapPoint(pp, &markerPtr->axes); + q = Blt_MapPoint(pp + 1, &markerPtr->axes); + if (Blt_LineRectClip(extsPtr, &p, &q)) { + count++; + } + } + return (count > 0); /* At least 1 segment passes through + * region. */ + } +} + +static void DrawLineProc(Marker *markerPtr, Drawable drawable) +{ + LineMarker *lmPtr = (LineMarker *)markerPtr; + + if (lmPtr->nSegments > 0) { + Graph* graphPtr = markerPtr->obj.graphPtr; + + Blt_Draw2DSegments(graphPtr->display, drawable, lmPtr->gc, + lmPtr->segments, lmPtr->nSegments); + if (lmPtr->xor) { /* Toggle the drawing state */ + lmPtr->xorState = (lmPtr->xorState == 0); + } + } +} + +static int ConfigureLineProc(Marker *markerPtr) +{ + Graph* graphPtr = markerPtr->obj.graphPtr; + LineMarker *lmPtr = (LineMarker *)markerPtr; + GC newGC; + XGCValues gcValues; + unsigned long gcMask; + Drawable drawable; + + drawable = Tk_WindowId(graphPtr->tkwin); + gcMask = (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle); + if (lmPtr->outlineColor != NULL) { + gcMask |= GCForeground; + gcValues.foreground = lmPtr->outlineColor->pixel; + } + if (lmPtr->fillColor != NULL) { + gcMask |= GCBackground; + gcValues.background = lmPtr->fillColor->pixel; + } + gcValues.cap_style = lmPtr->capStyle; + gcValues.join_style = lmPtr->joinStyle; + gcValues.line_width = LineWidth(lmPtr->lineWidth); + gcValues.line_style = LineSolid; + if (LineIsDashed(lmPtr->dashes)) { + gcValues.line_style = + (gcMask & GCBackground) ? LineDoubleDash : LineOnOffDash; + } + if (lmPtr->xor) { + unsigned long pixel; + gcValues.function = GXxor; + + gcMask |= GCFunction; + pixel = Tk_3DBorderColor(graphPtr->plotBg)->pixel; + if (gcMask & GCBackground) { + gcValues.background ^= pixel; + } + gcValues.foreground ^= pixel; + if (drawable != None) { + DrawLineProc(markerPtr, drawable); + } + } + newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); + if (lmPtr->gc != NULL) { + Blt_FreePrivateGC(graphPtr->display, lmPtr->gc); + } + if (LineIsDashed(lmPtr->dashes)) { + Blt_SetDashes(graphPtr->display, newGC, &lmPtr->dashes); + } + lmPtr->gc = newGC; + if (lmPtr->xor) { + if (drawable != None) { + MapLineProc(markerPtr); + DrawLineProc(markerPtr, drawable); + } + return TCL_OK; + } + markerPtr->flags |= MAP_ITEM; + if (markerPtr->drawUnder) { + graphPtr->flags |= CACHE_DIRTY; + } + Blt_EventuallyRedrawGraph(graphPtr); + return TCL_OK; +} + +static void LineToPostscriptProc(Marker *markerPtr, Blt_Ps ps) +{ + LineMarker *lmPtr = (LineMarker *)markerPtr; + + if (lmPtr->nSegments > 0) { + Blt_Ps_XSetLineAttributes(ps, lmPtr->outlineColor, + lmPtr->lineWidth, &lmPtr->dashes, lmPtr->capStyle, + lmPtr->joinStyle); + if ((LineIsDashed(lmPtr->dashes)) && (lmPtr->fillColor != NULL)) { + Blt_Ps_Append(ps, "/DashesProc {\n gsave\n "); + Blt_Ps_XSetBackground(ps, lmPtr->fillColor); + Blt_Ps_Append(ps, " "); + Blt_Ps_XSetDashes(ps, (Blt_Dashes *)NULL); + Blt_Ps_VarAppend(ps, + "stroke\n", + " grestore\n", + "} def\n", (char*)NULL); + } else { + Blt_Ps_Append(ps, "/DashesProc {} def\n"); + } + Blt_Ps_Draw2DSegments(ps, lmPtr->segments, lmPtr->nSegments); + } +} + +static void FreeLineProc(Marker *markerPtr) +{ + LineMarker *lmPtr = (LineMarker *)markerPtr; + Graph* graphPtr = markerPtr->obj.graphPtr; + + if (lmPtr->gc != NULL) { + Blt_FreePrivateGC(graphPtr->display, lmPtr->gc); + } + if (lmPtr->segments != NULL) { + free(lmPtr->segments); + } +} + +static void MapLineProc(Marker *markerPtr) +{ + Graph* graphPtr = markerPtr->obj.graphPtr; + LineMarker *lmPtr = (LineMarker *)markerPtr; + Point2d *srcPtr, *pend; + Segment2d *segments, *segPtr; + Point2d p, q; + Region2d extents; + + lmPtr->nSegments = 0; + if (lmPtr->segments != NULL) { + free(lmPtr->segments); + } + if (markerPtr->nWorldPts < 2) { + return; /* Too few points */ + } + Blt_GraphExtents(graphPtr, &extents); + + /* + * Allow twice the number of world coordinates. The line will represented + * 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. + */ + segments = malloc(markerPtr->nWorldPts * sizeof(Segment2d)); + srcPtr = markerPtr->worldPts; + p = Blt_MapPoint(srcPtr, &markerPtr->axes); + p.x += markerPtr->xOffset; + p.y += markerPtr->yOffset; + + segPtr = segments; + for (srcPtr++, pend = markerPtr->worldPts + markerPtr->nWorldPts; + srcPtr < pend; srcPtr++) { + Point2d next; + + next = Blt_MapPoint(srcPtr, &markerPtr->axes); + next.x += markerPtr->xOffset; + next.y += markerPtr->yOffset; + q = next; + if (Blt_LineRectClip(&extents, &p, &q)) { + segPtr->p = p; + segPtr->q = q; + segPtr++; + } + p = next; + } + lmPtr->nSegments = segPtr - segments; + lmPtr->segments = segments; + markerPtr->clipped = (lmPtr->nSegments == 0); +} + diff --git a/src/bltGrMarkerLine.h b/src/bltGrMarkerLine.h new file mode 100644 index 0000000..c2b4bf3 --- /dev/null +++ b/src/bltGrMarkerLine.h @@ -0,0 +1,96 @@ +/* + * 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_GR_MARKER_LINE_H +#define _BLT_GR_MARKER_LINE_H + +#include "bltGrMarker.h" + +typedef struct { + GraphObj obj; /* Must be first field in marker. */ + + MarkerClass *classPtr; + + Tcl_HashEntry *hashPtr; + + Blt_ChainLink link; + + const char* elemName; /* Element associated with marker. Let's + * you link a marker to an element. The + * marker is drawn only if the element + * is also visible. */ + Axis2d axes; + + Point2d *worldPts; /* Coordinate array to position + * marker. */ + + int nWorldPts; /* Number of points in above array */ + + int drawUnder; /* If non-zero, draw the marker + * underneath any elements. This can be + * a performance penalty because the + * graph must be redraw entirely each + * time the marker is redrawn. */ + + int clipped; /* Indicates if the marker is totally + * clipped by the plotting area. */ + + int hide; + unsigned int flags; + + + int xOffset, yOffset; /* Pixel offset from graph position */ + + int state; + + XColor* fillColor; + XColor* outlineColor; /* Foreground and background colors */ + + int lineWidth; /* Line width. */ + int capStyle; /* Cap style. */ + int joinStyle; /* Join style.*/ + Blt_Dashes dashes; /* Dash list values (max 11) */ + + GC gc; /* Private graphic context */ + + Segment2d *segments; /* Malloc'ed array of points. + * Represents individual line segments + * (2 points per segment) comprising the + * mapped line. The segments may not + * necessarily be connected after + * clipping. */ + int nSegments; /* # segments in the above array. */ + int xor; + int xorState; /* State of the XOR drawing. Indicates + * if the marker is currently drawn. */ +} LineMarker; + +extern MarkerCreateProc Blt_CreateLineProc; + +#endif |