505 lines
17 KiB
C
505 lines
17 KiB
C
#ifndef lint
|
|
static char sccsid[] = "@(#)mark.c 1.1 94/10/31 Copyr 1985-9 Sun Micro";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1985, 1986, 1987, 1988, 1989 by Sun Microsystems, Inc.
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose and without fee is hereby granted, provided that the above
|
|
* copyright notice appear in all copies and that both that copyright
|
|
* notice and this permission notice are retained, and that the name
|
|
* of Sun Microsystems, Inc., not be used in advertising or publicity
|
|
* pertaining to this software without specific, written prior permission.
|
|
* Sun Microsystems, Inc., makes no representations about the suitability
|
|
* of this software or the interface defined in this software for any
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
|
*/
|
|
/*
|
|
* CGI marker functions
|
|
*/
|
|
|
|
/*
|
|
marker_type
|
|
cgipw_marker_type
|
|
_cgi_marker_type
|
|
marker_size
|
|
cgipw_marker_size
|
|
_cgi_check_marker_size
|
|
_cgi_set_conv_marker_size
|
|
marker_color
|
|
cgipw_marker_color
|
|
_cgi_marker_color
|
|
marker_size_specification_mode
|
|
cgipw_marker_size_specification_mode
|
|
polymarker
|
|
cgipw_polymarker
|
|
_cgi_polymarker
|
|
_cgi_marker
|
|
_cgi_hollow2_circle
|
|
_cgi_hollow2_circ_pts
|
|
*/
|
|
|
|
#include "cgipriv.h"
|
|
|
|
View_surface *_cgi_vws; /* current view surface */
|
|
Outatt *_cgi_att; /* structure containing current attributes */
|
|
int _cgi_pix_mode; /* pixrect equivalent of drawing mode */
|
|
|
|
/* Like pw_put, but uses RasterOp code */
|
|
#define PW_PUT_WITH_OP(pw,x,y,op,color) pw_vector(pw, x,y, x,y, op, color)
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: marker_type */
|
|
/* */
|
|
/* Sets marker type to one of four enumerated CGI types */
|
|
/****************************************************************************/
|
|
|
|
Cerror marker_type(ttyp)
|
|
Cmartype ttyp; /* style of marker */
|
|
{
|
|
int err;
|
|
|
|
err = _cgi_check_state_5();
|
|
if (!err)
|
|
err = _cgi_marker_type(_cgi_att, ttyp);
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_marker_type */
|
|
/* */
|
|
/* */
|
|
/* Sets marker type to one of four enumerated CGI types */
|
|
/****************************************************************************/
|
|
|
|
Cerror cgipw_marker_type(desc, ttyp)
|
|
Ccgiwin *desc;
|
|
Cmartype ttyp; /* style of marker */
|
|
|
|
{
|
|
SETUP_CGIWIN(desc);
|
|
return (_cgi_marker_type(desc->vws->att, ttyp));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_marker_type */
|
|
/* */
|
|
/* */
|
|
/* Sets marker type to one of four enumerated CGI types */
|
|
/****************************************************************************/
|
|
|
|
Cerror _cgi_marker_type(att, ttyp)
|
|
Outatt *att;
|
|
Cmartype ttyp; /* style of marker */
|
|
|
|
{
|
|
int err = NO_ERROR;
|
|
|
|
if (att->asfs[3] == INDIVIDUAL)
|
|
{
|
|
att->marker.type = (Cmartype) ttyp;
|
|
}
|
|
else
|
|
{
|
|
err = EBTBUNDL;
|
|
}
|
|
return (err);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: marker_size */
|
|
/* */
|
|
/* Sets marker size */
|
|
/****************************************************************************/
|
|
|
|
Cerror marker_size(size)
|
|
Cfloat size; /* marker size */
|
|
{
|
|
int ivw;
|
|
int err;
|
|
|
|
err = _cgi_check_state_5();
|
|
if (!err)
|
|
err = _cgi_check_marker_size(_cgi_att, size);
|
|
if (!err)
|
|
{
|
|
_cgi_att->marker.size = size;
|
|
ivw = 0;
|
|
while (_cgi_bump_all_vws(&ivw))
|
|
_cgi_set_conv_marker_size(_cgi_vws);
|
|
}
|
|
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_marker_size */
|
|
/* */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror cgipw_marker_size(desc, size)
|
|
Ccgiwin *desc;
|
|
Cfloat size; /* marker size */
|
|
{
|
|
int err = NO_ERROR;
|
|
|
|
SETUP_CGIWIN(desc);
|
|
if (!err)
|
|
err = _cgi_check_marker_size(desc->vws->att, size);
|
|
if (!err)
|
|
{
|
|
desc->vws->att->marker.size = size;
|
|
_cgi_set_conv_marker_size(desc->vws);
|
|
}
|
|
|
|
return (err);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_check_marker_size */
|
|
/* */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror _cgi_check_marker_size(att, size)
|
|
Outatt *att;
|
|
Cfloat size; /* marker size */
|
|
{
|
|
if (att->asfs[4] != INDIVIDUAL)
|
|
return (EBTBUNDL);
|
|
else if (size < 0)
|
|
return (EBADSIZE); /* size must be positive */
|
|
else
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_set_conv_marker_size */
|
|
/* */
|
|
/* Created 851009 (wds) to organize setting a marker.width value. */
|
|
/****************************************************************************/
|
|
|
|
Cerror _cgi_set_conv_marker_size(vws)
|
|
View_surface *vws;
|
|
{
|
|
register Outatt *attP = vws->att;
|
|
float dist; /* x range of VDC space */
|
|
float wtemp; /* temporary result */
|
|
|
|
if (attP->mark_spec_mode == SCALED)
|
|
{
|
|
/* wds 850617: viewport coords are "VDC" for pixwin surfaces */
|
|
if (attP->vdc.use_pw_size)
|
|
dist = vws->vport.r_width;
|
|
else
|
|
dist = abs(attP->vdc.rect.r_width);
|
|
_cgi_devscalen((int) (dist * (attP->marker.size / 100.) + 0.5), wtemp);
|
|
if (wtemp < MIN_MKR_SIZE)
|
|
wtemp = MIN_MKR_SIZE;
|
|
vws->conv.marker_size = wtemp;
|
|
}
|
|
else
|
|
{
|
|
vws->conv.marker_size = attP->marker.size;
|
|
}
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: marker_color */
|
|
/* */
|
|
/* Sets marker color */
|
|
/****************************************************************************/
|
|
|
|
Cerror marker_color(index)
|
|
Cint index; /* marker color */
|
|
{
|
|
int err;
|
|
|
|
err = _cgi_check_state_5();
|
|
if (!err)
|
|
err = _cgi_marker_color(_cgi_att, index);
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_marker_color */
|
|
/* */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror cgipw_marker_color(desc, index)
|
|
Ccgiwin *desc;
|
|
Cint index; /* marker color */
|
|
{
|
|
SETUP_CGIWIN(desc);
|
|
return (_cgi_marker_color(desc->vws->att, index));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_marker_color */
|
|
/* */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror _cgi_marker_color(att, index)
|
|
Outatt *att;
|
|
Cint index; /* marker color */
|
|
{
|
|
int err = NO_ERROR;
|
|
|
|
if (att->asfs[5] == INDIVIDUAL)
|
|
{
|
|
err = _cgi_check_color(index);
|
|
if (!err)
|
|
{
|
|
att->marker.color = index;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = EBTBUNDL;
|
|
}
|
|
return (err);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: marker_size_specification_mode */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror marker_size_specification_mode(mode)
|
|
Cspecmode mode; /* pixels or percent */
|
|
{
|
|
int ivw;
|
|
Cerror err;
|
|
|
|
err = _cgi_check_state_5();
|
|
if (!err)
|
|
{
|
|
_cgi_att->mark_spec_mode = mode;
|
|
ivw = 0;
|
|
while (_cgi_bump_all_vws(&ivw))
|
|
_cgi_set_conv_marker_size(_cgi_vws);
|
|
}
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_marker_size_specification_mode */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror cgipw_marker_size_specification_mode(desc, mode)
|
|
Ccgiwin *desc;
|
|
Cspecmode mode; /* pixels or percent */
|
|
{
|
|
SETUP_CGIWIN(desc);
|
|
desc->vws->att->mark_spec_mode = mode;
|
|
/* Change the interpretation of existing marker size: */
|
|
_cgi_set_conv_marker_size(desc->vws);
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: polymarker */
|
|
/* */
|
|
/* displays marker points at each element of polycoors */
|
|
/****************************************************************************/
|
|
|
|
Cerror polymarker(polycoors)
|
|
Ccoorlist *polycoors; /* list of points */
|
|
{
|
|
int ivw;
|
|
Cerror err; /* error */
|
|
|
|
err = _cgi_err_check_4();
|
|
if (!err)
|
|
{
|
|
ivw = 0;
|
|
while (_cgi_bump_vws(&ivw))
|
|
{
|
|
err = _cgi_polymarker(_cgi_vws, polycoors);
|
|
}
|
|
}
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_polymarker */
|
|
/* */
|
|
/* displays marker points at each element of polycoors */
|
|
/****************************************************************************/
|
|
|
|
Cerror cgipw_polymarker(desc, polycoors)
|
|
Ccgiwin *desc;
|
|
Ccoorlist *polycoors; /* list of points */
|
|
{
|
|
SETUP_CGIWIN(desc);
|
|
return (_cgi_polymarker(desc->vws, polycoors));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_polymarker */
|
|
/* */
|
|
/* displays marker points at each element of polycoors */
|
|
/****************************************************************************/
|
|
|
|
Cerror _cgi_polymarker(vws, polycoors)
|
|
View_surface *vws;
|
|
Ccoorlist *polycoors; /* list of points */
|
|
{
|
|
register Ccoor *point; /* pointers to points */
|
|
register View_surface *vwsP = vws;
|
|
register int i, nt; /* counters */
|
|
int err = NO_ERROR; /* error */
|
|
|
|
/* actually draw polymarker */
|
|
point = polycoors->ptlist;
|
|
nt = polycoors->n;
|
|
if (nt <= MAXPTS)
|
|
{
|
|
for (i = 0; (i++ < nt);)
|
|
{ /* draw a marker at each point */
|
|
(void) _cgi_marker(vwsP, *point++);
|
|
}
|
|
}
|
|
else
|
|
err = ENMPTSTL;
|
|
return (err);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_marker */
|
|
/* */
|
|
/* draws a single marker */
|
|
/****************************************************************************/
|
|
Cerror _cgi_marker(vws, c1)
|
|
View_surface *vws;
|
|
Ccoor c1;
|
|
{
|
|
int x0, y0, half, quarter, color;
|
|
|
|
_cgi_devscale(c1.x, c1.y, x0, y0);
|
|
/*
|
|
* The following check ISN'T proper clipping, but is typically identical to
|
|
* the clipping of polylines. This clips to the REAL WINDOW (r_screen) and
|
|
* not to the effective viewport, nor the user's clipping rectangle.
|
|
*/
|
|
if (_cgi_err_check_69(x0, y0)) /* Control Point outside window? */
|
|
return (EVALOVWS); /* Do not render such a marker. */
|
|
/* arms of plus are guaranteed to be of equal length by int. division */
|
|
half = vws->conv.marker_size / 2;
|
|
color = vws->att->marker.color;
|
|
switch (vws->att->marker.type)
|
|
{
|
|
case (DOT):
|
|
PW_PUT_WITH_OP(vws->sunview.pw, x0, y0, _cgi_pix_mode, color);
|
|
break;
|
|
case (PLUS):
|
|
pw_vector(vws->sunview.pw, x0, y0 - half,
|
|
x0, y0 + half, _cgi_pix_mode, color);
|
|
pw_vector(vws->sunview.pw, x0 - half, y0,
|
|
x0 + half, y0, _cgi_pix_mode, color);
|
|
break;
|
|
case (ASTERISK):
|
|
pw_vector(vws->sunview.pw, x0, y0 - half,
|
|
x0, y0 + half, _cgi_pix_mode, color);
|
|
pw_vector(vws->sunview.pw, x0 - half, y0,
|
|
x0 + half, y0, _cgi_pix_mode, color);
|
|
quarter = (3 * half) / 4;
|
|
pw_vector(vws->sunview.pw, x0 - quarter,
|
|
y0 - quarter, x0 + quarter, y0 + quarter, _cgi_pix_mode, color);
|
|
pw_vector(vws->sunview.pw, x0 - quarter,
|
|
y0 + quarter, x0 + quarter, y0 - quarter, _cgi_pix_mode, color);
|
|
break;
|
|
case (CIRCLE): /* should be drawn with circle not O */
|
|
_cgi_hollow2_circle(vws, x0, y0, half, color);
|
|
break;
|
|
case (X):
|
|
pw_vector(vws->sunview.pw, x0 - half,
|
|
y0 - half, x0 + half, y0 + half, _cgi_pix_mode, color);
|
|
pw_vector(vws->sunview.pw, x0 - half,
|
|
y0 + half, x0 + half, y0 - half, _cgi_pix_mode, color);
|
|
break;
|
|
}
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_hollow2_circle */
|
|
/* */
|
|
/* draws empty circle with coors in screen space */
|
|
/****************************************************************************/
|
|
int _cgi_hollow2_circle(vws, x0, y0, rad, val)
|
|
View_surface *vws;
|
|
short x0, y0, rad, val;
|
|
{
|
|
register int x, y, d;
|
|
|
|
x = 0;
|
|
y = rad;
|
|
d = 3 - 2 * rad;
|
|
while (x < y)
|
|
{
|
|
_cgi_hollow2_circ_pts(vws, x0, y0, x, y, val);
|
|
if (d < 0)
|
|
d = d + 4 * x + 6;
|
|
else
|
|
{
|
|
d = d + 4 * (x - y) + 10;
|
|
y = y - 1;
|
|
}
|
|
x += 1;
|
|
}
|
|
if (x = y)
|
|
_cgi_hollow2_circ_pts(vws, x0, y0, x, y, val);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_hollow2_circ_pts */
|
|
/* */
|
|
/****************************************************************************/
|
|
int _cgi_hollow2_circ_pts(vws, x0, y0, x, y, color)
|
|
View_surface *vws;
|
|
short x0, y0, x, y, color;
|
|
{ /* draw symmetry points of circle */
|
|
struct pr_pos points[8];
|
|
points[0].x = -y;
|
|
points[0].y = x;
|
|
points[1].x = y;
|
|
points[1].y = x;
|
|
points[2].x = -x;
|
|
points[2].y = y;
|
|
points[3].x = x;
|
|
points[3].y = y;
|
|
points[4].x = -y;
|
|
points[4].y = -x;
|
|
points[5].x = y;
|
|
points[5].y = -x;
|
|
points[6].x = -x;
|
|
points[6].y = -y;
|
|
points[7].x = x;
|
|
points[7].y = -y;
|
|
pw_polypoint(vws->sunview.pw, x0, y0, 8, points,
|
|
_cgi_pix_mode | PIX_COLOR(color));
|
|
}
|