2021-10-11 18:37:13 -03:00

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));
}