#ifdef VMS #include #else /* UNIX */ #include #endif #include "defs.h" #include "xws_defs.h" /* Set line type */ xws_l_type(type) enum line_enum type; /* the requested line type */ { return(xws_set_type(type, LineGC)); } /* Set line width. */ /*ARGSUSED*/ xws_l_width(absolute_width, scaled_width) int absolute_width; /* requested line width in pixels */ float scaled_width; /* purposely ignored and redundant */ { XGCValues values; /* lines of width 1 pixel may be drawn faster if width is set to 0 */ values.line_width = (absolute_width <= 1 ? 0 : absolute_width); XChangeGC(Dpy, LineGC, GCLineWidth, &values); return((absolute_width < 1) ? GPLOT_INVALID_PARAMETER : GPLOT_SUCCESS); } /* Set line color */ xws_l_colour(r, g, b, index) float r, g, b; /* specification in direct color mode */ int index; /* specification in indexed color mode */ { /* set the foreground pixel in the Line Graphic Context */ XSetForeground(Dpy, LineGC, (*xws_get_pixel)(r, g, b, index)); return(GPLOT_SUCCESS); } #define DASH_OFFSET 0 /* bit offset into dash pattern for phasing */ /* Set line type in the requested Graphics Context -- LineGC or EdgeGC */ xws_set_type(type, gc) enum line_enum type; /* the requested line type */ GC gc; /* Graphic Context */ { XGCValues values; int status = GPLOT_SUCCESS; #define DASH_LENGTH 2 /* number of elements in dash_list */ static char dash_list[DASH_LENGTH] = {10, 2}; #define DOT_LENGTH 2 /* number of elements in dot_list */ static char dot_list[DOT_LENGTH] = {2, 2}; #define DASH_DOT_LENGTH 4 /* number of elements in dash_dot_list */ static char dash_dot_list[DASH_DOT_LENGTH] = {10, 2, 2, 2}; #define DASH_DOT_DOT_LENGTH 6 /* number of elements in dash_dot_dot_list */ static char dash_dot_dot_list[DASH_DOT_DOT_LENGTH] = {10, 2, 2, 2, 2, 2}; values.line_style = LineOnOffDash; values.fill_style = FillSolid; switch (type) { default: status = GPLOT_INVALID_PARAMETER; /* CGM standard indicates solid lines as a default */ /* falls through */ case solid_l: values.line_style = LineSolid; break; case dash: XSetDashes(Dpy, gc, DASH_OFFSET, dash_list, DASH_LENGTH); break; case dot_l: XSetDashes(Dpy, gc, DASH_OFFSET, dot_list, DOT_LENGTH); break; case dash_dot: XSetDashes(Dpy, gc, DASH_OFFSET, dash_dot_list, DASH_DOT_LENGTH); break; case dash_d_d: XSetDashes(Dpy, gc, DASH_OFFSET, dash_dot_dot_list, DASH_DOT_DOT_LENGTH); break; } XChangeGC(Dpy, gc, (GCLineStyle | GCFillStyle), &values); return(status); } /* Polyline processor routine. Assume line attributes have been * appropriately set in the graphics context LineGC. * The last parameter of xws_lines distinguishes polylines from polygons. */ xws_pline(point_count, x, y) int point_count; /* count of points */ int x[]; /* x coordinates */ int y[]; /* y coordinates */ { /* Regard a single line of length 0 as a request for a point */ if ((point_count == 2) && (x[0] == x[1]) && (y[0] == y[1])) { XDrawPoint(Dpy, Win, LineGC, x[0], MaxY - y[0]); return(GPLOT_SUCCESS); } /* otherwise a 'classical' polyline */ return(xws_lines(point_count, x, y, LineGC, FALSE)); } /* Polyline and Polygon edge processor routine. Assume GC line attributes * have been appropriately set. Draw polylines in batches of a maximum of * MAX_POINTS points. MAX_POINTS must be an integer greater than 1. If * the parameter 'closed' is true, the last point is connected to the first. */ xws_lines(point_count, x, y, gc, closed) int point_count; /* count of points */ int x[]; /* x coordinates */ int y[]; /* y coordinates */ GC gc; /* graphics context - determines line attributes */ int closed; /* if polylines, closed must be FALSE */ { register int n; /* count of processed polyline coordinates */ register int p; /* count of processed unsent polyline coordinates */ /* Draw lines in groups of (MAX_POINTS-1), except for the last group. * n = count of processed points from gplot's x and y arrays. * p = count of processed unsent point specifications. */ n = p = 0; while (n < point_count) { Points[p].x = (short) x[n]; Points[p].y = (short) (MaxY - y[n++]); if (++p == MAX_POINTS) { --p; XDrawLines(Dpy, Win, gc, Points, MAX_POINTS, CoordModeOrigin); Points[0].x = Points[p].x; Points[0].y = Points[p].y; p = 1; } } if (p > 1) XDrawLines(Dpy, Win, gc, Points, p, CoordModeOrigin); if (closed) /* connect the last point to the first */ XDrawLine(Dpy, Win, gc, (short) x[point_count-1], (short) (MaxY - y[point_count-1]), (short) x[0], (short) (MaxY - y[0])); return(GPLOT_SUCCESS); } /* Disjoint Polyline processor routine. * * Draw disjoint polylines as segments in batches of MAX_SEGMENTS segments, * except for the remainder batch. Line attributes are up to date in the * Graphics Context "LineGC". Discard last point, if unpaired, i.e. if * "point_count" is odd. * * n = count of processed polyline points from gplot's x and y arrays. * s = count of processed unsent segment specifications. * Segments is the data structure for X segment specifications. */ xws_dpline(point_count, x, y) int point_count; /* count of points */ int x[]; /* x coordinates */ int y[]; /* y coordinates */ { register int n; /* index into the gplot x and y coordinate arrays */ register int s; /* count of processed unsent X segment specifications */ if (point_count % 2) /* discard last point if an odd point count */ point_count--; n = 0; while (n < point_count) { for(s=0; (n < point_count) && (s < MAX_SEGMENTS); s++) { Segments[s].x1 = (short) x[n]; Segments[s].y1 = (short) (MaxY - y[n++]); Segments[s].x2 = (short) x[n]; Segments[s].y2 = (short) (MaxY - y[n++]); } XDrawSegments(Dpy, Win, LineGC, Segments, s); } return(GPLOT_SUCCESS); }