summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bltGrMarkerBitmap.C7
-rwxr-xr-xconfigure1
-rwxr-xr-xconfigure.in1
-rw-r--r--src/bltGrMarker.C357
-rw-r--r--src/bltGrMarkerLine.C324
-rw-r--r--src/bltGrMarkerLine.h96
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;
diff --git a/configure b/configure
index 8194598..980c6bb 100755
--- a/configure
+++ b/configure
@@ -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