Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

5464 lines
171 KiB

/*
* Copyright(C) 1999-2020, 2022, 2023 National Technology & Engineering Solutions
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
* NTESS, the U.S. Government retains certain rights in this software.
*
* See packages/seacas/LICENSE for details
*/
/*
* SUN DEC/ULTRIX ALLIANT : C routines must have underscores
* SGI CONVEX : C routines must have underscores
*
* VAX HP IBM/aix : C routines do not have underscores
*
* CRAY/UNICOS : C routines must be capitalized,
* and no underscores
*/
#if !defined(CRA) && !defined(ADDC_) && !defined(COUGAR)
#define vdmova wpstmv
#define vdmoni wpstmo
#define vdgnam wpstgn
#define vbiqdv wpstiv
#define vbiqpk wpstqp
#define vdlina wpstln
#define vdtext wpsttx
#define vdpnta wpstpt
#define vdpoly wpstpy
#define vdiqcp wpstcp
#define vdstos wpstos
#define vdiqos wpstio
#define vdstfc wpstfc
#define vdstbc wpstbc
#define vdstin wpstin
#define vdstls wpstls
#define vdstlw wpstlw
#define vdstcs wpstcs
#define vdaabu wpstbu
#define vdaloc wpstlo
#define vdabgl wpstbl
#define vdakgl wpstkl
#define vdstla wpstla
#define vdinit wpstnt
#define vdfram wpstfr
#define vdterm wpsttr
#define vdiqdc wpstdc
#define vdnwpg wpstpg
#define vdbell wpstbe
#define vdwait wpstwt
#define vdbufl wpstfl
#define vdstco wpstco
#define vdiqco wpstic
#define vdescp wpstes
#define vdiqes wpstie
#define vdiqnd wpstid
#define vimova wpstim
#define vilina wpstil
#define vipnta wpstip
#define vitext wpstix
#define viinit wpstii
#define viterm wpstit
#define vinwpg wpstig
#define vcjob vcjob
#define vconod wpston
#define vberrh wpster
#define vdloge wpstle
#define cdrwfs wpstwf
#define cdrrfs wpstrf
#define cdrofs wpstof
#define cdrof3 wpsto3
#define cdrcfs wpstcf
#define cdroff wpstff
#define cdroab wpstab
#define bgpbuf wpstbf
#define qmsbuf wpstqm
#define qmsbu1 wpstbf
#define ddcbuf wpstbf
#define h75buf wpstbf
#define btkbuf wpstbf
#define nmtbuf wpstbf
#define onhbuf wpstoh
#define vbimbf wpstib
#define vbpkg wpstpk
#define vbdev wpstdv
#define vdiqrs wpstqr
#define vdstmp wpstmp
#define vdstrs wpstrs
#define vdstrv wpstrv
#define vdbrgb wpstbg
#define vdfrgb wpstfg
#define vdpixl wpstpx
#define vdpixi wpstpi
#define vdrpix wpstrp
#define vdrpxi wpstri
#define vdrscl wpstrl
#define vdiqci wpstci
#define vbstmp wpst01
#define vcndcm wpst02
#define vcattr wpst03
#define vifram wpst04
#define vccrps wpst05
#define vcescp wpst06
#define devcap wpst07
#define vcscal wpst08
#define vcddim wpst09
#define vipoly wpst10
#define vcvect wpst11
#define vblina wpst12
#define vbvect wpst13
#define vbstls wpst14
#define pstbuf wpst15
#define cgixxx cgipst
#endif
#if defined(CRA)
#define vdmova WPSTMV
#define vdmoni WPSTMO
#define vdgnam WPSTGN
#define vbiqdv WPSTIV
#define vbiqpk WPSTQP
#define vdlina WPSTLN
#define vdtext WPSTTX
#define vdpnta WPSTPT
#define vdpoly WPSTPY
#define vdiqcp WPSTCP
#define vdstos WPSTOS
#define vdiqos WPSTIO
#define vdstfc WPSTFC
#define vdstbc WPSTBC
#define vdstin WPSTIN
#define vdstls WPSTLS
#define vdstlw WPSTLW
#define vdstcs WPSTCS
#define vdaabu WPSTBU
#define vdaloc WPSTLO
#define vdabgl WPSTBL
#define vdakgl WPSTKL
#define vdstla WPSTLA
#define vdinit WPSTNT
#define vdfram WPSTFR
#define vdterm WPSTTR
#define vdiqdc WPSTDC
#define vdnwpg WPSTPG
#define vdbell WPSTBE
#define vdwait WPSTWT
#define vdbufl WPSTFL
#define vdstco WPSTCO
#define vdiqco WPSTIC
#define vdescp WPSTES
#define vdiqes WPSTIE
#define vdiqnd WPSTID
#define vimova WPSTIM
#define vilina WPSTIL
#define vipnta WPSTIP
#define vitext WPSTIX
#define viinit WPSTII
#define viterm WPSTIT
#define vinwpg WPSTIG
#define cdrcom CDRCOM
#define vcjob VCJOB
#define vconod WPSTON
#define vberrh WPSTER
#define vdloge WPSTLE
#define cdrwfs WPSTWF
#define cdrrfs WPSTRF
#define cdrofs WPSTOF
#define cdrof3 WPSTO3
#define cdrcfs WPSTCF
#define cdroff WPSTFF
#define cdroab WPSTAB
#define bgpbuf WPSTBF
#define qmsbuf WPSTQM
#define qmsbu1 WPSTBF
#define ddcbuf WPSTBF
#define h75buf WPSTBF
#define btkbuf WPSTBF
#define nmtbuf WPSTBF
#define onhbuf WPSTOH
#define vbimbf WPSTIB
#define vbpkg WPSTPK
#define vbdev WPSTDV
#define vdiqrs WPSTQR
#define vdstmp WPSTMP
#define vdstrs WPSTRS
#define vdstrv WPSTRV
#define vdbrgb WPSTBG
#define vdfrgb WPSTFG
#define vdpixl WPSTPX
#define vdpixi WPSTPI
#define vdrpix WPSTRP
#define vdrpxi WPSTRI
#define vdrscl WPSTRL
#define vdiqci WPSTCI
#define vbstmp WPST01
#define vcndcm WPST02
#define vcattr WPST03
#define vifram WPST04
#define vccrps WPST05
#define vcescp WPST06
#define devcap WPST07
#define vcscal WPST08
#define vcddim WPST09
#define vipoly WPST10
#define vcvect WPST11
#define vblina WPST12
#define vbvect WPST13
#define vbstls WPST14
#define pstbuf WPST15
#define wpstzz WPSTZZ
#define cgixxx CGIPST
#endif
#if defined(ADDC_) || defined(COUGAR)
#define vdmova wpstmv_
#define vdmoni wpstmo_
#define vdgnam wpstgn_
#define vbiqdv wpstiv_
#define vbiqpk wpstqp_
#define vdlina wpstln_
#define vdtext wpsttx_
#define vdpnta wpstpt_
#define vdpoly wpstpy_
#define vdiqcp wpstcp_
#define vdstos wpstos_
#define vdiqos wpstio_
#define vdstfc wpstfc_
#define vdstbc wpstbc_
#define vdstin wpstin_
#define vdstls wpstls_
#define vdstlw wpstlw_
#define vdstcs wpstcs_
#define vdaabu wpstbu_
#define vdaloc wpstlo_
#define vdabgl wpstbl_
#define vdakgl wpstkl_
#define vdstla wpstla_
#define vdinit wpstnt_
#define vdfram wpstfr_
#define vdterm wpsttr_
#define vdiqdc wpstdc_
#define vdnwpg wpstpg_
#define vdbell wpstbe_
#define vdwait wpstwt_
#define vdbufl wpstfl_
#define vdstco wpstco_
#define vdiqco wpstic_
#define vdescp wpstes_
#define vdiqes wpstie_
#define vdiqnd wpstid_
#define vimova wpstim_
#define vilina wpstil_
#define vipnta wpstip_
#define vitext wpstix_
#define viinit wpstii_
#define viterm wpstit_
#define vinwpg wpstig_
#define cdrcom cdrcom_
#define vcjob vcjob_
#define vconod wpston_
#define vberrh wpster_
#define vdloge wpstle_
#define cdrwfs wpstwf_
#define cdrrfs wpstrf_
#define cdrofs wpstof_
#define cdrof3 wpsto3_
#define cdrcfs wpstcf_
#define cdroff wpstff_
#define cdroab wpstab_
#define bgpbuf wpstbf_
#define qmsbuf wpstqm_
#define qmsbu1 wpstbf_
#define ddcbuf wpstbf_
#define h75buf wpstbf_
#define btkbuf wpstbf_
#define nmtbuf wpstbf_
#define onhbuf wpstoh_
#define vbimbf wpstib_
#define vbpkg wpstpk_
#define vbdev wpstdv_
#define vdiqrs wpstqr_
#define vdstmp wpstmp_
#define vdstrs wpstrs_
#define vdstrv wpstrv_
#define vdbrgb wpstbg_
#define vdfrgb wpstfg_
#define vdpixl wpstpx_
#define vdpixi wpstpi_
#define vdrpix wpstrp_
#define vdrpxi wpstri_
#define vdrscl wpstrl_
#define vdiqci wpstci_
#define vbstmp wpst01_
#define vcndcm wpst02_
#define vcattr wpst03_
#define vifram wpst04_
#define vccrps wpst05_
#define vcescp wpst06_
#define devcap wpst07_
#define vcscal wpst08_
#define vcddim wpst09_
#define vipoly wpst10_
#define vcvect wpst11_
#define vblina wpst12_
#define vbvect wpst13_
#define vbstls wpst14_
#define pstbuf wpst15_
#define wpstbf wpstbf_
#define wpstzz wpstzz_
#define cgixxx cgipst_
#endif
#if defined(CONVEX)
#define cdrcom_ _cdrcom_
#define cdrcm2_ _cdrcm2_
#define vcjob_ _vcjob_
#define vconod_ _vconod_
#define cdrunx_ _cdrunx_
#endif
/* cgipst.h - header file to define device dependent stuff for driver
* Postscript B/W (pst)
* Sandia National Laboratories, Div 2634
* Tue Dec 19 10:36:45 MST 1989 - last date modified
*/
#include "svdi.h"
/******************************************************************************/
/* */
/* type and constant declarations */
/* */
/******************************************************************************/
#define MAX_DEVICE_SURFACES 6 /* num of surfaces device supports */
/* ...set to 1 for interactive device */
#define ERROR_LIST_SIZE 10 /* number of errors stored */
#define COLOR_TABLE_SIZE 256 /* max color table for SVDI is 256 */
#define MAX_TEXT_LENGTH 136 /* max text length for SVDI is 136 */
#define MAX_POLYLINE -1 /* -1 = no limit */
#define MAX_DJ_POLYLINE -1 /* -1 = no limit */
#define MAX_POLYMARKER -1 /* -1 = no limit */
#define MAX_POLYGON 2000 /* uses min of this and SVDI limit */
#define MAX_ARRAY 1 /* for pixel array and cell array */
/* ...set to 1 for non raster device */
#define BUFFER_SIZE 132 /* for batch device buffer routines */
/* ...set to 1 for interactive device */
#define DEFAULT_OUTFILE_NAME "" /* not used, driver builds the name */
/* end cgipst.h */
#include "data_def.h"
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#if defined(CRA) || (defined(SUN) && (defined(SYSV) || defined(SVR4)))
#include <fcntl.h>
#include <sys/types.h>
#endif
#include "cdrcom.h"
#include "cgi.h"
#include "cgidef.h"
#include "devid.h"
#include "fortyp.h"
#include "stdtyp.h"
#include <sys/file.h>
/* ------------------------------------------------------------*/
/* >> FUNCTION PROTOTYPES */
/*-------------------------------------------------------------*/
/* cgi/vdi routines */
static void xactivate(anything **surf_list);
static void xdeactivate(anything **surf_list);
static void xci(anything **params, int num_surfaces, anything **surf_list);
static void xct(int num_surfaces, anything **surf_list);
static void xcxdfac(int num_surfaces, anything **surf_list);
static void xcpds(anything **params, int num_surfaces, anything **surf_list);
static void xcendpg(int num_surfaces, anything **surf_list);
static void xcbc(anything **params, int num_surfaces, anything **surf_list);
static void xcvdcx(anything **params, int num_surfaces, anything **surf_list);
static void xcv(anything **params, int num_surfaces, anything **surf_list);
static void xccl(anything **params, int num_surfaces, anything **surf_list);
static void xcdscl(anything **params, int num_surfaces, anything **surf_list);
static void xcdqerr(anything **params, anything **surf_list);
static void xcerhct(anything **params, int num_surfaces, anything **surf_list);
static void xccixp(anything **params, int num_surfaces, anything **surf_list);
static void xcesc(anything **params, int num_surfaces, anything **surf_list);
static void xcqid(anything **params, anything **surf_list);
static void xcqd(anything **params, anything **surf_list);
static void xclf(anything **params, anything **surf_list);
static void xclpr(anything **params, anything **surf_list);
static void xcqsp(anything **params, anything **surf_list);
static void xclesc(anything **params, anything **surf_list);
static void xcqp(anything **params, anything **surf_list);
static void xcqcl(anything **params, anything **surf_list);
static void xcpl(anything **params, int num_surfaces, anything **surf_list);
static void xcdjpl(anything **params, int num_surfaces, anything **surf_list);
static void xcpm(anything **params, int num_surfaces, anything **surf_list);
static void xctx(anything **params, int num_surfaces, anything **surf_list);
static void xcpg(anything **params, int num_surfaces, anything **surf_list);
static void xcca(anything **params, int num_surfaces, anything **surf_list);
static void xcpxa(anything **params, int num_surfaces, anything **surf_list);
static void xclnt(anything **params, int num_surfaces, anything **surf_list);
static void xclnw(anything **params, int num_surfaces, anything **surf_list);
static void xclnc(anything **params, int num_surfaces, anything **surf_list);
static void xcmkt(int num_surfaces, anything **surf_list);
static void xcmks(anything **params, int num_surfaces, anything **surf_list);
static void xcmkc(anything **params, int num_surfaces, anything **surf_list);
static void xctxp(anything **params, int num_surfaces, anything **surf_list);
static void xctxc(anything **params, int num_surfaces, anything **surf_list);
static void xcchh(anything **params, int num_surfaces, anything **surf_list);
static void xccho(anything **params, int num_surfaces, anything **surf_list);
static void xcis(anything **params, int num_surfaces, anything **surf_list);
static void xcflc(anything **params, int num_surfaces, anything **surf_list);
static void xccsm(anything **params, int num_surfaces, anything **surf_list);
static void xcct(anything **params, int num_surfaces, anything **surf_list);
static void xcgtxx(anything **params, anything **surf_list);
static void xcqprl(anything **params, anything **surf_list);
static void xcqln(anything **params, anything **surf_list);
static void xcqlnt(anything **params, anything **surf_list);
static void xcqslw(anything **params, anything **surf_list);
static void xcqmk(anything **params, anything **surf_list);
static void xcqmkt(anything **params, anything **surf_list);
static void xcqsms(anything **params, anything **surf_list);
static void xcqchh(anything **params, anything **surf_list);
static void xcqfl(anything **params, anything **surf_list);
static void xcqc(anything **params, anything **surf_list);
static void xcqlna(anything **params, anything **surf_list);
static void xcqmka(anything **params, anything **surf_list);
static void xcqtxa(anything **params, anything **surf_list);
static void xcqfla(anything **params, anything **surf_list);
static void xcqcte(anything **params, anything **surf_list);
static void xcili(anything **params, anything **surf_list);
static void xcrqlc(anything **params, anything **surf_list);
/* utility routines */
static void init_state(surf_statelist *surf_state);
static void set_dev_descrip(void);
static void reset_vdi(surf_statelist *surf_state);
static void set_mapping(surf_statelist *surf_state);
static void set_clipping(surf_statelist *cur_state);
static void set_foreground_color(surf_statelist *surf_state, int *colors);
static void set_background_color(surf_statelist *surf_state, int *colors);
static void report_error(surf_statelist *surf_state, int e_class, int e_num, int f_id);
static void gettoken(int *index_p, int *numrecs_p, char *data_p, int max_chars, char *outtoken_p);
static int poly_clip(point *cmin, point *cmax, float *vx, float *vy, int vlen, float *xout,
float *yout, int *lenout);
static int inside_bnd(point *v, point *bmin, point *bmax, int bound_num);
static point intersect_bnd(point *p1, point *p2, point *bmin, point *bmax, int bound_num);
/* cdr routines */
/* -- not used with interactive devices */
void cdrofs(int *);
void cdrof3(int *, int *);
void cdroff(int *, int *, int *, int *);
void cdrrfs(int *, int *, char *, int *);
void cdrwfs(int *, int *, char *, int *);
void cdrcfs(int *, int *);
void cdroab(int *, int *);
static char *copy_string(char *dest, char const *source, long int elements)
{
char *d;
for (d = dest; d + 1 < dest + elements && *source; d++, source++) {
*d = *source;
}
*d = '\0';
return d;
}
/*-------------------------------------------------------------*/
/* >> GLOBAL VARIABLE DECLARATIONS */
/*-------------------------------------------------------------*/
/* variables used to maintain state list, free list */
static int first_free_state = -1;
static int last_alloc_state = -1;
/* declare one statelist per surface */
static surf_statelist surf_states[MAX_DEVICE_SURFACES];
/* declare one description table per device */
static dev_descrip_table dev_descrip;
/* variable to keep track of current statelist */
/* -- this is global so CDR can know which state to look at */
static surf_statelist *cur_state;
/* These arrays are global because of size. Used in cell and pixel array */
static float rarray[MAX_ARRAY], garray[MAX_ARRAY], barray[MAX_ARRAY];
static int varray[MAX_ARRAY];
/*-------------------------------------------------------------*/
/* >> CGI/SVDI DEVICE DRIVER ROUTINES */
/*-------------------------------------------------------------*/
void cgixxx(anything *params[], int num_surfaces, anything *surf_list[])
{
/* Main entry point */
switch (*(short *)params[0]) {
case ACTIVATE_FN: xactivate(surf_list); break;
case DEACTIVATE_FN: xdeactivate(surf_list); break;
case CI_FN: xci(params, num_surfaces, surf_list); break;
case CT_FN: xct(num_surfaces, surf_list); break;
case CXDFAC_FN: xcxdfac(num_surfaces, surf_list); break;
case CPDS_FN: xcpds(params, num_surfaces, surf_list); break;
case CENDPG_FN: xcendpg(num_surfaces, surf_list); break;
case CBC_FN: xcbc(params, num_surfaces, surf_list); break;
case CVDCX_FN: xcvdcx(params, num_surfaces, surf_list); break;
case CV_FN: xcv(params, num_surfaces, surf_list); break;
case CCL_FN: xccl(params, num_surfaces, surf_list); break;
case CDSCL_FN: xcdscl(params, num_surfaces, surf_list); break;
case CDQERR_FN: xcdqerr(params, surf_list); break;
case CERHCT_FN: xcerhct(params, num_surfaces, surf_list); break;
case CCIXP_FN: xccixp(params, num_surfaces, surf_list); break;
case CESC_FN: xcesc(params, num_surfaces, surf_list); break;
case CQID_FN: xcqid(params, surf_list); break;
case CQD_FN: xcqd(params, surf_list); break;
case CLF_FN: xclf(params, surf_list); break;
case CLPR_FN: xclpr(params, surf_list); break;
case CQSP_FN: xcqsp(params, surf_list); break;
case CLESC_FN: xclesc(params, surf_list); break;
case CQP_FN: xcqp(params, surf_list); break;
case CQCL_FN: xcqcl(params, surf_list); break;
case CPL_FN: xcpl(params, num_surfaces, surf_list); break;
case CDJPL_FN: xcdjpl(params, num_surfaces, surf_list); break;
case CPM_FN: xcpm(params, num_surfaces, surf_list); break;
case CTX_FN: xctx(params, num_surfaces, surf_list); break;
case CPG_FN: xcpg(params, num_surfaces, surf_list); break;
case CCA_FN: xcca(params, num_surfaces, surf_list); break;
case CPXA_FN: xcpxa(params, num_surfaces, surf_list); break;
case CLNT_FN: xclnt(params, num_surfaces, surf_list); break;
case CLNW_FN: xclnw(params, num_surfaces, surf_list); break;
case CLNC_FN: xclnc(params, num_surfaces, surf_list); break;
case CMKT_FN: xcmkt(num_surfaces, surf_list); break;
case CMKS_FN: xcmks(params, num_surfaces, surf_list); break;
case CMKC_FN: xcmkc(params, num_surfaces, surf_list); break;
case CTXP_FN: xctxp(params, num_surfaces, surf_list); break;
case CTXC_FN: xctxc(params, num_surfaces, surf_list); break;
case CCHH_FN: xcchh(params, num_surfaces, surf_list); break;
case CCHO_FN: xccho(params, num_surfaces, surf_list); break;
case CIS_FN: xcis(params, num_surfaces, surf_list); break;
case CFLC_FN: xcflc(params, num_surfaces, surf_list); break;
case CCSM_FN: xccsm(params, num_surfaces, surf_list); break;
case CCT_FN: xcct(params, num_surfaces, surf_list); break;
case CGTXX_FN: xcgtxx(params, surf_list); break;
case CQPRL_FN: xcqprl(params, surf_list); break;
case CQLN_FN: xcqln(params, surf_list); break;
case CQLNT_FN: xcqlnt(params, surf_list); break;
case CQSLW_FN: xcqslw(params, surf_list); break;
case CQMK_FN: xcqmk(params, surf_list); break;
case CQMKT_FN: xcqmkt(params, surf_list); break;
case CQSMS_FN: xcqsms(params, surf_list); break;
case CQCHH_FN: xcqchh(params, surf_list); break;
case CQFL_FN: xcqfl(params, surf_list); break;
case CQC_FN: xcqc(params, surf_list); break;
case CQLNA_FN: xcqlna(params, surf_list); break;
case CQMKA_FN: xcqmka(params, surf_list); break;
case CQTXA_FN: xcqtxa(params, surf_list); break;
case CQFLA_FN: xcqfla(params, surf_list); break;
case CQCTE_FN: xcqcte(params, surf_list); break;
case CILI_FN: xcili(params, surf_list); break;
case CRQLC_FN: xcrqlc(params, surf_list); break;
} /* end switch */
} /* end cgixxx */
/* ACTIVATE */
static void xactivate(anything **surf_list)
{
int new_state; /* index of new state to use */
if (first_free_state >= 0) { /* there is free one, use it */
new_state = first_free_state;
first_free_state = surf_states[new_state].next_free_state;
}
else if (last_alloc_state < MAX_DEVICE_SURFACES - 1) {
new_state = last_alloc_state + 1; /* can alloc one */
++last_alloc_state;
}
else { /* none available */
new_state = -1;
} /* end if */
if (new_state < 0) { /* problem, report error & go away */
surf_list[0] = NULL;
return;
} /* end if problem */
/* got new state, init it */
surf_states[new_state].cgi_inited = CNO;
surf_states[new_state].this_index = new_state; /* save for dealloc */
/* -- for batch devices */
copy_string(surf_states[new_state].filename, DEFAULT_OUTFILE_NAME, 100);
surf_states[new_state].file_d = -1;
/* set surface state_list pointer to point to this state list */
surf_list[0] = (anything *)&(surf_states[new_state]);
} /* end xactivate */
/* DEACTIVATE */
static void xdeactivate(anything **surf_list)
{
/* deallocate memory allocated for cgi state list */
int index; /* which state is this surface linked to */
index = ((surf_statelist *)surf_list[0])->this_index;
if ((index >= 0) && (index < MAX_DEVICE_SURFACES)) {
surf_states[index].next_free_state = first_free_state;
first_free_state = index;
} /* end if */
/* unlink cgi state list from surface */
surf_list[0] = NULL;
} /* end xdeactivate */
/* INITIALIZE */
static void xci(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surf_list */
float zero = 0.;
int izero = 0;
for (i = 0; i < num_surfaces; ++i) {
/* cur_state is global - points to current statelist */
cur_state = (surf_statelist *)surf_list[i];
/* initialize/reinit SVDI and/or set device descript table */
/* -- this needs to happen before calling init_state */
if (cur_state->cgi_inited == CNO) { /* this surface has never been
initialized */
vdinit(&zero, &izero);
/* set device descript table for this device only once */
if (dev_descrip.set_flag == FALSE) {
set_dev_descrip();
dev_descrip.set_flag = TRUE;
} /* end if set_flag */
} /* end if surface not initialized */
else { /* this surface has been initialized once already */
/* reset SVDI attributes */
reset_vdi(cur_state);
/* if prepare drawing surface, issue a new page */
if (*(int *)params[1] == CYES) {
vdnwpg();
}
} /* end else surface initialized */
/* initialize/reinitialize the default device state */
init_state(cur_state);
/* set cgi_inited to initialized */
cur_state->cgi_inited = CYES;
} /* end for each surface */
} /* end xci */
/* TERMINATE */
static void xct(int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* terminate and set state to uninitialized */
vdterm();
cur_state->cgi_inited = CNO;
} /* end for each surface */
} /* end xct */
/* EXECUTE DEFERRED ACTIONS */
static void xcxdfac(int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
vdbufl();
} /* end for each surface */
} /* end xcxdfac */
/* PREPARE DRAWING SURFACE */
static void xcpds(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* new page if page has been marked or parameter is forced */
if (cur_state->pic_dirty == CDIRTY || *(int *)params[1] == CFORCC) {
vdnwpg();
cur_state->pic_dirty = CCLEAN;
}
} /* end for each surface */
} /* end xcpds */
/* END PAGE */
static void xcendpg(int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* perform an implicit execute deferred actions */
vdbufl();
/* for hardcopy, call new page only if page has been marked */
if (dev_descrip.copy_class == CHARD) {
if (cur_state->pic_dirty == CDIRTY) {
vdnwpg();
cur_state->pic_dirty = CCLEAN;
} /* end if dirty page */
}
} /* end for each surface */
} /* end xcendpg */
/* BACKGROUND COLOR */
static void xcbc(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
int bg_color[3]; /* temporary array */
bg_color[0] = *(int *)params[1];
bg_color[1] = *(int *)params[2];
bg_color[2] = *(int *)params[3];
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
set_background_color(cur_state, bg_color);
} /* end for each surface */
} /* end xcbc */
/* VDC EXTENT */
static void xcvdcx(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* store the values in the state list */
/* default integer precision is 16 - check range */
if (*(float *)params[1] > 32767. || *(float *)params[2] > 32767. ||
*(float *)params[3] > 32767. || *(float *)params[4] > 32767. ||
*(float *)params[1] < -32767. || *(float *)params[2] < -32767. ||
*(float *)params[3] < -32767. || *(float *)params[4] < -32767.) {
/* error 1:-103 VDC Extent out of range. Function ignored */
report_error(cur_state, 1, -103, *(short *)params[0]);
return;
} /* end if error */
/* no error */
cur_state->vdc1.x = *(float *)params[1];
cur_state->vdc1.y = *(float *)params[2];
cur_state->vdc2.x = *(float *)params[3];
cur_state->vdc2.y = *(float *)params[4];
/* end else no error */
/* VDC to viewport (in NDC) mapping */
/* -- this routine sets effective viewport in VDC and
NDC (forcing isotropic mapping) and the mapping scale */
set_mapping(cur_state);
/* determine new effective clipping rectangle */
/* ..First figure out the min and max VDC points. Since
* the user cannot change the clip rectangle, the min and
* max clip rectangle points are known. (min = clip_rect1 = [0,0];
* max = clip_rect2 = [32767.,32767.])
*/
/* need to check for degenerate case */
cur_state->eff_clip_rect1.x =
max(min(cur_state->vdc1.x, cur_state->vdc2.x), cur_state->clip_rect1.x);
cur_state->eff_clip_rect1.y =
max(min(cur_state->vdc1.y, cur_state->vdc2.y), cur_state->clip_rect1.y);
cur_state->eff_clip_rect2.x =
min(max(cur_state->vdc1.x, cur_state->vdc2.x), cur_state->clip_rect2.x);
cur_state->eff_clip_rect2.y =
min(max(cur_state->vdc1.y, cur_state->vdc2.y), cur_state->clip_rect2.y);
/* set clipping region */
set_clipping(cur_state);
} /* end for each surface */
} /* end xcvdcx */
/* DEVICE VIEWPORT */
static void xcv(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* viewport - default viewport specification mode is FRACTION OF
* DRAWING SURFACE. Thus, the viewport (0,0),(1,1) corresponds to
* the lower and upper corners, respectively, of the default
* device viewport, which is the largest unrotated rectangular area
* visible on the drawing surface. Numbers outside the range
* [0.0...1.0] may be specified.
*/
/* store values in state list */
cur_state->vp1.x = *(float *)params[1];
cur_state->vp1.y = *(float *)params[2];
cur_state->vp2.x = *(float *)params[3];
cur_state->vp2.y = *(float *)params[4];
/* do VDC to NDC mapping */
/* -- this routine sets effective viewports in VDC and
NDC (forcing isotropic mapping) and the mapping scale */
set_mapping(cur_state);
/* set clipping region */
set_clipping(cur_state);
} /* end for each surface */
} /* end xcv */
/* CLIP INDICATOR */
static void xccl(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* check for a legal enumerated value, store in state table
and set the clipping region */
if (*(int *)params[1] == CON || *(int *)params[1] == COFF) {
cur_state->clip_indicator = *(int *)params[1];
set_clipping(cur_state);
}
else {
/* error 1:-101 Enumerated parameter out of range. Function ignored */
report_error(cur_state, 1, -101, *(short *)params[0]);
}
} /* end for each surface */
} /* end xccl */
/* DRAWING SURFACE CLIP INDICATOR */
static void xcdscl(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* check for a legal enumerated value, store in state table
and set the clipping region */
if (*(int *)params[1] == CDCOFF || *(int *)params[1] == CDCREC || *(int *)params[1] == CVPORT) {
cur_state->ds_clip_indicator = *(int *)params[1];
set_clipping(cur_state);
}
else {
/* error 1:-101 Enumerated parameter out of range. Function ignored */
report_error(cur_state, 1, -101, *(short *)params[0]);
}
} /* end for each surface */
} /* end xcdscl */
/* DEQUEUE ERROR REPORTS */
static void xcdqerr(anything **params, anything **surf_list)
{
int i; /* loop variable */
int max_ret; /* max number of errors to return */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* find the number of errors to be returned */
max_ret = (*(int *)params[1] < cur_state->err_count) ? *(int *)params[1] : cur_state->err_count;
for (i = 0; i < max_ret; i++) {
((int *)params[5])[i] = cur_state->err_queue[cur_state->err_head_ptr].err_class;
((int *)params[6])[i] = cur_state->err_queue[cur_state->err_head_ptr].err_num;
((int *)params[7])[i] = cur_state->err_queue[cur_state->err_head_ptr].func_id;
/* update the head of list ptr */
cur_state->err_head_ptr++;
if (cur_state->err_head_ptr == ERROR_LIST_SIZE) {
cur_state->err_head_ptr = 0;
}
/* decrement the count of errors */
cur_state->err_count--;
} /* end for i */
/* number of reports remaining in the queue */
*(int *)params[3] = cur_state->err_count;
/* number of reports returned */
*(int *)params[4] = i;
/* validity flag */
*(int *)params[2] = CVAL;
} /* end xcdqerr */
/* ERROR HANDLING CONTROL */
static void xcerhct(anything **params, int num_surfaces, anything **surf_list)
{
int i, j; /* loop indices */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* store error control level in state list */
for (j = 0; j < *(int *)params[1]; j++) {
/* check enumeration types */
if (((int *)params[3])[j] != CEHON && ((int *)params[3])[j] != CEHROF &&
((int *)params[3])[j] != CEHDOF) {
/* error 1:-101 Enumerated parameter out of range. Function ignored */
report_error(cur_state, 1, -101, *(short *)params[0]);
/* check for legal index */
}
else if (((int *)params[2])[j] < 1 || ((int *)params[2])[j] > MAX_ERROR_CLASS) {
/* error 1:-102 Index out of range. Function ignored */
report_error(cur_state, 1, -102, *(short *)params[0]);
}
else {
cur_state->err_flag[((int *)params[2])[j] - 1] = ((int *)params[3])[j];
}
} /* end for j */
} /* end for each surface */
} /* end xcerhct */
/* COLOR INDEX PRECISION */
static void xccixp(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
/* I'm not doing anything with color index precision now */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
if (*(int *)params[1] == 8 || *(int *)params[1] == 16 || *(int *)params[1] == 24 ||
*(int *)params[1] == 32) {
cur_state->color_index_prec = *(int *)params[1];
}
else {
/* error 3:204 Selected precision not supported */
report_error(cur_state, 3, 204, *(short *)params[0]);
}
} /* end for each surface */
} /* end xccixp */
/* ESCAPE */
static void xcesc(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
int j; /* loop index */
int first; /* logical; TRUE = first time through */
char data[80]; /* temp for parsing data record */
char c; /* single character */
int vdi_esc; /* used for SVDI escape call */
int count; /* used for SVDI escape call */
float args[10]; /* used for SVDI escape call */
int tokenindex; /* index in data record of first char */
/* after end of token*/
first = TRUE;
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
switch (*(int *)params[1]) {
case XEMFNM: /* file name */
if (first) {
tokenindex = 0; /* first char of data record */
/* params[4] is an added parameter - contains the string length */
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
first = FALSE;
} /* end if first */
/* this function must be called before CI */
/* ...error message if not?? check for legal file name?? */
if (cur_state->cgi_inited != CYES) {
copy_string(cur_state->filename, data, 100);
}
break;
case XEAGMD: /* set terminal to alpha/graphics */
if (first) {
tokenindex = 0; /* first char of data record */
/* params[4] is an added parameter - contains the string length */
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
/* SVDI takes care of 'graphics', check for 'alpha' */
j = 0;
while ((c = data[j++])) {
if (isalpha(c) && isupper(c)) {
data[j - 1] = tolower(c);
}
}
first = FALSE;
} /* end if first */
if (strncmp(data, "alpha", 5) == 0) {
vdbufl();
}
break;
case XESVDI: /* SVDI escape */
if (first) {
tokenindex = 0; /* first char of data record */
/* first token is SVDI escape number */
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
vdi_esc = strtol(data, NULL, 10);
/* second token is number of parameters to SVDI escape */
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
count = strtol(data, NULL, 10);
/* the rest of the tokens contain the arguments */
for (j = 0; j < count && j < 10; j++) {
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
args[j] = (float)strtod(data, NULL);
}
first = FALSE;
} /* end if first */
vdescp(&vdi_esc, &count, args);
break;
case XEPGSZ: /* Page size */
if (first) {
tokenindex = 0; /* first char of data record */
/* first token is page size in x */
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
args[0] = (float)strtod(data, NULL);
/* second token is page size in y */
gettoken(&tokenindex, (int *)params[2], (char *)params[3], 80, data);
args[1] = (float)strtod(data, NULL);
/* page size svdi number is 1400 */
vdi_esc = 1400;
count = 2;
first = FALSE;
} /* end if first */
vdescp(&vdi_esc, &count, args);
break;
case XEBELL: /* Ring the bell */ vdbell(); break;
default:
/* error 2:001 Request unsupported feature. Function ignored */
report_error(cur_state, 2, 001, *(short *)params[0]);
break;
} /* end switch */
} /* end for i */
} /* end xcesc */
/* INQUIRE DEVICE IDENTIFICATION */
static void xcqid(anything **params, anything **surf_list)
{
char *cgi_devid; /* pointer to character device id */
int maxchr; /* max number of chars in device id */
int qdc_index = 23; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set yet */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* device id */
vdiqdc(&qdc_index, &value);
cgi_devid = get_devid_char(value);
if (cgi_devid != NULL) {
copy_string(dev_descrip.dev_id, cgi_devid, 4);
}
} /* end if not set */
/* response validity */
*(int *)params[2] = CVAL;
/* return device class - this is set in set_dev_descrip() */
*(int *)params[3] = dev_descrip.dev_class;
/* return device id */
maxchr = (*(int *)params[1] > 3) ? 3 : *(int *)params[1];
copy_string((char *)params[4], dev_descrip.dev_id, maxchr);
} /* end xcqid */
/* INQUIRE DEVICE DESCRIPTION */
static void xcqd(anything **params, anything **surf_list)
{
int qdc_index; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* display type */
qdc_index = 2;
vdiqdc(&qdc_index, &value);
if (value == 0.) {
dev_descrip.display_type = CVECT;
}
else if (value == 1.) {
dev_descrip.display_type = CRAST;
}
else {
dev_descrip.display_type = COTHER;
}
/* background color capability */
qdc_index = 32;
vdiqdc(&qdc_index, &value);
dev_descrip.bcolor_cap = (value == 1.0) ? CYES : CNO;
/* dynamic modification for background color */
dev_descrip.dynamic_mod_bg = CIRG;
/* dynamic modification for VDC to device mapping */
dev_descrip.dynamic_mod_map = CIRG;
/* width and height in millimeters */
/* ...SVDI returns 0 if it doesn't know. CGI does this also */
qdc_index = 17;
vdiqdc(&qdc_index, &dev_descrip.draw_surf_width);
qdc_index = 18;
vdiqdc(&qdc_index, &dev_descrip.draw_surf_height);
/* pixel location relative to coordinates */
dev_descrip.pix_loc = CPXON;
} /* end haven't been set */
/* validity flag */
*(int *)params[1] = CVAL;
/* stuff info into return values */
/* ...copy_class and device corners are set in set_dev_descrip() */
*(int *)params[2] = dev_descrip.copy_class;
*(int *)params[3] = dev_descrip.display_type;
*(int *)params[4] = dev_descrip.bcolor_cap;
*(int *)params[5] = dev_descrip.dynamic_mod_bg;
*(int *)params[6] = dev_descrip.dynamic_mod_map;
*(int *)params[7] = dev_descrip.dc1.x;
*(int *)params[8] = dev_descrip.dc1.y;
*(int *)params[9] = dev_descrip.dc2.x;
*(int *)params[10] = dev_descrip.dc2.y;
*(float *)params[11] = dev_descrip.draw_surf_width;
*(float *)params[12] = dev_descrip.draw_surf_height;
*(int *)params[13] = dev_descrip.pix_loc;
} /* end xcqd */
/* LOOKUP FUNCTION SUPPORT */
static void xclf(anything **params, anything **surf_list)
{
int i; /* index for loop on surfaces */
int qdc_index = 24; /* for inquire SVDI */
static float poly_support = -1.; /* level of SVDI poly support */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
for (i = 0; i < *(int *)params[1]; i++) {
switch (*(short *)params[0]) {
case ACTIVATE_FN: ((int *)params[5])[i] = CSYES; break;
case DEACTIVATE_FN: ((int *)params[5])[i] = CSYES; break;
case CI_FN: ((int *)params[5])[i] = CSYES; break;
case CT_FN: ((int *)params[5])[i] = CSYES; break;
case CXDFAC_FN: ((int *)params[5])[i] = CSYES; break;
case CPDS_FN: ((int *)params[5])[i] = CSYES; break;
case CENDPG_FN: ((int *)params[5])[i] = CSYES; break;
case CBC_FN: ((int *)params[5])[i] = CSYES; break;
case CVDCX_FN: ((int *)params[5])[i] = CSYES; break;
case CV_FN: ((int *)params[5])[i] = CSYES; break;
case CCL_FN: ((int *)params[5])[i] = CSYES; break;
case CDSCL_FN: ((int *)params[5])[i] = CSYES; break;
case CDQERR_FN: ((int *)params[5])[i] = CSYES; break;
case CERHCT_FN: ((int *)params[5])[i] = CSYES; break;
case CCIXP_FN: ((int *)params[5])[i] = CSNO; break;
case CESC_FN: ((int *)params[5])[i] = CSYES; break;
case CQID_FN: ((int *)params[5])[i] = CSYES; break;
case CQD_FN: ((int *)params[5])[i] = CSYES; break;
case CLF_FN: ((int *)params[5])[i] = CSYES; break;
case CLPR_FN: ((int *)params[5])[i] = CSYES; break;
case CQSP_FN: ((int *)params[5])[i] = CSYES; break;
case CLESC_FN: ((int *)params[5])[i] = CSYES; break;
case CQP_FN: ((int *)params[5])[i] = CSYES; break;
case CQCL_FN: ((int *)params[5])[i] = CSYES; break;
case CPL_FN: ((int *)params[5])[i] = CSYES; break;
case CDJPL_FN: ((int *)params[5])[i] = CSYES; break;
case CPM_FN: ((int *)params[5])[i] = CSYES; break;
case CTX_FN: ((int *)params[5])[i] = CSYES; break;
case CPG_FN:
if (poly_support == -1.) {
vdiqdc(&qdc_index, &poly_support);
}
if (poly_support < 3.) {
((int *)params[5])[i] = CSNO;
}
else {
((int *)params[5])[i] = CSYES;
}
break;
case CCA_FN: ((int *)params[5])[i] = CSYES; break;
case CPXA_FN: ((int *)params[5])[i] = CSYES; break;
case CLNT_FN: ((int *)params[5])[i] = CSYES; break;
case CLNW_FN: ((int *)params[5])[i] = CSYES; break;
case CLNC_FN: ((int *)params[5])[i] = CSYES; break;
case CMKT_FN: ((int *)params[5])[i] = CSYES; break;
case CMKS_FN: ((int *)params[5])[i] = CSNO; break;
case CMKC_FN: ((int *)params[5])[i] = CSYES; break;
case CTXP_FN: ((int *)params[5])[i] = CSNO; break;
case CTXC_FN: ((int *)params[5])[i] = CSNO; break;
case CCHH_FN: ((int *)params[5])[i] = CSYES; break;
case CCHO_FN: ((int *)params[5])[i] = CSNO; break;
case CIS_FN: ((int *)params[5])[i] = CSYES; break;
case CFLC_FN: ((int *)params[5])[i] = CSYES; break;
case CCSM_FN: ((int *)params[5])[i] = CSYES; break;
case CCT_FN: ((int *)params[5])[i] = CSYES; break;
case CGTXX_FN: ((int *)params[5])[i] = CSYES; break;
case CQPRL_FN: ((int *)params[5])[i] = CSYES; break;
case CQLN_FN: ((int *)params[5])[i] = CSYES; break;
case CQLNT_FN: ((int *)params[5])[i] = CSYES; break;
case CQSLW_FN: ((int *)params[5])[i] = CSNO; break;
case CQMK_FN: ((int *)params[5])[i] = CSNO; break;
case CQMKT_FN: ((int *)params[5])[i] = CSYES; break;
case CQSMS_FN: ((int *)params[5])[i] = CSNO; break;
case CQCHH_FN: ((int *)params[5])[i] = CSYES; break;
case CQFL_FN: ((int *)params[5])[i] = CSYES; break;
case CQC_FN: ((int *)params[5])[i] = CSYES; break;
case CQLNA_FN: ((int *)params[5])[i] = CSYES; break;
case CQMKA_FN: ((int *)params[5])[i] = CSNO; break;
case CQTXA_FN: ((int *)params[5])[i] = CSYES; break;
case CQFLA_FN: ((int *)params[5])[i] = CSNO; break;
case CQCTE_FN: ((int *)params[5])[i] = CSYES; break;
case CILI_FN: ((int *)params[5])[i] = CSYES; break;
case CRQLC_FN: ((int *)params[5])[i] = CSYES; break;
default: ((int *)params[5])[i] = CSNO; break;
} /* end switch */
}
/* validity flag */
*(int *)params[4] = CVAL;
} /* end xclf */
/* LOOKUP PROFILE SUPPORT */
static void xclpr(anything **params, anything **surf_list)
{
int i; /* index for loop on surfaces */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
for (i = 0; i < *(int *)params[1]; i++) {
if (strncmp(((char **)params[2])[i], "1-WAY-OUTPUT", 12) != 0 ||
strncmp(((char **)params[2])[i], "2-WAY-OUTPUT", 12) ||
strncmp(((char **)params[2])[i], "SLATEC 1", 8) != 0) {
((int *)params[4])[i] = CSYES;
}
else {
((int *)params[4])[i] = CSNO;
}
}
/* validity flag */
*(int *)params[3] = CVAL;
} /* end xclpr */
/* INQUIRE SUPPORTED PRECISIONS */
static void xcqsp(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* this stuff is basically machine dependent. I return INVAL and
leave it at that */
*(int *)params[1] = CINVAL;
} /* end xcqsp */
/* LOOKUP ESCAPE SUPPORT */
static void xclesc(anything **params, anything **surf_list)
{
int i; /* loop index */
int esc = 1400; /* for inquire escape */
int support; /* for inquire escape */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
for (i = 0; i < *(int *)params[1]; i++) {
/* return YES for supported escapes, else return NO */
switch (((int *)params[2])[i]) {
case XEMFNM: ((int *)params[4])[i] = CSYES; break;
case XEAGMD: ((int *)params[4])[i] = CSYES; break;
case XESVDI: ((int *)params[4])[i] = CSYES; break;
case XEBELL: ((int *)params[4])[i] = CSYES; break;
case XEPGSZ:
vdiqes(&esc, &support);
if (support == 1 || support == 2) {
((int *)params[4])[i] = CSYES;
}
else {
((int *)params[4])[i] = CSNO;
}
break;
default: ((int *)params[4])[i] = CSNO; break;
} /* end switch */
}
/* validity flag */
*(int *)params[3] = CVAL;
} /* end xclesc */
/* INQUIRE CURRENT PRECISIONS */
static void xcqp(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* validity flag */
*(int *)params[1] = CINVAL;
} /* end xcqp */
/* INQUIRE CLIPPING */
static void xcqcl(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* clip indicator */
*(int *)params[2] = cur_state->clip_indicator;
/* clip rectangle */
((float *)params[3])[0] = cur_state->clip_rect1.x;
((float *)params[3])[1] = cur_state->clip_rect1.y;
((float *)params[3])[2] = cur_state->clip_rect2.x;
((float *)params[3])[3] = cur_state->clip_rect2.y;
/* drawing surface clip indicator */
*(int *)params[4] = cur_state->ds_clip_indicator;
/* drawing surface clip rectangle */
/* Default is the whole drawing surface; routines to change the
* drawing surface clip rectangle are not included. Since veiwport
* specification mode is FRACTION OF DRAWING SURFACE, units for
* rectangle are 0 - 1 */
((float *)params[5])[0] = 0.;
((float *)params[5])[1] = 0.;
((float *)params[5])[2] = 1.;
((float *)params[5])[3] = 1.;
/* validity flag */
*(int *)params[1] = CVAL;
} /* end xcqcl */
/* POLYLINE */
static void xcpl(anything **params, int num_surfaces, anything **surf_list)
{
int i, j; /* indices for loops */
int np; /* number of points in polyline */
float prev_x, prev_y; /* line end points */
float cur_x, cur_y; /* line end points */
float save_x, save_y; /* used for clipping */
int prev_code, cur_code; /* encoded endpoints - for clipping */
int mode = 0, done; /* stuff used for clipping */
static unsigned mask = ~(~0u << 1); /* for masking off bits */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* do some error checking */
if (MAX_POLYLINE != -1 && *(int *)params[1] > MAX_POLYLINE) {
/* error 6:301 - Number of points too large. Max is used */
report_error(cur_state, 6, 301, *(short *)params[0]);
np = MAX_POLYLINE;
}
else {
np = *(int *)params[1];
}
/* set SVDI foreground color if needed */
set_foreground_color(cur_state, cur_state->line_color);
/* take a short cut if no clipping is on */
if (!cur_state->clip_on) {
for (j = 0; j < np; j++) {
/* map VDC to NDC */
cur_x = *((float *)params[2] + j) * cur_state->xscale + cur_state->xoffset;
cur_y = *((float *)params[3] + j) * cur_state->yscale + cur_state->yoffset;
if (j == 0) {
vdmova(&cur_x, &cur_y);
}
else {
vdlina(&cur_x, &cur_y);
}
} /* end for j */
} /* end no clipping on */
else { /* clipping is on */
/* This clipping algorithm is loosely based on the Cohen-
* Sutherland algorithm. This algorithm takes into account
* the fact that points are consecutive, ie., it tries to
* encode each point only once. Everything is done
* inline for efficiency
*/
/* convert VDC to NDC */
prev_x = *((float *)params[2]) * cur_state->xscale + cur_state->xoffset;
prev_y = *((float *)params[3]) * cur_state->yscale + cur_state->yoffset;
/* encode the point */
prev_code = 0;
if ((cur_state->clipmax.y - prev_y) < 0) {
prev_code = prev_code | (1 << 3);
}
else if ((prev_y - cur_state->clipmin.y) < 0) {
prev_code = prev_code | (1 << 2);
}
if ((cur_state->clipmax.x - prev_x) < 0) {
prev_code = prev_code | (1 << 1);
}
else if ((prev_x - cur_state->clipmin.x) < 0) {
prev_code = prev_code | (1 << 0);
}
if (!prev_code) {
vdmova(&prev_x, &prev_y);
}
j = 0;
while (++j < np) {
/* convert VDC to NDC */
cur_x = *((float *)params[2] + j) * cur_state->xscale + cur_state->xoffset;
cur_y = *((float *)params[3] + j) * cur_state->yscale + cur_state->yoffset;
/* encode the endpoint */
cur_code = 0;
if ((cur_state->clipmax.y - cur_y) < 0) {
cur_code = cur_code | (1 << 3);
}
else if ((cur_y - cur_state->clipmin.y) < 0) {
cur_code = cur_code | (1 << 2);
}
if ((cur_state->clipmax.x - cur_x) < 0) {
cur_code = cur_code | (1 << 1);
}
else if ((cur_x - cur_state->clipmin.x) < 0) {
cur_code = cur_code | (1 << 0);
}
/* determine which case this is */
if (!prev_code && !cur_code) { /* trivial accept */
vdlina(&cur_x, &cur_y);
prev_x = cur_x;
prev_y = cur_y;
done = TRUE;
} /* end trivial accept */
else if (prev_code & cur_code) { /* trivial reject */
prev_x = cur_x;
prev_y = cur_y;
prev_code = cur_code;
done = TRUE;
}
else {
done = FALSE;
if (prev_code) {
if (cur_code) {
mode = 2; /* both out */
}
else {
mode = 1; /* prev out; cur in */
}
}
else {
mode = 3; /* prev in; cur out */
}
}
while (!done) {
switch (mode) {
case 1: /* prev out, cur in... clip */
case 2: /* both out, clip prev first */
if (prev_code & mask) { /* clip at left edge */
prev_y =
prev_y + (cur_y - prev_y) * (cur_state->clipmin.x - prev_x) / (cur_x - prev_x);
prev_x = cur_state->clipmin.x;
}
else if ((prev_code >> 1) & mask) { /* clip at right edge */
prev_y =
prev_y + (cur_y - prev_y) * (cur_state->clipmax.x - prev_x) / (cur_x - prev_x);
prev_x = cur_state->clipmax.x;
}
if ((prev_code >> 2) & mask) { /* clip at bottom edge */
prev_x =
prev_x + (cur_x - prev_x) * (cur_state->clipmin.y - prev_y) / (cur_y - prev_y);
prev_y = cur_state->clipmin.y;
}
else if ((prev_code >> 3) & mask) { /* clip at top edge */
prev_x =
prev_x + (cur_x - prev_x) * (cur_state->clipmax.y - prev_y) / (cur_y - prev_y);
prev_y = cur_state->clipmax.y;
}
switch (mode) {
case 1: /* not looping through, draw it */
vdmova(&prev_x, &prev_y);
vdlina(&cur_x, &cur_y);
prev_x = cur_x;
prev_y = cur_y;
prev_code = cur_code;
done = TRUE;
break;
case 2: /* both were out, encode new point */
prev_code = 0;
if ((cur_state->clipmax.y - prev_y) < 0) {
prev_code = prev_code | (1 << 3);
}
else if ((prev_y - cur_state->clipmin.y) < 0) {
prev_code = prev_code | (1 << 2);
}
if ((cur_state->clipmax.x - prev_x) < 0) {
prev_code = prev_code | (1 << 1);
}
else if ((prev_x - cur_state->clipmin.x) < 0) {
prev_code = prev_code | (1 << 0);
}
if (prev_code) { /* reject it */
prev_x = cur_x;
prev_y = cur_y;
prev_code = cur_code;
done = TRUE;
}
else { /* prev is in */
vdmova(&prev_x, &prev_y);
mode = 3; /* cur is still out, go through again */
}
break;
} /* end inner switch */
break;
case 3: /* prev in, cur out...clip */
save_x = cur_x;
save_y = cur_y;
if (cur_code & mask) { /* clip at left edge */
cur_y = cur_y + (prev_y - cur_y) * (cur_state->clipmin.x - cur_x) / (prev_x - cur_x);
cur_x = cur_state->clipmin.x;
}
else if ((cur_code >> 1) & mask) { /* clip at right edge */
cur_y = cur_y + (prev_y - cur_y) * (cur_state->clipmax.x - cur_x) / (prev_x - cur_x);
cur_x = cur_state->clipmax.x;
}
if ((cur_code >> 2) & mask) { /* clip at bottom edge */
cur_x = cur_x + (prev_x - cur_x) * (cur_state->clipmin.y - cur_y) / (prev_y - cur_y);
cur_y = cur_state->clipmin.y;
}
else if ((cur_code >> 3) & mask) { /* clip at top edge */
cur_x = cur_x + (prev_x - cur_x) * (cur_state->clipmax.y - cur_y) / (prev_y - cur_y);
cur_y = cur_state->clipmax.y;
}
vdlina(&cur_x, &cur_y);
prev_x = save_x;
prev_y = save_y;
prev_code = cur_code;
done = TRUE;
break;
default: done = TRUE; break;
} /* end switch */
} /* end while !done */
} /* end while j*/
} /* end else clipping is on */
/* flag that the page has been marked */
cur_state->pic_dirty = CDIRTY;
} /* end for i */
} /* end xcpl */
/* DISJOINT POLYLINE */
static void xcdjpl(anything **params, int num_surfaces, anything **surf_list)
{
int i, j; /* indices for loops */
int np; /* number of points in polyline */
float x1, y1, x2, y2; /* line endpoints in NDC */
int code1, code2; /* encoded endpoints for clipping */
int mode = 0, done; /* variables used for clipping */
static unsigned mask = ~(~0u << 1); /* for masking off bits */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* check for errors */
if (MAX_DJ_POLYLINE != -1 && *(int *)params[1] > MAX_DJ_POLYLINE) {
/* error 6:301 - Number of points too large. Max is used */
report_error(cur_state, 6, 301, *(short *)params[0]);
np = MAX_DJ_POLYLINE;
}
else {
np = *(int *)params[1];
}
/* set SVDI foreground color if needed */
set_foreground_color(cur_state, cur_state->line_color);
/* if clipping is off, just do it */
if (!cur_state->clip_on) {
for (j = 0; j < np - 1; j = j + 2) {
/* map VDC to NDC */
x1 = *((float *)params[2] + j) * cur_state->xscale + cur_state->xoffset;
y1 = *((float *)params[3] + j) * cur_state->yscale + cur_state->yoffset;
x2 = *((float *)params[2] + j + 1) * cur_state->xscale + cur_state->xoffset;
y2 = *((float *)params[3] + j + 1) * cur_state->yscale + cur_state->yoffset;
vdmova(&x1, &y1);
vdlina(&x2, &y2);
} /* end for j */
} /* end if clipping is off */
else { /* clipping is on */
/* Clip a line. Kind of based on Cohen-Sutherland algorithm.
* Everything is done inline for efficiency.
*/
for (j = 0; j < np - 1; j = j + 2) {
/* map VDC to NDC */
x1 = *((float *)params[2] + j) * cur_state->xscale + cur_state->xoffset;
y1 = *((float *)params[3] + j) * cur_state->yscale + cur_state->yoffset;
x2 = *((float *)params[2] + j + 1) * cur_state->xscale + cur_state->xoffset;
y2 = *((float *)params[3] + j + 1) * cur_state->yscale + cur_state->yoffset;
/* encode the two points */
code1 = 0;
if ((cur_state->clipmax.y - y1) < 0) {
code1 = code1 | (1 << 3);
}
else if ((y1 - cur_state->clipmin.y) < 0) {
code1 = code1 | (1 << 2);
}
if ((cur_state->clipmax.x - x1) < 0) {
code1 = code1 | (1 << 1);
}
else if ((x1 - cur_state->clipmin.x) < 0) {
code1 = code1 | (1 << 0);
}
code2 = 0;
if ((cur_state->clipmax.y - y2) < 0) {
code2 = code2 | (1 << 3);
}
else if ((y2 - cur_state->clipmin.y) < 0) {
code2 = code2 | (1 << 2);
}
if ((cur_state->clipmax.x - x2) < 0) {
code2 = code2 | (1 << 1);
}
else if ((x2 - cur_state->clipmin.x) < 0) {
code2 = code2 | (1 << 0);
}
/* determine which case this is */
if (!code1 && !code2) { /* trivial accept - draw it */
vdmova(&x1, &y1);
vdlina(&x2, &y2);
done = TRUE;
} /* end trivial accept */
else if (code1 & code2) { /* trivial reject - do nothing */
done = TRUE;
}
else {
done = FALSE;
if (code1) {
if (code2) {
mode = 2; /* both out */
}
else {
mode = 1; /* x1,y1 out; x2,y2 in */
}
}
else {
mode = 3; /* x1,y1 in; x2,y2 out */
}
}
while (!done) {
switch (mode) {
case 1: /* x1,y1 out, x2,y2 in... clip x1,y1*/
case 2: /* both out, clip x1,y1 first */
if (code1 & mask) { /* clip at left edge */
y1 = y1 + (y2 - y1) * (cur_state->clipmin.x - x1) / (x2 - x1);
x1 = cur_state->clipmin.x;
}
else if ((code1 >> 1) & mask) { /* clip at right edge */
y1 = y1 + (y2 - y1) * (cur_state->clipmax.x - x1) / (x2 - x1);
x1 = cur_state->clipmax.x;
}
if ((code1 >> 2) & mask) { /* clip at bottom edge */
x1 = x1 + (x2 - x1) * (cur_state->clipmin.y - y1) / (y2 - y1);
y1 = cur_state->clipmin.y;
}
else if ((code1 >> 3) & mask) { /* clip at top edge */
x1 = x1 + (x2 - x1) * (cur_state->clipmax.y - y1) / (y2 - y1);
y1 = cur_state->clipmax.y;
}
switch (mode) {
case 1: /* not looping through, draw it */
vdmova(&x1, &y1);
vdlina(&x2, &y2);
done = TRUE;
break;
case 2: /* both were out, encode new point */
code1 = 0;
if ((cur_state->clipmax.y - y1) < 0) {
code1 = code1 | (1 << 3);
}
else if ((y1 - cur_state->clipmin.y) < 0) {
code1 = code1 | (1 << 2);
}
if ((cur_state->clipmax.x - x1) < 0) {
code1 = code1 | (1 << 1);
}
else if ((x1 - cur_state->clipmin.x) < 0) {
code1 = code1 | (1 << 0);
}
if (code1) {
done = TRUE; /* new point is out, reject */
}
else {
mode = 3; /* x1,y1 in; x2,y2 out; clip x2,y2 */
}
break;
} /* end inner switch */
break;
case 3: /* x1,y1 in, x2,y2 out...clip */
if (code2 & mask) { /* clip at left edge */
y2 = y2 + (y1 - y2) * (cur_state->clipmin.x - x2) / (x1 - x2);
x2 = cur_state->clipmin.x;
}
else if ((code2 >> 1) & mask) { /* clip at right edge */
y2 = y2 + (y1 - y2) * (cur_state->clipmax.x - x2) / (x1 - x2);
x2 = cur_state->clipmax.x;
}
if ((code2 >> 2) & mask) { /* clip at bottom edge */
x2 = x2 + (x1 - x2) * (cur_state->clipmin.y - y2) / (y1 - y2);
y2 = cur_state->clipmin.y;
}
else if ((code2 >> 3) & mask) { /* clip at top edge */
x2 = x2 + (x1 - x2) * (cur_state->clipmax.y - y2) / (y1 - y2);
y2 = cur_state->clipmax.y;
}
vdmova(&x1, &y1);
vdlina(&x2, &y2);
done = TRUE;
break;
default: done = TRUE; break;
} /* end switch */
} /* end while !done */
} /* end for j */
} /* end else clipping is on */
/* flag that the page has been marked */
cur_state->pic_dirty = CDIRTY;
} /* end for i */
} /* end xcdjpl */
/* POLYMARKER */
static void xcpm(anything **params, int num_surfaces, anything **surf_list)
{
int i, j; /* indices for loops */
int np; /* number of points */
float *x, *y; /* x,y values */
float x_vdi, y_vdi; /* x,y values in NDC */
int ok; /* flag TRUE =mark lies in clip region */
for (i = 0; i < num_surfaces; ++i) {
np = *(int *)params[1];
x = (float *)params[2];
y = (float *)params[3];
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* check for errors */
if (MAX_POLYMARKER != -1 && *(int *)params[1] > MAX_POLYMARKER) {
/* error 6:301 - Number of points too large. Max is used */
report_error(cur_state, 6, 301, *(short *)params[0]);
np = MAX_POLYMARKER;
}
else {
np = *(int *)params[1];
}
/* set SVDI foreground color if needed */
set_foreground_color(cur_state, cur_state->mark_color);
/* set marker type */
/* --only support "dot" for now - so nothing to set */
/* set marker size */
/* --only support "dot" for now - so nothing to set */
for (j = 0; j < np; j++) {
/* map VDC to NDC */
x_vdi = x[j] * cur_state->xscale + cur_state->xoffset;
y_vdi = y[j] * cur_state->yscale + cur_state->yoffset;
ok = TRUE;
if (cur_state->clip_on) { /* clip is on */
/* ...clip the whole polymarker - it's in or it's out */
ok = ((x_vdi <= cur_state->clipmax.x && x_vdi >= cur_state->clipmin.x) &&
(y_vdi <= cur_state->clipmax.y && y_vdi >= cur_state->clipmin.y));
}
if (ok) {
vdpnta(&x_vdi, &y_vdi);
}
} /* end for j */
/* flag that the page has been marked */
cur_state->pic_dirty = CDIRTY;
} /* end for i */
} /* end xcpm */
/* TEXT */
static void xctx(anything **params, int num_surfaces, anything **surf_list)
{
int i, j; /* indices for loops */
float x, y; /* x,y starting position */
char *ch; /* input character string */
char c; /* 1 character */
int np; /* number of chars in text string */
int ich[MAX_TEXT_LENGTH]; /* array of ascii chars to pass SVDI */
int ok; /* flag TRUE =line lies in clip region */
float temp_array[14]; /* used for SVDI inquiries */
float char_height; /* char height, in VDC or NDC */
float char_width; /* char width, in VDC or NDC */
int skip; /* nbr of chars to skip when clipping */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* error checking */
if (*(int *)params[3] != CFINAL) {
/* compound text not supported */
/* error 2:001 - Request for unsupported feature. Function ignored */
report_error(cur_state, 2, 001, *(short *)params[0]);
break;
}
/* params[5] is an added parameter which is length of string */
else if (MAX_TEXT_LENGTH != -1 && *(int *)params[5] > MAX_TEXT_LENGTH) {
/* error 6:301 - Number of points too large. Max is used */
report_error(cur_state, 6, 301, *(short *)params[0]);
np = MAX_TEXT_LENGTH;
}
else {
np = *(int *)params[5];
}
/* if there is nothing to draw, break */
if (np <= 0) {
break;
}
/* set SVDI foreground color if needed */
set_foreground_color(cur_state, cur_state->text_color);
/* find out what the SVDI character height/width is */
vdiqos(&temp_array[1]);
/* convert stuff to NDC */
char_width = temp_array[7];
char_height = temp_array[6];
/* map VDC to NDC */
x = *(float *)params[1] * cur_state->xscale + cur_state->xoffset;
y = *(float *)params[2] * cur_state->yscale + cur_state->yoffset;
ok = TRUE;
skip = 0;
/* this text clipping assumes no backspaces, etc.,and only the
* default character orientation.
*/
if (cur_state->clip_on) { /* clipping is on, do it */
/* if the string doesn't fit in y, reject it */
ok = (y >= cur_state->clipmin.y && (y + char_height) <= cur_state->clipmax.y);
if (ok) { /* ok in y, check it in x */
/* check for trivial reject */
ok = (x < cur_state->clipmax.x && (x + (np * char_width)) > cur_state->clipmin.x);
if (ok) { /* it's in there, clip it */
/* clip to left edge */
if (x < cur_state->clipmin.x) {
/* ...compute how many chars to skip */
skip = ceil((cur_state->clipmin.x - x) / char_width);
/* ...compute new x */
x = x + ((float)skip * char_width);
/* ...compute new number of chars */
np = np - skip;
}
/* clip to right edge */
if (x + (np * char_width) > cur_state->clipmax.x) {
/* ...compute how many chars fit */
np = (int)((cur_state->clipmax.x - x) / char_width);
}
} /* end if ok in x */
} /* end if ok in y */
} /* end if clip_on */
ok = ok && np > 0; /* make sure there is still some text left */
if (ok) { /* everything is still ok */
/* move to position, and draw the text */
vdmova(&x, &y);
ch = &(((char *)params[4])[skip]);
for (j = 0; j < np; j++) {
c = *ch++;
/* this works for ASCII machines */
ich[j] = (int)c;
}
vdtext(&j, ich);
} /* end if ok */
} /* end for each surface */
} /* end xctx */
/* POLYGON */
static void xcpg(anything **params, int num_surfaces, anything **surf_list)
{
int i, j; /* indices for loops */
int np; /* number of points */
float *x, *y; /* x,y VDC values */
float xnew[MAX_POLYGON]; /* clipped x,y values (VDC or NDC) */
float ynew[MAX_POLYGON];
int npnew; /* number of points after clip */
float temp_array[14]; /* temp used for SVDI inquire */
int qdc_index; /* for inquire SVDI */
int vdi_ls; /* SVDI linestyle */
int ok; /* flag TRUE =line lies in clip region */
static float poly_support = -1.; /* save whether SVDI does polygons */
static float vdi_polymax = -1.; /* store SVDI polygon max value */
/* find out SVDI support for polygons. */
if (poly_support == -1.) {
qdc_index = 24;
vdiqdc(&qdc_index, &poly_support);
}
/* get and store max polygon points from SVDI */
if (vdi_polymax == -1.) {
qdc_index = 25;
vdiqdc(&qdc_index, &vdi_polymax);
}
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* error checking */
if (MAX_POLYGON != -1 && (*(int *)params[1] > MAX_POLYGON || *(int *)params[1] > vdi_polymax)) {
/* error 6:302 - Number of points in polygon too large. Max used */
report_error(cur_state, 6, 302, *(short *)params[0]);
np = (MAX_POLYGON < vdi_polymax) ? MAX_POLYGON : vdi_polymax;
}
else {
np = *(int *)params[1];
}
x = (float *)params[2];
y = (float *)params[3];
/* set SVDI foreground color if needed */
set_foreground_color(cur_state, cur_state->fill_color);
/* map VDC to NDC */
for (j = 0; j < np; j++) {
xnew[j] = *x++ * cur_state->xscale + cur_state->xoffset;
ynew[j] = *y++ * cur_state->yscale + cur_state->yoffset;
} /* end for j */
ok = TRUE;
if (cur_state->clip_on) { /* clip is on */
/* poly clip returns new x,y values and a count */
/* this routine should be done inline for efficiency */
ok = poly_clip(&cur_state->clipmin, &cur_state->clipmax, xnew, ynew, np, xnew, ynew, &npnew);
}
else { /* no clpping */
npnew = np;
}
if (ok) { /* everything's ok, do the polygon */
/* if hollow or if no polygon support, draw the border lines.
if solid, call vdpoly */
if ((cur_state->interior_style == CHOLLO) || /* hallow OR */
(poly_support < 3.)) { /*no poly supp */
vdiqos(&temp_array[1]); /* make sure line style is solid */
if (temp_array[4] != 0) {
vdi_ls = 0;
vdstls(&vdi_ls);
}
vdmova(&xnew[0], &ynew[0]);
for (j = 1; j < npnew; j++) {
vdlina(&xnew[j], &ynew[j]);
}
vdlina(&xnew[0], &ynew[0]);
if (temp_array[4] != 0) { /* set line style back */
vdi_ls = (int)temp_array[4];
vdstls(&vdi_ls);
}
} /* end if hollow OR no poly support */
else { /* solid polygon */
vdpoly(xnew, ynew, &npnew);
}
/* flag that the page has been marked */
cur_state->pic_dirty = CDIRTY;
} /*end if ok */
} /* end for i */
} /* end xcpg */
/* CELL ARRAY */
static void xcca(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
int j, k; /* loop indices */
int index, index_inc, count; /* array indices */
int nx, ny; /* number of cells in x,y */
int nx1, ny1; /* number of cells in x,y after clipping */
int *cells; /* color values */
int ix, iy, yinc; /* SVDI logical raster coordinates */
float x1, x2, y1, y2; /* corners of rectangle in NDC */
float xmin, xmax, ymin, ymax; /* SVDI raster viewport (NDC) */
int xdir, ydir; /* x,y directions on the device */
int imap;
float xcell, ycell; /* area per cell */
int ok; /* flag TRUE =line lies in clip region */
int skipx, skipy; /* number of cells clipped in xmin,ymin */
/* if there isn't anything to draw, return */
if (*(int *)params[7] == 0 || *(int *)params[8] == 0) {
return;
}
/* if cell array has negative dimension, use absolute values */
nx = nx1 = abs(*(int *)params[7]);
ny = ny1 = abs(*(int *)params[8]);
cells = (int *)params[10];
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* if color selection mode is in error, ignore function */
if (cur_state->csm == -1) {
break;
}
/* for now, only allow 4 cases (same as pixel array),
* where nx runs only horizontal, and ny runs vertical.
* this routine needs to be fixed to allow all 8 cases
* Also, this routine does not allow skewing.
*/
if (*(float *)params[2] != *(float *)params[6] || *(float *)params[3] != *(float *)params[5]) {
/* error 1:-106 Illegal cell array. Function ignored */
report_error(cur_state, 1, -106, *(short *)params[0]);
return;
}
/* map corners to NDC */
x1 = *(float *)params[1] * cur_state->xscale + cur_state->xoffset;
x2 = *(float *)params[3] * cur_state->xscale + cur_state->xoffset;
y1 = *(float *)params[2] * cur_state->yscale + cur_state->yoffset;
y2 = *(float *)params[4] * cur_state->yscale + cur_state->yoffset;
/* figure out the raster viewport limits, and figure
* out x and y directions based on mappings and
* rectangle orientation.
*/
if (x1 < x2) {
xmin = x1;
xmax = x2;
xdir = CINCR;
}
else {
xmin = x2;
xmax = x1;
xdir = CDECR;
}
if (y1 < y2) {
ymin = y1;
ymax = y2;
ydir = CINCR;
}
else {
ymin = y2;
ymax = y1;
ydir = CDECR;
}
ok = TRUE;
skipx = skipy = 0;
if (cur_state->clip_on) { /* clipping is on, do it */
/* trivial reject */
ok = ((xmin < cur_state->clipmax.x && xmax > cur_state->clipmin.x) &&
(ymin < cur_state->clipmax.y && ymax > cur_state->clipmin.y));
if (ok) { /* it's in there, clip it */
/* clip in x first */
xcell = (xmax - xmin) / nx; /* area per cell */
/* clip at left edge */
if (xmin < cur_state->clipmin.x) {
/* ...compute how many cells to skip */
skipx = ceil((cur_state->clipmin.x - xmin) / xcell);
/* ...compute new xmin */
xmin = xmin + ((float)skipx * xcell);
/* ...compute new nx */
nx1 = nx - skipx;
} /* end clip at left edge */
/* clip at right edge */
if (xmax > cur_state->clipmax.x) {
/* ...compute new nx - how much will fit */
nx1 = (int)((cur_state->clipmax.x - xmin) / xcell);
/* ...compute new xmax */
xmax = xmin + (nx1 * xcell);
} /* end clip at right edge */
/* now clip in y */
ycell = (ymax - ymin) / ny; /* area per cell */
/* clip at bottom edge */
if (ymin < cur_state->clipmin.y) {
/* ...compute how many cells to skip */
skipy = ceil((cur_state->clipmin.y - ymin) / ycell);
/* ...compute new ymin */
ymin = ymin + ((float)skipy * ycell);
/* ...compute new ny */
ny1 = ny - skipy;
} /* end clip at bottom edge */
/* clip at top edge */
if (ymax > cur_state->clipmax.y) {
/* ...compute new ny - how much will fit */
ny1 = (int)((cur_state->clipmax.y - ymin) / ycell);
/* ...compute new ymax */
ymax = ymin + (ny1 * ycell);
} /* end clip at top edge */
} /* end if ok */
} /* end if clip is on */
/* make sure there is still something left */
ok = ok && (nx1 > 0 && ny1 > 0);
if (ok) { /* everything is still ok */
/* set the raster space */
vdstrs(&nx1, &ny1);
imap = 3;
vbstmp(&imap);
imap = 5;
vbstmp(&imap);
/* set the raster viewport */
vdstrv(&xmin, &xmax, &ymin, &ymax);
/* direct color or indexed */
if (cur_state->csm == CINDEX) { /* indexed color */
/* Indexing into the cell array is based on clipping info
* and the orientation of the rectangle. SVDI+raster puts
* [0,0] at the top left corner.
*/
/* There are 4 different cases based on the orientation
* of the rectangle. ( really, there are 8, but I'm not
* supporting the other 4 right now ). If x is increasing,
* the most natural case, the cell array will be written
* out one raster line at a time, either top to bottom or
* bottom to top depending on the y direction. If x is
* decreasing, the cell array will have to be copied and
* reordered, so it will be written out in chunks. In this
* case, it will always be written out top to bottom.
*/
if (xdir == CINCR) { /* x increasing */
ix = 0;
/* compute iy and y increment based on y direction */
if (ydir == CINCR) { /* y increasing */
iy = ny1 - 1;
yinc = -1;
}
else {
iy = 0;
yinc = 1;
}
/* This special case is for efficiency, since is will probably
* be most of the cases: If no clipping is on and [0,0] is at
* the top left (like SVDI+raster) draw the whole cell array.
*/
if (!cur_state->clip_on && iy == 0) {
count = nx * ny;
vdpixi(&ix, &iy, &cells[0], &count);
} /* end special case */
else { /* special case doesn't apply, draw one line at a time */
/* starting index based on clipping info */
index = (ny - ny1 - skipy) * nx + skipx;
/* output one raster line at a time */
for (k = 0; k < ny1; k++) {
vdpixi(&ix, &iy, &cells[index], &nx1);
index = index + nx; /* compute next index */
iy = iy + yinc; /* compute next raster line */
} /* end for k */
} /* end else no special case */
} /* end x increasing */
else { /* x decreasing */
/* always write top to bottom */
ix = iy = count = 0;
/* starting index and index increment are based on
clipping info and the y direction*/
if (ydir == CINCR) { /* y increasing */
index = (ny1 + skipy) * nx - skipx - 1;
index_inc = -nx + nx1;
yinc = -1;
}
else { /* y decreasing */
index = (ny - ny1 - skipy) * nx + (nx - 1) - skipx;
index_inc = nx + nx1;
yinc = 1;
}
/* reorder the cell colors */
for (k = 0; k < ny1; k++) {
for (j = 0; j < nx1; j++) {
assert(count < MAX_ARRAY);
varray[count++] = cells[index--];
}
/* if another row won't fit, or done, output varray */
if (count + nx1 > MAX_ARRAY || k == ny1 - 1) {
vdpixi(&ix, &iy, varray, &count);
count = 0; /* reset varray counter */
iy = iy + (yinc * (k + 1)); /* update iy */
}
/* compute next index */
index = index + index_inc;
} /* end for k */
} /* end x decreasing */
} /* end if indexed color */
else { /* direct color */
/* Indexing into the cells array is based on clipping info,
* and the orientation of the cell array. In SVDI+raster,
* the top left corner is [0,0]. For direct color, the cell
* array is always drawn from top to bottom. If the cell array
* is oriented with [0,0] at the the bottom left corner, the
* way the cells array is indexed takes care of the flipping.
*/
ix = iy = count = 0;
if (xdir == CINCR) { /* x increasing */
/* starting index and index increment are based on
clipping info and the y direction */
if (ydir == CINCR) { /* y increasing */
index = ((ny1 + skipy - 1) * nx * 3) + (skipx * 3);
index_inc = -(nx + nx1) * 3;
}
else { /* y decreasing */
index = (ny - ny1 - skipy) * nx * 3 + (skipx * 3);
index_inc = (nx - nx1) * 3;
}
/* store as much info as possible before calling vdpixl */
for (k = 0; k < ny1; k++) {
for (j = 0; j < nx1; j++) {
assert(count < MAX_ARRAY);
rarray[count] = (float)cells[index++] / 255.0f;
garray[count] = (float)cells[index++] / 255.0f;
barray[count] = (float)cells[index++] / 255.0f;
count++;
} /* end for j */
/* if another row won't fit, or done, output rgb arrays */
if (count + nx1 > MAX_ARRAY || k == ny1 - 1) {
vdpixl(&ix, &iy, rarray, garray, barray, &count);
count = 0; /* reset rgb array counter */
iy = k + 1; /* update iy */
}
/* compute next index into the cells array */
index = index + index_inc;
} /* end for k */
} /* end if x increasing */
else { /* x decreasing */
/* starting index and index increment are based on
clipping info and the y direction */
if (ydir == CINCR) { /* y increasing */
index = (ny1 + skipy) * nx * 3 - (skipx * 3) - 3;
index_inc = (-nx + nx1) * 3;
}
else { /* y decreasing */
index = (ny - ny1 - skipy) * nx * 3 + ((nx - 1) * 3) - (skipx * 3);
index_inc = (nx + nx1) * 3;
}
/* store as much info as possible before calling vdpixl */
for (k = 0; k < ny1; k++) {
for (j = 0; j < nx1; j++) {
assert(count < MAX_ARRAY);
rarray[count] = (float)cells[index] / 255.0f;
garray[count] = (float)cells[index + 1] / 255.0f;
barray[count] = (float)cells[index + 2] / 255.0f;
index = index - 3;
count++;
} /* end for j */
/* if another row won't fit, or done, output rgb arrays */
if (count + nx1 > MAX_ARRAY || k == ny1 - 1) {
vdpixl(&ix, &iy, rarray, garray, barray, &count);
count = 0; /* reset rgb array counter */
iy = k + 1; /* update iy */
}
/* compute next index into the cells array */
index = index + index_inc;
} /* end for k */
} /* end else x decreasing */
} /* end else direct color */
/* flag that the page has been marked */
cur_state->pic_dirty = CDIRTY;
} /* end if ok */
} /* end for each surface */
} /* end xcca */
/* PIXEL ARRAY */
static void xcpxa(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
int j, k; /* loop indices */
int *pxclrs; /* pixel color values */
int nx, ny; /* size of pixel color array */
int nx1, ny1; /* number of pixels after clipping */
int index, index_inc; /* index into pxclrs array */
int count; /* index into temp pixel arrays */
int repx, repy; /* replication in x and y */
int xdir, ydir; /* x and y direction on the DEVICE */
float x_orig, y_orig; /* x and y origin */
float x_dist, y_dist; /* distance pixels run from the origin */
int ix, iy, yinc; /* SVDI logical raster coordinates */
float xmin, xmax, ymin, ymax; /* SVDI raster viewport after clipping */
int ok; /* flag TRUE =line lies in clip region */
int skipx, skipy; /* count pixels skipped in xmin,ymin */
int imap;
int qrs_index; /* index for SVDI inquiries */
float temp_array[2]; /* temporary array for SVDI inquiries */
float x_pxl_scale; /* for converting pixels to NDC/VDC space */
float y_pxl_scale;
static float x_pixels = -1.; /* number of pixels in full NDC space */
static float y_pixels = -1.;
float zero = 0.0;
/* if nx,ny,repx,or repy are non positive, nothing is drawn */
if (*(int *)params[3] < 0 || *(int *)params[4] < 0 || *(int *)params[5] < 0 ||
*(int *)params[6] < 0) {
return;
}
/* set up initial values */
nx = nx1 = *(int *)params[3];
ny = ny1 = *(int *)params[4];
repx = *(int *)params[5];
repy = *(int *)params[6];
pxclrs = (int *)params[9];
/* find (and save) the number of pixels in full NDC space */
if (x_pixels == -1. && y_pixels == -1.) {
vdstrv(&zero, &dev_descrip.xndc_max, &zero, &dev_descrip.yndc_max);
qrs_index = 2;
vdiqrs(&qrs_index, temp_array);
x_pixels = temp_array[0];
y_pixels = temp_array[1];
} /* end find number of pixels */
/* loop through surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* if color selection mode is in error, ignore function */
if (cur_state->csm == -1) {
break;
}
/* check enumerated types */
if ((*(int *)params[7] != CINCR && *(int *)params[7] != CDECR) ||
(*(int *)params[8] != CINCR && *(int *)params[8] != CDECR)) {
/* error 1:-101 enumerated parameter out of range. Function ignored */
report_error(cur_state, 1, -101, *(short *)params[0]);
break;
}
/* figure out what x direction and y direction are in terms
* of the device, since x direction and y direction are dependent
* on the VDC to device mapping. If xscale is positive, then
* VDC and VP are either both increasing or both decreasing and
* x direction on the device is the same as x direction in VDC.
* If xscale is negative, one is increasing and one is decreasing,
* and x direction on the device is opposite of x direction in
* VDC. Same holds for y (where "increasing" means bottom to top)
*/
if (cur_state->xscale > 0) {
xdir = *(int *)params[7];
}
else {
xdir = (*(int *)params[7] == CINCR) ? CDECR : CINCR;
}
if (cur_state->yscale > 0) {
ydir = *(int *)params[8];
}
else {
ydir = (*(int *)params[8] == CINCR) ? CDECR : CINCR;
}
/* map to NDC */
/* origin */
x_orig = *(float *)params[1] * cur_state->xscale + cur_state->xoffset;
y_orig = *(float *)params[2] * cur_state->yscale + cur_state->yoffset;
/* scale to convert pixels to NDC space */
x_pxl_scale = dev_descrip.xndc_max / x_pixels;
y_pxl_scale = dev_descrip.yndc_max / y_pixels;
/* figure out raster viewport mins and maxes */
x_dist = nx * repx * x_pxl_scale;
y_dist = ny * repy * y_pxl_scale;
/* ...x is increasing or decreasing */
if (xdir == CINCR) {
xmin = x_orig;
xmax = x_orig + x_dist;
}
else {
xmin = x_orig - x_dist;
xmax = x_orig;
}
/* y is increasing or decreasing */
if (ydir == CINCR) {
ymin = y_orig;
ymax = y_orig + y_dist;
}
else {
ymin = y_orig - y_dist;
ymax = y_orig;
}
ok = TRUE;
skipx = skipy = 0;
if (cur_state->clip_on) { /* do the clipping */
/* trivial reject */
ok = ((xmin < cur_state->clipmax.x && xmax > cur_state->clipmin.x) &&
(ymin < cur_state->clipmax.y && ymax > cur_state->clipmin.y));
if (ok) { /* it's in there, clip it */
/* clip in x first */
if (xmin < cur_state->clipmin.x) { /* ...left edge */
/* ...compute how many pixels to skip */
skipx = ceil((cur_state->clipmin.x - xmin) / (x_pxl_scale * repx));
/* ...compute new xmin */
xmin = xmin + ((float)skipx * x_pxl_scale * repx);
/* ...compute new nx */
nx1 = nx - skipx;
} /* end clip left edge */
if (xmax > cur_state->clipmax.x) { /* ...right edge */
/* ...compute new nx */
nx1 = (int)((cur_state->clipmax.x - xmin) / (x_pxl_scale * repx));
/* ...compute new xmax */
xmax = xmin + (nx1 * x_pxl_scale * repx);
} /* end clip right edge */
/* now clip in y */
if (ymin < cur_state->clipmin.y) { /* ...bottom edge */
/* ...compute how many pixels to skip */
skipy = ceil((cur_state->clipmin.y - ymin) / (y_pxl_scale * repy));
/* ...compute new ymin */
ymin = ymin + ((float)skipy * y_pxl_scale * repy);
/* ...compute new ny */
ny1 = ny - skipy;
} /* end bottom left edge */
if (ymax > cur_state->clipmax.y) { /* ...top edge */
/* ...compute new ny */
ny1 = (int)((cur_state->clipmax.y - ymin) / (y_pxl_scale * repy));
/* ...comput new ymax */
ymax = ymin + (ny1 * y_pxl_scale * repy);
} /* end clip top edge */
} /* end if ok */
} /* end if clip_on */
/* make sure there is still something to draw */
ok = ok && (nx1 > 0 && ny1 > 0);
if (ok) { /* everything is still ok */
/* set the raster viewport */
vdstrv(&xmin, &xmax, &ymin, &ymax);
imap = 2;
vbstmp(&imap);
imap = 5;
vbstmp(&imap);
/* set the raster space to number of device pixels in viewport */
vdstrs(&nx1, &ny1);
/* direct color or indexed */
if (cur_state->csm == CINDEX) { /* indexed color */
/* Indexing into the pixel array is based on clipping info
* and the orientation of the pixel array, which is
* determined by whether x and y are increasing or
* decreasing in VDC from the origin. SVDI+raster puts
* [0,0] at the top left corner.
*/
/* There are 4 different cases based on the x and y
* directions. If x is increasing, the most natural
* case, the pixel array will be written out one raster
* line at a time, either top to bottom or bottom to
* top depending on the y direction. If x is decreasing,
* the pixel array will have to be copied and reordered,
* so it will be written out in chunks. In this case,
* it will always be written out top to bottom.
*/
if (xdir == CINCR) { /* x increasing */
ix = 0;
/* compute iy and y increment based on y direction */
if (ydir == CINCR) { /* y increasing */
iy = ny1 - 1;
yinc = -1;
}
else { /* y decreasing */
iy = 0;
yinc = 1;
}
/* This special case is for efficiency, since is will probably
* be most of the cases: If no clipping is on and [0,0] is at
* the top left (like SVDI+raster) draw the whole pixel array.
*/
if (!cur_state->clip_on && iy == 0) {
count = nx * ny;
vdpixi(&ix, &iy, &pxclrs[0], &count);
} /* end special case */
else { /* special case doesn't apply, draw one line at a time */
/* starting index based on clipping info */
index = (ny - ny1 - skipy) * nx + skipx;
/* output one raster line at a time */
for (k = 0; k < ny1; k++) {
vdpixi(&ix, &iy, &pxclrs[index], &nx1);
index = index + nx; /* compute next index */
iy = iy + yinc; /* compute next raster line */
} /* end for k */
} /* end else no special case */
} /* end x increasing */
else { /* x decreasing */
/* always write top to bottom */
ix = iy = count = 0;
/* starting index and index increment are based on
clipping info and the y direction*/
if (ydir == CINCR) { /* y increasing */
index = (ny1 + skipy) * nx - skipx - 1;
index_inc = -nx + nx1;
yinc = -1;
}
else { /* y decreasing */
index = (ny - ny1 - skipy) * nx + (nx - 1) - skipx;
index_inc = nx + nx1;
yinc = 1;
}
/* reorder the pixel colors */
for (k = 0; k < ny1; k++) {
for (j = 0; j < nx1; j++) {
assert(count < MAX_ARRAY);
varray[count++] = pxclrs[index--];
}
/* if another row won't fit, or done, output varray */
if (count + nx1 > MAX_ARRAY || k == ny1 - 1) {
vdpixi(&ix, &iy, varray, &count);
count = 0; /* reset varray counter */
iy = iy + (yinc * (k + 1)); /* update iy */
}
/* compute next index */
index = index + index_inc;
} /* end for k */
} /* end x decreasing */
} /* end if indexed color */
else { /* direct color */
/* For direct color, the color values always have to be
* copied, so the raster lines are written out in chucks.
* The raster lines will always be written top to bottom;
* indexing and reordering of the color values will be
* based on x and y direction.
*/
ix = iy = count = 0;
if (xdir == CINCR) { /* x increasing */
/* starting index and index increment are based on
clipping info and the y direction */
if (ydir == CINCR) { /* y increasing */
index = ((ny1 + skipy - 1) * nx * 3) + (skipx * 3);
index_inc = -(nx + nx1) * 3;
}
else { /* y decreasing */
index = (ny - ny1 - skipy) * nx * 3 + (skipx * 3);
index_inc = (nx - nx1) * 3;
}
/* store as much info as possible before calling vdpixl */
for (k = 0; k < ny1; k++) {
for (j = 0; j < nx1; j++) {
assert(count < MAX_ARRAY);
rarray[count] = (float)pxclrs[index++] / 255.0f;
garray[count] = (float)pxclrs[index++] / 255.0f;
barray[count] = (float)pxclrs[index++] / 255.0f;
count++;
} /* end for j */
/* if another row won't fit, or done, output rgb arrays */
if (count + nx1 > MAX_ARRAY || k == ny1 - 1) {
vdpixl(&ix, &iy, rarray, garray, barray, &count);
count = 0; /* reset rgb array counter */
iy = k + 1; /* update iy */
}
/* compute next index into the pxclrs array */
index = index + index_inc;
} /* end for k */
} /* end if x increasing */
else { /* x decreasing */
/* starting index and index increment are based on
clipping info and the y direction */
if (ydir == CINCR) { /* y increasing */
index = (ny1 + skipy) * nx * 3 - (skipx * 3) - 3;
index_inc = (-nx + nx1) * 3;
}
else { /* y decreasing */
index = (ny - ny1 - skipy) * nx * 3 + ((nx - 1) * 3) - (skipx * 3);
index_inc = (nx + nx1) * 3;
}
/* store as much info as possible before calling vdpixl */
for (k = 0; k < ny1; k++) {
for (j = 0; j < nx1; j++) {
assert(count < MAX_ARRAY);
rarray[count] = (float)pxclrs[index] / 255.0f;
garray[count] = (float)pxclrs[index + 1] / 255.0f;
barray[count] = (float)pxclrs[index + 2] / 255.0f;
index = index - 3;
count++;
} /* end for j */
/* if another row won't fit, or done, output rgb arrays */
if (count + nx1 > MAX_ARRAY || k == ny1 - 1) {
vdpixl(&ix, &iy, rarray, garray, barray, &count);
count = 0; /* reset rgb array counter */
iy = k + 1; /* update iy */
}
/* compute next index into the pxclrs array */
index = index + index_inc;
} /* end for k */
} /* end else x decreasing */
} /* end else direct color */
/* flag that the page has been marked */
cur_state->pic_dirty = CDIRTY;
} /* end if ok */
} /* end for each surface */
} /* end xcpxa */
/* LINE TYPE */
static void xclnt(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
int vdi_style; /* SVDI linestyle */
/* CGI line types: */
/* 1: solid - supported
* 2: dash - supported
* 3: dot - supported
* 4: dash dot - supported
* 5: dash dot dot - not supported
*/
/* SVDI linestyles: */
/* 0: solid
* 1: dotted
* 2: dot dash
* 3: short dash
* 4: long dash
* 5: medium dash
*/
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* let SVDI catch any out of range indices */
cur_state->line_type = *(int *)params[1];
/* make sure it really needs to be set */
if (cur_state->line_type != cur_state->vdi_attrib.line_type) {
cur_state->vdi_attrib.line_type = cur_state->line_type;
/* map to SVDI styles */
switch (cur_state->line_type) {
case 1: vdi_style = 0; break;
case 2: vdi_style = 5; break;
case 3: vdi_style = 1; break;
case 4: vdi_style = 2; break;
case 5: vdi_style = 0; break; /* not supported, set to solid */
default: vdi_style = cur_state->line_type; break;
} /* end switch */
vdstls(&vdi_style);
} /* end it needs to be set */
} /* end for each surface */
} /* end xclnt */
/* LINE WIDTH */
static void xclnw(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
float vdi_lw; /* SVDI linewidth */
float temp_array[14]; /* use for SVDI inquiry */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* make sure it needs to be updated */
if (*(float *)params[1] != cur_state->vdi_attrib.line_width) {
/* save the original in vdi_attrib array */
cur_state->vdi_attrib.line_width = *(float *)params[1];
/* convert to NDC and set the linewidth */
vdi_lw = dev_descrip.linewidth_nominal * *(float *)params[1] * fabs(cur_state->xscale);
vdstlw(&vdi_lw);
/* find out what it really got set at */
vdiqos(&temp_array[1]);
/* map it back to (scaled) VDC and store it in state table */
cur_state->line_width =
(temp_array[5] * fabs(cur_state->xscale) * 100) / dev_descrip.linewidth_nominal;
} /* end it needs to be updated */
} /* end for each surface */
} /* end xclnw */
/* LINE COLOR */
static void xclnc(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* if color selection mode is in error, ignore function */
if (cur_state->csm == -1) {
break;
}
if (cur_state->csm == CINDEX) { /* indexed mode */
/* let SVDI catch out of range indices */
cur_state->line_csm = CINDEX;
cur_state->line_color[0] = *(int *)params[1];
} /* end indexed mode */
else { /* direct color mode */
/* let SVDI catch illegal color values */
cur_state->line_csm = CDRECT;
cur_state->line_color[0] = *((int *)params[1] + 0);
cur_state->line_color[1] = *((int *)params[1] + 1);
cur_state->line_color[2] = *((int *)params[1] + 2);
} /* end direct color mode */
} /* end for each surface */
} /* end xclnc */
/* MARKER TYPE */
static void xcmkt(int num_surfaces, anything **surf_list)
{
/* CGI marker types: */
/* 1: dot - supported
* 2: plus - not supported
* 3: asterisk - not supported
* 4: circle - not supported
* 5: cross - not supported
*/
/* SVDI only supports a dot, which is the default */
/* An unsupported index is mapped to a supported value, such
* as the default, without error. So can just ignore this
* function.
*/
} /* end xcmkt */
/* MARKER SIZE */
static void xcmks(anything **params, int num_surfaces, anything **surf_list)
{
/* marker size is mapped to nearest avail marker size on
* the device. SVDI only supports 1 marker size, which is
* the default size, so this function not supported.
*/
/* error 4:001 - Function not supported. Function ignored */
report_error(cur_state, 4, 001, *(short *)params[0]);
} /* end xcmks */
/* MARKER COLOR */
static void xcmkc(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* if color selection mode is in error, ignore function */
if (cur_state->csm == -1) {
break;
}
if (cur_state->csm == CINDEX) { /* indexed mode */
/* let SVDI catch out of range indices */
cur_state->mark_csm = CINDEX;
cur_state->mark_color[0] = *(int *)params[1];
} /* end indexed mode */
else { /* direct color mode */
/* let SVDI catch illegal color values */
cur_state->mark_csm = CDRECT;
cur_state->mark_color[0] = *((int *)params[1] + 0);
cur_state->mark_color[1] = *((int *)params[1] + 1);
cur_state->mark_color[2] = *((int *)params[1] + 2);
} /* end direct color mode */
} /* end for each surface */
} /* end xcmkc */
/* TEXT PRECISION */
static void xctxp(anything **params, int num_surfaces, anything **surf_list)
{
/* error 4:001 - Function not supported. Function ignored */
report_error(cur_state, 4, 001, *(short *)params[0]);
} /* end xctxp */
/* TEXT COLOR */
static void xctxc(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* if color selection mode is in error, ignore function */
if (cur_state->csm == -1) {
break;
}
if (cur_state->csm == CINDEX) { /* indexed mode */
/* let SVDI catch out of range indices */
cur_state->text_csm = CINDEX;
cur_state->text_color[0] = *(int *)params[1];
} /* end indexed mode */
else { /* direct color mode */
/* let SVDI catch illegal color values */
cur_state->text_csm = CDRECT;
cur_state->text_color[0] = *((int *)params[1] + 0);
cur_state->text_color[1] = *((int *)params[1] + 1);
cur_state->text_color[2] = *((int *)params[1] + 2);
} /* end direct mode */
} /* end for each surface */
} /* end xctxc */
/* CHARACTER HEIGHT */
static void xcchh(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
float vdi_cs; /* SVDI character size */
float temp_array[14]; /* used for SVDI inquire */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* set SVDI character size if needed */
if (*(float *)params[1] != cur_state->vdi_attrib.char_x) {
/* let SVDI catch illegal character height */
cur_state->vdi_attrib.char_x = *(float *)params[1];
/* map to NDC */
vdi_cs = *(float *)params[1] * fabs(cur_state->xscale);
vdstcs(&vdi_cs);
/* inquire to find out what it really got set to */
vdiqos(&temp_array[1]);
/* map back to VDC and store in state table */
cur_state->char_height = temp_array[6] / fabs(cur_state->xscale);
} /* end if char size needs to be set */
} /* end for each surface */
} /* end xcchh */
/* CHARACTER ORIENTATION */
static void xccho(anything **params, int num_surfaces, anything **surf_list)
{
/* error 4:001 - Function not supported. Function ignored */
report_error(cur_state, 4, 001, *(short *)params[0]);
} /* end xccho */
/* INTERIOR STYLE */
static void xcis(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
/* CGI interior styles: */
/* hollow - supported
* solid - supported
* pattern - not supported
* hatch - not supported
* empty - not supported
* bitmap - not supported
*/
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* check for legal enumerated value */
if (*(int *)params[1] == CHOLLO || *(int *)params[1] == CSOLID) {
cur_state->interior_style = *(int *)params[1];
}
else {
/* error 1:-101 Enumerated parameter out of range. Function ignored */
report_error(cur_state, 1, -101, *(short *)params[0]);
}
} /* end for each surface */
} /* end xcis */
/* FILL COLOR */
static void xcflc(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* if color selection mode is in error, ignore function */
if (cur_state->csm == -1) {
break;
}
if (cur_state->csm == CINDEX) { /* indexed mode */
/* let SVDI catch out of range indices */
cur_state->fill_csm = CINDEX;
cur_state->fill_color[0] = *(int *)params[1];
} /* end indexed color */
else { /* direct color mode */
/* let SVDI catch illegal color values */
cur_state->fill_csm = CDRECT;
cur_state->fill_color[0] = *((int *)params[1] + 0);
cur_state->fill_color[1] = *((int *)params[1] + 1);
cur_state->fill_color[2] = *((int *)params[1] + 2);
} /* end direct color mode */
} /* end for each surface */
} /* end xcflc */
/* COLOR SELECTION MODE */
static void xccsm(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* check enumerated parameters */
if (*(int *)params[1] != CDRECT && *(int *)params[1] != CINDEX) {
/* error 1:-101 enumerated parameter out of range. Function ignored */
report_error(cur_state, 1, -101, *(short *)params[0]);
}
else {
/* if the device supports both index and direct, or the
request if only for index, everything is honky-dory */
if (dev_descrip.csm_avail == CCLRID || *(int *)params[1] == CINDEX) {
cur_state->csm = *(int *)params[1];
}
else { /* must be an error */
/* error 3:305 - Color selection mode not supported. All
functions with affected parameters ignored until reset */
report_error(cur_state, 3, 305, *(short *)params[0]);
cur_state->csm = -1; /* flag error condition */
} /* end else must be an error */
} /* end else */
} /* end for each surface */
} /* end xccsm */
/* COLOR TABLE */
static void xcct(anything **params, int num_surfaces, anything **surf_list)
{
int i; /* index for loop on surfaces */
int j, k; /* indices for looping */
int starti; /* starting color index */
int num_cols; /* number of colors in color list */
int tmp_array[3]; /* temp array used for setting bg color */
float color_array[256][3]; /* used for setting SVDI color table */
int num_set; /* number of colors being set, for SVDI */
int maxindex; /* max color index to set */
int indx_ptr; /* for keeping track of color indices */
int index1, index2; /* defines a range of indices to set */
int first; /* marks first time through loop */
int one = 1;
first = TRUE;
/* loop through surfaces */
for (i = 0; i < num_surfaces; ++i) {
cur_state = (surf_statelist *)surf_list[i];
if (cur_state->cgi_inited != CYES) {
break;
}
/* starting color index and number of colors */
starti = *(int *)params[1];
num_cols = *(int *)params[2];
/* error checking */
/* an out of range index in an index definition function should
be ignored. should an error be reported ?? */
if (starti < 0) {
starti = 0;
}
if ((starti + num_cols - 1) > dev_descrip.num_cols) {
/* error 6:308 - Too many color specifiers. Discard extras */
report_error(cur_state, 6, 308, *(short *)params[0]);
num_cols = dev_descrip.num_cols - starti + 1;
} /* end error */
/* convert rgb to lie between 0. and 1. */
/* ...only do this once */
if (first) {
k = 0;
for (j = starti; j < starti + num_cols; j++) {
color_array[j][0] = (float)((int *)params[3])[k++] / 255.0f;
color_array[j][1] = (float)((int *)params[3])[k++] / 255.0f;
color_array[j][2] = (float)((int *)params[3])[k++] / 255.0f;
}
first = FALSE;
}
/* mark that the color table has been set */
cur_state->color_set = TRUE;
/* update the current state color table */
k = 0;
for (j = starti; j < starti + num_cols; j++) {
cur_state->color_table[j].r = ((int *)params[3])[k++];
cur_state->color_table[j].g = ((int *)params[3])[k++];
cur_state->color_table[j].b = ((int *)params[3])[k++];
}
/* set the SVDI color table */
/* color indices are mapped so that fg and bg colors are
* 'reasonable' colors. If the user sets either the fg index
* color or bg color index, map those colors so that the
* fg and bg colors won't change
*/
/* color index mappings:
* if set index 0 --> set bg_index
* if set index 1 --> set fg_index
* if set bg_index --> set 0
* if set fg_index --> set 1
*/
/* set the special cases first */
/* 1. caller setting index 0 - set the background color */
/* --set_background_color() will set color table entry bg_index */
if (starti == 0) {
tmp_array[0] = cur_state->color_table[0].r;
tmp_array[1] = cur_state->color_table[0].g;
tmp_array[2] = cur_state->color_table[0].b;
set_background_color(cur_state, tmp_array);
}
/* 2. caller setting index 1 - set index fg_index */
if (starti <= 1 && (starti + num_cols > 1)) {
vdstco(&one, &dev_descrip.index_array[cur_state->fg_index], &color_array[1],
&dev_descrip.col_mode);
}
/* 3. caller setting index bg_index - set index 0 */
if (cur_state->bg_index != 0) { /* .. don't do it twice */
if (starti <= cur_state->bg_index && (starti + num_cols > cur_state->bg_index)) {
vdstco(&one, &dev_descrip.index_array[0], &color_array[cur_state->bg_index],
&dev_descrip.col_mode);
}
}
/* 4. caller setting index fg_index - set index 1 */
if (cur_state->fg_index != 1) { /* .. don't do it twice */
if (starti <= cur_state->fg_index && (starti + num_cols > cur_state->fg_index)) {
vdstco(&one, &dev_descrip.index_array[1], &color_array[cur_state->fg_index],
&dev_descrip.col_mode);
}
}
/* now do all the rest */
/* ...sort for convenience */
if (cur_state->fg_index < cur_state->bg_index) {
index1 = cur_state->fg_index;
index2 = cur_state->bg_index;
}
else {
index1 = cur_state->bg_index;
index2 = cur_state->fg_index;
} /* end sort */
maxindex = starti + num_cols - 1;
indx_ptr = starti;
if (indx_ptr < 2) {
indx_ptr = 2;
}
/* 1. set color table between index 1 and index1 */
if (indx_ptr <= 2) {
num_set = min(index1 - 2, maxindex - 1);
if (num_set > 0) {
vdstco(&num_set, &dev_descrip.index_array[2], &color_array[2], &dev_descrip.col_mode);
indx_ptr = index1 + 1;
}
}
if (indx_ptr == index1) { /* update indx_ptr */
indx_ptr = indx_ptr + 1;
}
/* 2. set color table between index1 and index2 */
if (indx_ptr < index2) {
num_set = min(index2 - indx_ptr, maxindex - indx_ptr + 1);
if (num_set > 0) {
vdstco(&num_set, &dev_descrip.index_array[indx_ptr], &color_array[indx_ptr],
&dev_descrip.col_mode);
indx_ptr = index2 + 1;
}
}
if (indx_ptr == index2) { /* update indx_ptr */
indx_ptr = indx_ptr + 1;
}
/* 3. set color table after index 2 */
if (indx_ptr >= index2 + 1) {
num_set = maxindex - indx_ptr + 1;
if (num_set > 0) {
vdstco(&num_set, &dev_descrip.index_array[indx_ptr], &color_array[indx_ptr],
&dev_descrip.col_mode);
}
}
} /* end for each surface */
} /* end xcct */
/* GET TEXT EXTENT */
static void xcgtxx(anything **params, anything **surf_list)
{
float act_h, act_w; /* actual char height and width (VDC) */
float x1, y1, x2; /* parrallelogram parts */
float save, temp_h; /* temporary variables */
float temp_array[14]; /* temp array used for SVDI inquires */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* find out actual height and width from SVDI for this size */
/* ..save the old value */
vdiqos(&temp_array[1]);
save = temp_array[6];
/* ..set current height value */
temp_h = cur_state->char_height * fabs(cur_state->xscale);
vdstcs(&temp_h);
/* ..find out actual height and width */
vdiqos(&temp_array[1]);
act_h = temp_array[6] / fabs(cur_state->xscale);
act_w = temp_array[7] / fabs(cur_state->xscale);
/* set it back to original */
vdstcs(&save);
/* parallelogram */
/* x1, y1 = bottom left corner of string */
x1 = *(float *)params[1];
y1 = *(float *)params[2];
*(float *)params[8] = x1;
*(float *)params[9] = y1;
/* x2, y2 = bottom right corner of string */
/* params[4] is an added parameter that contains string size */
x2 = x1 + (*(int *)params[16] * act_w);
*(float *)params[10] = x2;
*(float *)params[11] = y1;
/* x3, y3 = top right corner of string ( x3 = x2 )*/
*(float *)params[12] = x2;
*(float *)params[13] = y1 + act_h;
/* x4, y4 = top left corner of string ( y4 = y3 )*/
*(float *)params[14] = x1;
*(float *)params[15] = y1 + act_h;
/* concatenation point is bottom right corner ( x2, y2 )*/
*(float *)params[6] = x2;
*(float *)params[7] = y1;
/* validity flags */
*(int *)params[4] = CVAL;
*(int *)params[5] = CVAL;
} /* end xcgtxx */
/* INQUIRE PRIMITIVE SUPPORT LEVELS */
static void xcqprl(anything **params, anything **surf_list)
{
int qdc_index = 25; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* max points for a polyline */
dev_descrip.max_pts_polyline = MAX_POLYLINE;
/* max points for a disjoint polyline */
dev_descrip.max_pts_disj_polyline = MAX_DJ_POLYLINE;
/* max points for a polygon */
vdiqdc(&qdc_index, &value);
dev_descrip.max_pts_polygon = (value == 99999.) ? MAX_POLYGON : min((int)value, MAX_POLYGON);
/* max points for a polygon set */
/* --not supported */
dev_descrip.max_pts_polygon_set = 0;
/* max points for a polymarker */
dev_descrip.max_pts_polymarker = MAX_POLYMARKER;
/* max number of points for a closed figure */
/* --not supported */
dev_descrip.max_pts_closed_fig = 0;
/* max characters of text */
dev_descrip.max_chars_text = MAX_TEXT_LENGTH;
/* max number of cell color specifiers for cell array */
dev_descrip.max_pts_cellarray = -1;
/* cell array fill capability */
dev_descrip.cellarray_fill_cap = CFILLD;
/* cell array alignment */
dev_descrip.cellarray_align_cap = CAXIS;
/* compound text capability */
dev_descrip.compound_text_cap = CCNONE;
/* closed figure capability */
dev_descrip.compound_fig_cap = CCNONE;
} /* end if not set */
/* validity flag */
*(int *)params[1] = CVAL;
/* stuff all the values into the return parameters */
*(int *)params[2] = dev_descrip.max_pts_polyline;
*(int *)params[3] = dev_descrip.max_pts_disj_polyline;
*(int *)params[4] = dev_descrip.max_pts_polygon;
*(int *)params[5] = dev_descrip.max_pts_polygon_set;
*(int *)params[6] = dev_descrip.max_pts_polymarker;
*(int *)params[7] = dev_descrip.max_pts_closed_fig;
*(int *)params[8] = dev_descrip.max_chars_text;
*(int *)params[9] = dev_descrip.max_pts_cellarray;
*(int *)params[10] = dev_descrip.cellarray_fill_cap;
*(int *)params[11] = dev_descrip.cellarray_align_cap;
*(int *)params[12] = dev_descrip.compound_text_cap;
*(int *)params[13] = dev_descrip.compound_fig_cap;
} /* end xcqprl */
/* INQUIRE LINE CAPABILITY */
static void xcqln(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* set the validity flag */
*(int *)params[1] = CVAL;
/* number of predefined line bundles - bundles not supported */
*(int *)params[2] = 0;
/* number of settable line bundles - bundles not supported */
*(int *)params[3] = 0;
/* max line bundle index - bundles not supported */
*(int *)params[4] = 0;
/* dynamic modification for line bundles- bundles not supported */
*(int *)params[5] = 0;
/* nom, min, max, get set in set_dev_descrip() at initialization */
*(int *)params[6] = dev_descrip.linewidth_nominal;
*(int *)params[7] = dev_descrip.linewidth_min;
*(int *)params[8] = dev_descrip.linewidth_max;
} /* end xcqln */
/* INQUIRE LIST OF AVAILABLE LINE TYPES */
static void xcqlnt(anything **params, anything **surf_list)
{
int i, j; /* loop indices */
int qdc_index = 6; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set */
static int ntotal; /* save total nbr of linestyles */
static unsigned mask = ~(~0u << 1);
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* inquire supported linestyles from SVDI */
vdiqdc(&qdc_index, &value);
/* SVDI always supports linestyle 0 */
ntotal = 0;
dev_descrip.line_types[ntotal++] = 0;
/* find all SVDI linestyles supported by looking at bits */
for (i = 0; i < 5; i++) {
if (((int)value & mask << i) >> i == 1) {
dev_descrip.line_types[ntotal++] = i + 1;
}
}
/* map to CGI linestyles */
/* cgi linestyles: 1 - solid 2 - dash 3 - dot,
* 4 - dashdot 5 - dash dot dot
* vdi linestyles: 0 - solid 1 - dotted 2 - dot dash
* 3 - short dash 4 - long dash 5 - medium dash
*/
for (i = 0; i < ntotal; i++) {
switch (dev_descrip.line_types[i]) {
case 0: dev_descrip.line_types[i] = 1; break;
case 1: dev_descrip.line_types[i] = 3; break;
case 2: dev_descrip.line_types[i] = 4; break;
/* ...all SVDI dashes map to cgi dash */
case 3: dev_descrip.line_types[i] = 2; break;
case 4: dev_descrip.line_types[i] = 2; break;
case 5: dev_descrip.line_types[i] = 2; break;
default: break;
} /* end switch */
}
/* take out duplicates */
for (i = 0; i < ntotal; i++) {
if (dev_descrip.line_types[i] == 2) {
break;
}
ntotal = i + 1;
}
} /* end if not set */
/* set the total */
*(int *)params[4] = ntotal;
/* do some error checking */
if (*(int *)params[2] < 1) {
/* error - set validity flag to invalid */
*(int *)params[3] = CINVAL;
}
else { /* send back only the ones requested - zero out the rest */
i = *(int *)params[2] - 1;
j = 0;
*(int *)params[5] = 0; /* actual number of list elements sent back */
while (j < ntotal) {
if (j < *(int *)params[1] && i < ntotal) {
((int *)params[6])[j++] = dev_descrip.line_types[i++];
(*(int *)params[5])++;
}
else {
((int *)params[6])[j++] = 0;
}
}
/* set validity flag */
*(int *)params[3] = CVAL;
} /* end else send back */
} /* end xcqlnt */
/* INQUIRE LIST OF AVAILABLE SCALED LINE WIDTHS */
static void xcqslw(anything **params, anything **surf_list)
{
int qdc_index = 5; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set */
static int ntotal; /* save total nbr of linewidths */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* number of linewidths available */
vdiqdc(&qdc_index, &value);
ntotal = (int)value;
} /* end if not set */
/* validity flag */
*(int *)params[3] = CVAL;
*(int *)params[4] = ntotal;
/* nlist = 0 means empty list ( continuous range ) */
/* --leave list (params[6]) untouched */
*(int *)params[5] = 0;
} /* end xcqslw */
/* INQUIRE MARKER CAPABILITY */
static void xcqmk(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* set the validity flag */
*(int *)params[1] = CVAL;
/* number of predefined marker bundles - bundles not supported */
*(int *)params[2] = 0;
/* number of settable marker bundles - bundles not supported */
*(int *)params[3] = 0;
/* max marker bundle index - bundles not supported */
*(int *)params[4] = 0;
/* dynamic modification for marker bundles- bundles not supported */
*(int *)params[5] = 0;
/* nom, min, max, get set in set_dev_descrip() at initialization */
*(int *)params[6] = dev_descrip.mark_nominal;
*(int *)params[7] = dev_descrip.mark_min;
*(int *)params[8] = dev_descrip.mark_max;
} /* end xcqmk */
/* INQUIRE LIST OF AVAILABLE MARKER TYPES */
static void xcqmkt(anything **params, anything **surf_list)
{
static int set = FALSE; /* flag whether values have been set */
static int ntotal; /* save total nbr of linestyles */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* SVDI only supports 1 marker type - "dot" */
ntotal = 1;
dev_descrip.mark_types[0] = 1;
} /* end if not set */
/* set validity flag */
*(int *)params[3] = CVAL;
*(int *)params[4] = ntotal;
if (*(int *)params[1] > 0) {
*(int *)params[5] = 1;
((int *)params[6])[0] = dev_descrip.mark_types[0];
}
else {
*(int *)params[5] = 0;
}
} /* end xcqmkt */
/* INQUIRE LIST OF AVAILABLE SCALED MARKER SIZES */
static void xcqsms(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* validity flag */
*(int *)params[3] = CVAL;
/* there is only 1 size */
*(int *)params[4] = 1;
*(int *)params[5] = 1;
((int *)params[6])[0] = dev_descrip.mark_nominal;
} /* end xcqsms */
/* INQUIRE LIST OF AVAILABLE CHARACTER HEIGHTS */
static void xcqchh(anything **params, anything **surf_list)
{
int qdc_index = 7; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set */
static int ntotal; /* save total nbr of char heights */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* number of char sizes */
vdiqdc(&qdc_index, &value);
ntotal = (int)value;
} /* end if not set */
/* font - SRCP does not support multiple fonts; use null string */
/* I don't check for font, anything goes */
/* only string precision is supported */
if (*(int *)params[2] == CSTRNG) {
/* total number of character heights */
*(int *)params[6] = ntotal;
/* set nlist = 0 means empty list ( continuous range ) */
/* --leave list (params[8]) untouched */
*(int *)params[7] = 0;
/* validity flag */
*(int *)params[5] = CVAL;
} /* end if */
else {
*(int *)params[5] = CINVAL;
}
} /* end xcqchh */
/* INQUIRE FILL CAPABILITY */
static void xcqfl(anything **params, anything **surf_list)
{
static int set = FALSE; /* flag whether values have been set */
static int ntotal; /* save total nbr of fill styles */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set */
set = TRUE;
ntotal = 2;
dev_descrip.interior_styles[0] = CHOLLO;
dev_descrip.interior_styles[1] = CSOLID;
} /* end if not set */
/* set the validity flag */
*(int *)params[1] = CVAL;
/* number of predefined fill bundles - bundles not supported */
*(int *)params[2] = 0;
/* number of settable fill bundles - bundles not supported */
*(int *)params[3] = 0;
/* max fill bundle index - bundles not supported */
*(int *)params[4] = 0;
/* dynamic modification for fill bundles- bundles not supported */
*(int *)params[5] = 0;
/* interior styles */
*(int *)params[6] = ntotal;
((int *)params[7])[0] = dev_descrip.interior_styles[0];
((int *)params[7])[1] = dev_descrip.interior_styles[1];
/* number of predefined patterns - patterns not supported */
*(int *)params[8] = 0;
/* number of settable patterns - patterns not supported */
*(int *)params[9] = 0;
/* maximum pattern index - patterns not supported */
*(int *)params[10] = 0;
/* preferred pattern size divisor - patterns not supported */
*(int *)params[11] = 0;
/* maximum pattern size - patterns not supported */
*(int *)params[12] = 0;
*(int *)params[13] = 0;
/* pattern transformation support - patterns not supported */
*(int *)params[14] = CPTNO;
} /* end xcqfl */
/* INQUIRE COLOR CAPABILITIES */
static void xcqc(anything **params, anything **surf_list)
{
int qdc_index; /* index for inquiries to vdiqdc */
float value; /* value returned by vdiqdc */
static int set = FALSE; /* flag whether values have been set */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
if (!set) { /* values have't been set, inquire SVDI */
set = TRUE;
/* number of simultaneous colors */
dev_descrip.num_simul_colors = dev_descrip.num_cols;
/* number of available colors */
qdc_index = 27;
vdiqdc(&qdc_index, &value);
dev_descrip.num_avail_colors = (int)value;
/* number of available intensities */
/* --see 7.1.4 about direct color */
qdc_index = 3;
vdiqdc(&qdc_index, &value);
dev_descrip.num_avail_int = (int)value;
/* dynamic modification accepted for color table */
dev_descrip.dynamic_mod_ct = CIRG;
/* color overwrite capability */
/* --what is the answer?? */
/* dev_descrip. color_overwrite = ??; */
/* monochromatic device */
qdc_index = 32;
vdiqdc(&qdc_index, &value);
dev_descrip.monochrome_device = (value == 0.0) ? CYES : CNO;
} /* end not set */
/* validity flag */
*(int *)params[1] = CVAL;
/* return the answers */
*(int *)params[2] = dev_descrip.num_simul_colors;
*(int *)params[3] = dev_descrip.num_avail_colors;
((int *)params[4])[0] = dev_descrip.num_avail_int;
*(int *)params[5] = dev_descrip.csm_avail; /* set in set_dev_descrip()*/
*(int *)params[6] = dev_descrip.dynamic_mod_ct;
*(int *)params[7] = dev_descrip.color_overwrite;
*(int *)params[8] = dev_descrip.monochrome_device;
} /* end xcqc */
/* INQUIRE LINE ATTRIBUTES */
static void xcqlna(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* validity flag */
*(int *)params[1] = CVAL;
/* line bundle index - bundles not supported */
*(int *)params[2] = 0;
/* line type */
*(int *)params[3] = cur_state->line_type;
/* line width spcification mode - only support scaled */
*(int *)params[4] = CSCA;
/* line width */
*(float *)params[5] = cur_state->line_width;
/* color selection mode in which line color was last specified */
*(int *)params[6] = cur_state->line_csm;
/* line color in color selection mode last specified */
((int *)params[7])[0] = cur_state->line_color[0];
if (cur_state->line_csm == CDRECT) {
((int *)params[7])[1] = cur_state->line_color[1];
((int *)params[7])[2] = cur_state->line_color[2];
}
/* line clipping mode */
*(int *)params[8] = CLOCUS;
} /* end xcqlna */
/* INQUIRE MARKER ATTRIBUTES */
static void xcqmka(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* validity flag */
*(int *)params[1] = CVAL;
/* marker bundle index - bundles not supported */
*(int *)params[2] = 0;
/* marker type */
*(int *)params[3] = cur_state->mark_type;
/* marker size spcification mode - only support scaled */
*(int *)params[4] = CSCA;
/* marker size */
*(float *)params[5] = cur_state->mark_size;
/* color selection mode in which marker color was last specified */
*(int *)params[6] = cur_state->mark_csm;
/* marker color in color selection mode last specified */
((int *)params[7])[0] = cur_state->mark_color[0];
if (cur_state->mark_csm == CDRECT) {
((int *)params[7])[1] = cur_state->mark_color[1];
((int *)params[7])[2] = cur_state->mark_color[2];
}
/* marker clipping mode */
*(int *)params[8] = CLOCUS;
} /* end xcqmka */
/* INQUIRE TEXT ATTRIBUTES */
static void xcqtxa(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* validity flag */
*(int *)params[1] = CVAL;
/* text bundle index - bundles not supported */
*(int *)params[2] = 0;
/* font index - only the default font is supported */
*(int *)params[3] = 1;
/* font precision */
*(int *)params[4] = CSTRNG;
/* character expansion factor */
*(float *)params[5] = 1.0;
/* character spacing */
*(float *)params[6] = 0.0;
/* color selection mode in which text color was last specified */
*(int *)params[7] = cur_state->text_csm;
/* text color in color selection mode last specified */
((int *)params[8])[0] = cur_state->text_color[0];
if (cur_state->text_csm == CDRECT) {
((int *)params[8])[1] = cur_state->text_color[1];
((int *)params[8])[2] = cur_state->text_color[2];
}
/* character height */
*(float *)params[9] = cur_state->char_height;
/* character orientation */
((float *)params[10])[0] = 0.;
((float *)params[10])[1] = 1.;
((float *)params[10])[2] = 1.;
((float *)params[10])[3] = 0.;
/* text path */
*(int *)params[11] = CTPRIT;
/* horizontal alignment */
*(int *)params[12] = CTANH;
/* continuous horizontal alignment */
*(float *)params[13] = 1.0;
/* vertical alignment */
*(int *)params[14] = CTANV;
/* continuous horizontal alignment */
*(float *)params[15] = 1.0;
/* character set index ?? */
*(int *)params[16] = 1;
/* alternate character set index ?? */
*(int *)params[17] = 1;
} /* end xcqtxa */
/* INQUIRE FILL ATTRIBUTES */
static void xcqfla(anything **params, anything **surf_list)
{
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* validity flag */
*(int *)params[1] = CVAL;
/* fill bundle index - bundles not supported */
*(int *)params[2] = 0;
/* interior style */
*(int *)params[3] = cur_state->interior_style;
/* color selection mode in which fill color was last specified */
*(int *)params[4] = cur_state->fill_csm;
/* fill color in color selection mode last specified */
((int *)params[5])[0] = cur_state->fill_color[0];
if (cur_state->fill_csm == CDRECT) {
((int *)params[5])[1] = cur_state->fill_color[1];
((int *)params[5])[2] = cur_state->fill_color[2];
}
/* hatch index - not supported */
*(int *)params[6] = 0;
/* pattern index - not supported */
*(int *)params[7] = 0;
/* --i don't know what any of the following means */
/* fill bitmap identifier */
*(int *)params[8] = 0;
/* fill bitmap region */
*(float *)params[9] = 0.;
*(float *)params[10] = 0.;
*(float *)params[11] = 0.;
*(float *)params[12] = 0.;
/* fill reference point */
*(float *)params[13] = 0.;
*(float *)params[14] = 0.;
/* pattern orientation and size */
*(float *)params[15] = 0.;
*(float *)params[16] = 0.;
*(float *)params[17] = 0.;
*(float *)params[18] = 0.;
} /* end xcqfla */
/* INQUIRE LIST OF COLOR TABLE ENTRIES */
static void xcqcte(anything **params, anything **surf_list)
{
int i; /* loop index */
int first; /* index of first element to return */
int nreq; /* number of list elements requested */
int j = 0; /* array index */
/* there is only one surface for inquiries */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* number of requested elements, and the first index */
nreq = *(int *)params[1];
first = *(int *)params[2];
/* error checking */
if (first < 1) {
first = 1;
}
if ((first + nreq - 1) > dev_descrip.num_cols) {
nreq = dev_descrip.num_cols - first + 1;
}
/* actual number of colors returned */
*(int *)params[5] = nreq;
for (i = first; i < (first + *(int *)params[5]); i++) {
((int *)params[6])[j++] = cur_state->color_table[i - 1].r;
((int *)params[6])[j++] = cur_state->color_table[i - 1].g;
((int *)params[6])[j++] = cur_state->color_table[i - 1].b;
} /* end for i */
/* return total number of colors */
*(int *)params[4] = dev_descrip.num_cols;
/* validity flag */
*(int *)params[3] = CVAL;
} /* end xcqcte */
/* INITIALIZE LOGICAL INPUT DEVICE */
static void xcili(anything **params, anything **surf_list)
{
/* there is only one surface for input */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* only support locator */
if (*(int *)params[1] != CLOCAT) {
/* error 2:001 - Request for an unsupported feature. Function ignored */
report_error(cur_state, 2, 001, *(short *)params[0]);
}
else if (*(int *)params[2] != 1) {
/* error 3:501 - LID index exceeds number of this class of LID.
Function ignored */
report_error(cur_state, 3, 501, *(short *)params[0]);
}
else if (dev_descrip.dev_class == CINPUT ||
dev_descrip.dev_class == COUTIN) { /* device does input */
cur_state->input_dev_class = CLOCAT;
cur_state->input_dev_index = 1;
cur_state->input_dev_state = CREADY;
} /* end if device does input */
} /* end xcili */
/* REQUEST LOCATOR */
static void xcrqlc(anything **params, anything **surf_list)
{
float x, y; /* x,y values of locator */
/* there is only one surface for input */
cur_state = (surf_statelist *)surf_list[0];
if (cur_state->cgi_inited != CYES) {
return;
}
/* check if device has been initialized */
/* ...only support input device index 1 */
if (*(int *)params[1] != 1 || cur_state->input_dev_state != CREADY) {
/* error 5:501 - Function illegal in LID state RELEASED.
Function ignored */
report_error(cur_state, 5, 501, *(short *)params[0]);
*(int *)params[3] = CINVAL;
}
else if (dev_descrip.dev_class == CINPUT ||
dev_descrip.dev_class == COUTIN) { /* device does input */
/* for now only allow limited timeout */
/* positive and negative values = wait forever, 0 = no wait */
if (*(int *)params[2] == 0) {
*(int *)params[3] = CINVAL;
return;
}
/* get location and trigger */
vdakgl((int *)params[6], &x, &y);
/* convert location from NDC to VDC */
*(float *)params[7] =
(x - (cur_state->vp1.x * dev_descrip.xndc_max)) / cur_state->xscale + cur_state->vdc1.x;
*(float *)params[8] =
(y - (cur_state->vp1.y * dev_descrip.yndc_max)) / cur_state->yscale + cur_state->vdc1.y;
/* response validity */
*(int *)params[3] = CVAL;
/* request status, SVDI only has trigger */
*(int *)params[4] = CTRIGR;
/* measure validity */
/* --i'm not sure when measure validity is invalid */
*(int *)params[5] = CVAL;
} /* end else device does input */
else { /* device doesn't do input */
/* response validity */
*(int *)params[3] = CVAL;
}
} /* end xcrqlc */
/*-------------------------------------------------------------*/
/* >> UTILITY ROUTINES */
/*-------------------------------------------------------------*/
/* init_state */
/* Initialize the state list */
static void init_state(surf_statelist *surf_state)
/* surface statelist to init */
{
int i; /* loop index */
float tmp_array[1][3]; /* temp array to set SVDI color table */
int one = 1;
/* set default error control: class 1 : DETECTION OFF
class 2 - MAX_ERROR_CLASS : REPORTING OFF */
surf_state->err_flag[0] = CEHDOF;
for (i = 1; i < MAX_ERROR_CLASS; i++) {
surf_state->err_flag[i] = CEHROF;
}
/* initialize to 0 errors */
surf_state->err_head_ptr = 0;
surf_state->err_count = 0;
/* default vdc extent */
surf_state->vdc1.x = 0.0;
surf_state->vdc1.y = 0.0;
surf_state->vdc2.x = 32767.;
surf_state->vdc2.y = 32767.;
/* viewport - default viewport specification mode is FRACTION OF
* DRAWING SURFACE. Thus, the viewport (0,0),(1,1) corresponds to
* the lower and upper corners, respectively, of the default
* device viewport, which is the largest unrotated rectangular area
* visible on the drawing surface.
*/
/* default viewport is (0,0),(1,1) */
surf_state->vp1.x = 0.0;
surf_state->vp1.y = 0.0;
surf_state->vp2.x = 1.0;
surf_state->vp2.y = 1.0;
/* VDC to viewport in NDC mapping */
/* --device viewport mapping defaults are: isotropy forced,
horizontal alignment left, vertical alignment bottom */
/* -- this routine sets effective viewport in VDC and
NDC (forcing isotropic mapping) and the mapping scale */
set_mapping(surf_state);
/* default clip indicator is off (VDC clipping) */
surf_state->clip_indicator = COFF;
/* default view surface clip indicator is viewport */
surf_state->ds_clip_indicator = CVPORT;
/* default clip rectangle is (0,0) (32767,32767) */
/* ...can't be changed in SS-CGI */
surf_state->clip_rect1.x = 0.0;
surf_state->clip_rect1.y = 0.0;
surf_state->clip_rect2.x = 32767.;
surf_state->clip_rect2.y = 32767.;
/* effective clip rectangle is intersection of VDC extent and
clip rectangle */
surf_state->eff_clip_rect1.x = 0.0;
surf_state->eff_clip_rect1.y = 0.0;
surf_state->eff_clip_rect2.x = 32767.;
surf_state->eff_clip_rect2.y = 32767.;
/* set the clip region */
set_clipping(surf_state);
/* default color mode is indexed */
surf_state->csm = CINDEX;
/* default line, fill, text, and marker color indices */
surf_state->line_color[0] = 1;
surf_state->fill_color[0] = 1;
surf_state->text_color[0] = 1;
surf_state->mark_color[0] = 1;
/* default line type is solid */
surf_state->line_type = 1;
/* default interior style is hollow */
surf_state->interior_style = CHOLLO;
/* char size is in VDC - default is 1/100 of default VDC extent */
surf_state->char_height = 327.;
/* default line width specification mode is scaled, default
linewidth is 1. */
surf_state->line_width = 1.;
/* default marker specification mode is scaled, default
marker size is 1. */
surf_state->mark_size = 1.;
/* the only default colors defined in CGI are index 0 = background,
* and index 1 = foreground. Use SVDI's bg and fg until the user
* sets the color table.
*/
if (dev_descrip.svdi_type == 0) { /* vector SVDI */
/* set up the fg and bg mappings */
surf_state->bg_index = dev_descrip.att_array[2];
surf_state->fg_index = dev_descrip.att_array[1];
/* set the current surface color table */
vdiqco(&one, &dev_descrip.index_array[surf_state->bg_index], tmp_array, &dev_descrip.col_mode);
surf_state->color_table[0].r = (int)(tmp_array[0][0] * 255.0f);
surf_state->color_table[0].g = (int)(tmp_array[0][1] * 255.0f);
surf_state->color_table[0].b = (int)(tmp_array[0][2] * 255.0f);
vdiqco(&one, &dev_descrip.index_array[surf_state->fg_index], tmp_array, &dev_descrip.col_mode);
surf_state->color_table[1].r = (int)(tmp_array[0][0] * 255.0f);
surf_state->color_table[1].g = (int)(tmp_array[0][1] * 255.0f);
surf_state->color_table[1].b = (int)(tmp_array[0][2] * 255.0f);
} /* end if vector SVDI */
else { /* raster SVDI */
vdiqci(&dev_descrip.att_array[11], &dev_descrip.att_array[12], &dev_descrip.att_array[13],
&surf_state->bg_index);
vdiqci(&dev_descrip.att_array[8], &dev_descrip.att_array[9], &dev_descrip.att_array[10],
&surf_state->fg_index);
/* set the current surface color table */
surf_state->color_table[0].r = (int)(dev_descrip.att_array[8] * 255.0f);
surf_state->color_table[0].g = (int)(dev_descrip.att_array[9] * 255.0f);
surf_state->color_table[0].b = (int)(dev_descrip.att_array[10] * 255.0f);
surf_state->color_table[1].r = (int)(dev_descrip.att_array[11] * 255.0f);
surf_state->color_table[1].g = (int)(dev_descrip.att_array[12] * 255.0f);
surf_state->color_table[1].b = (int)(dev_descrip.att_array[13] * 255.0f);
} /* end else raster SVDI */
/* set/reset the SVDI attribute array */
/* --set everything to -1 to force resetting of attributes */
surf_state->vdi_attrib.fg_color = -1;
surf_state->vdi_attrib.bg_color = -1;
surf_state->vdi_attrib.intensity = -1.0;
surf_state->vdi_attrib.line_type = -1;
surf_state->vdi_attrib.line_width = -1.0;
surf_state->vdi_attrib.char_x = -1.0;
surf_state->vdi_attrib.char_y = -1.0;
surf_state->vdi_attrib.fg_rgb[0] = -1.0;
surf_state->vdi_attrib.fg_rgb[1] = -1.0;
surf_state->vdi_attrib.fg_rgb[2] = -1.0;
surf_state->vdi_attrib.bg_rgb[0] = -1.0;
surf_state->vdi_attrib.bg_rgb[1] = -1.0;
surf_state->vdi_attrib.bg_rgb[2] = -1.0;
/* set color_set flag to false = color table not set by user */
surf_state->color_set = FALSE;
/* set picture state to clean */
surf_state->pic_dirty = CCLEAN;
} /* end init_state */
/* set_dev_descrip */
/* Set the device description table */
static void set_dev_descrip(void)
{
/* dev_descrip is global */
int j; /* loop index */
int qdc_index; /* used for inquiring SVDI */
float value; /* value returned from inquire SVDI */
/* set copy_class */
qdc_index = 1;
vdiqdc(&qdc_index, &value);
if (value == 0.) {
dev_descrip.copy_class = CHARD;
}
else {
dev_descrip.copy_class = CSOFT;
}
/* device corners in device coords */
dev_descrip.dc1.x = 0;
dev_descrip.dc1.y = 0;
qdc_index = 15;
vdiqdc(&qdc_index, &value);
dev_descrip.dc2.x = (int)value;
qdc_index = 16;
vdiqdc(&qdc_index, &value);
dev_descrip.dc2.y = (int)value;
/* vector or raster SVDI (0=vector, 1=raster) */
qdc_index = 29;
vdiqdc(&qdc_index, &value);
dev_descrip.svdi_type = (int)value;
/* vector SVDI only does indexed color, raster does both */
if (dev_descrip.svdi_type == 0) {
dev_descrip.csm_avail = CCLRI;
}
else {
dev_descrip.csm_avail = CCLRID;
}
/* device class */
qdc_index = 13;
vdiqdc(&qdc_index, &value);
dev_descrip.dev_class = (value == 0.) ? COUTPT : COUTIN;
/* NDC space */
vdiqnd(&dev_descrip.xndc_max, &dev_descrip.yndc_max);
/* output status */
vdiqos(&dev_descrip.att_array[1]);
/* min line width - SVDI returns value in DC */
qdc_index = 19;
vdiqdc(&qdc_index, &value);
dev_descrip.linewidth_min = (int)value;
/* max line width - SVDI returns value in DC */
qdc_index = 31;
vdiqdc(&qdc_index, &value);
dev_descrip.linewidth_max = (int)value;
/* use the default SVDI linewidth as nominal */
/* --convert to device coordinates */
value = (dev_descrip.att_array[5] / dev_descrip.xndc_max) * .01 *
(dev_descrip.dc2.x - dev_descrip.dc1.x);
dev_descrip.linewidth_nominal = (int)max(value, 1.);
/* --make sure that for some reason it isn't out of range */
dev_descrip.linewidth_nominal =
max(min(dev_descrip.linewidth_nominal, dev_descrip.linewidth_max), dev_descrip.linewidth_min);
/* nominal,min,max marker size - only one size */
qdc_index = 20;
vdiqdc(&qdc_index, &value);
dev_descrip.mark_nominal = (int)value;
dev_descrip.mark_min = (int)value;
dev_descrip.mark_max = (int)value;
/* inquire the number of colors */
qdc_index = 4;
vdiqdc(&qdc_index, &value);
/* check for max colors */
dev_descrip.num_cols = ((int)value > COLOR_TABLE_SIZE) ? COLOR_TABLE_SIZE : (int)value;
/* set up a color index array for use in color table stuff */
for (j = 0; j < 256; j++) {
dev_descrip.index_array[j] = j;
}
/* set SVDI color mode */
dev_descrip.col_mode = 0;
/* inquire default SVDI color table. */
vdiqco(&dev_descrip.num_cols, dev_descrip.index_array, dev_descrip.color_array,
&dev_descrip.col_mode);
} /* end set_dev_descrip */
/* reset_vdi */
/* Reset SVDI values. Used if CI is called twice */
static void reset_vdi(surf_statelist *surf_state)
/* current surface statelist */
{
/* reset the output status */
vdstos(&dev_descrip.att_array[1]);
/* only reset color table is user has changed it */
if (surf_state->color_set) {
vdstco(&dev_descrip.num_cols, dev_descrip.index_array, dev_descrip.color_array,
&dev_descrip.col_mode);
}
} /* end reset_vdi */
/* set_mapping */
/* Set up the VDC to NDC mappings. Also sets the effective viewports
* in NDC and VDC.
*/
static void set_mapping(surf_statelist *surf_state)
{
point ndc_vp1, ndc_vp2;
/* viewport in NDC space */
ndc_vp1.x = cur_state->vp1.x * dev_descrip.xndc_max;
ndc_vp1.y = cur_state->vp1.y * dev_descrip.yndc_max;
ndc_vp2.x = cur_state->vp2.x * dev_descrip.xndc_max;
ndc_vp2.y = cur_state->vp2.y * dev_descrip.yndc_max;
/* x and y scale maps VDC to viewport in NDC (ISOTROPIC Mapping) */
/* ...smallest scale magnitude, but keep the original sign */
surf_state->xscale = (ndc_vp2.x - ndc_vp1.x) / (surf_state->vdc2.x - surf_state->vdc1.x);
surf_state->yscale = (ndc_vp2.y - ndc_vp1.y) / (surf_state->vdc2.y - surf_state->vdc1.y);
if (fabs(surf_state->xscale) < fabs(surf_state->yscale)) {
surf_state->yscale =
(surf_state->yscale < 0) ? -1 * fabs(surf_state->xscale) : fabs(surf_state->xscale);
}
else {
surf_state->xscale =
(surf_state->xscale < 0) ? -1 * fabs(surf_state->yscale) : fabs(surf_state->yscale);
}
/* x and y offset for VDC to NDC mapping */
surf_state->xoffset = (ndc_vp1.x < ndc_vp2.x)
? ndc_vp1.x - surf_state->vdc1.x * surf_state->xscale
: ndc_vp2.x - surf_state->vdc2.x * surf_state->xscale;
surf_state->yoffset = (ndc_vp1.y < ndc_vp2.y)
? ndc_vp1.y - surf_state->vdc1.y * surf_state->yscale
: ndc_vp2.y - surf_state->vdc2.y * surf_state->yscale;
/* effective viewport */
/* - mode is FRACTION OF DRAWING SURFACE */
surf_state->eff_vp1.x = cur_state->vp1.x;
surf_state->eff_vp1.y = cur_state->vp1.y;
surf_state->eff_vp2.x =
(surf_state->vdc2.x * surf_state->xscale + surf_state->xoffset) / dev_descrip.xndc_max;
surf_state->eff_vp2.y =
(surf_state->vdc2.y * surf_state->yscale + surf_state->yoffset) / dev_descrip.yndc_max;
} /* end set_mapping */
/* set_clipping */
/* Set up the clip region. */
static void set_clipping(surf_statelist *my_cur_state)
{
point clip1, clip2; /* temp clip values */
clip1.x = clip1.y = clip2.x = clip2.y = 0;
/* The clip region depends on clip indicator and drawing surface
* clip indicator.
*/
switch (my_cur_state->clip_indicator) {
case CON:
/* VDC clipping is on */
switch (my_cur_state->ds_clip_indicator) {
case CDCOFF: /* view surface clipping off */
/* map the effective clip rectangle to NDC */
my_cur_state->clip_on = TRUE;
clip1.x = my_cur_state->eff_clip_rect1.x * my_cur_state->xscale + my_cur_state->xoffset;
clip1.y = my_cur_state->eff_clip_rect1.y * my_cur_state->yscale + my_cur_state->yoffset;
clip2.x = my_cur_state->eff_clip_rect2.x * my_cur_state->xscale + my_cur_state->xoffset;
clip2.y = my_cur_state->eff_clip_rect2.y * my_cur_state->yscale + my_cur_state->yoffset;
break; /* end case CDCOFF */
case CVPORT: /* clip at viewport */
/* map the effective clip rectangle to NDC */
my_cur_state->clip_on = TRUE;
clip1.x = my_cur_state->eff_clip_rect1.x * my_cur_state->xscale + my_cur_state->xoffset;
clip1.y = my_cur_state->eff_clip_rect1.y * my_cur_state->yscale + my_cur_state->yoffset;
clip2.x = my_cur_state->eff_clip_rect2.x * my_cur_state->xscale + my_cur_state->xoffset;
clip2.y = my_cur_state->eff_clip_rect2.y * my_cur_state->yscale + my_cur_state->yoffset;
break; /* end case CVPORT */
case CDCREC: /* clip at display surface */
/* map the effective clip rectangle to NDC and intersect it
with the max NDC space */
my_cur_state->clip_on = TRUE;
clip1.x = my_cur_state->eff_clip_rect1.x * my_cur_state->xscale + my_cur_state->xoffset;
clip1.y = my_cur_state->eff_clip_rect1.y * my_cur_state->yscale + my_cur_state->yoffset;
clip2.x = my_cur_state->eff_clip_rect2.x * my_cur_state->xscale + my_cur_state->xoffset;
clip2.y = my_cur_state->eff_clip_rect2.y * my_cur_state->yscale + my_cur_state->yoffset;
clip1.x = max(min(clip1.x, clip2.x), 0.0);
clip1.y = max(min(clip1.y, clip2.y), 0.0);
clip2.x = min(max(clip1.x, clip2.x), dev_descrip.xndc_max);
clip2.y = min(max(clip1.y, clip2.y), dev_descrip.yndc_max);
break; /* end case CDCREC */
default:
/* illegal enumeration type - ignore function */
break;
} /* end switch ds_clip_indicator */
break; /* end case CON */
case COFF:
/* VDC clipping is off */
switch (my_cur_state->ds_clip_indicator) {
case CDCOFF: /* display surface clipping off */
/* no clip */
my_cur_state->clip_on = FALSE;
break; /* end case CDCOFF */
case CVPORT: /* clip at viewport */
/* clip at NDC effective viewport */
my_cur_state->clip_on = TRUE;
clip1.x = my_cur_state->eff_vp1.x * dev_descrip.xndc_max;
clip1.y = my_cur_state->eff_vp1.y * dev_descrip.yndc_max;
clip2.x = my_cur_state->eff_vp2.x * dev_descrip.xndc_max;
clip2.y = my_cur_state->eff_vp2.y * dev_descrip.yndc_max;
break; /* end case CVPORT */
case CDCREC: /* clip at display surface */
/* clip at max NDC space */
my_cur_state->clip_on = TRUE;
clip1.x = 0.0;
clip1.y = 0.0;
clip2.x = dev_descrip.xndc_max;
clip2.y = dev_descrip.yndc_max;
break; /* end case CDCREC */
default:
/* illegal enumeration type - ignore function */
break;
} /* end switch ds_clip_indicator */
break; /* end case COFF */
default:
/* illegal enumeration type - ignore function */
break;
} /* end switch clip_indicator */
/* set clipmin and clipmax such that clipmin is the minimum corner of
* the clipping window, and clipmax is the maximum. This is done
* so that the clipping algorithms work correctly with mirroring.
*/
if (my_cur_state->clip_on) {
my_cur_state->clipmin.x = min(clip1.x, clip2.x);
my_cur_state->clipmax.x = max(clip1.x, clip2.x);
my_cur_state->clipmin.y = min(clip1.y, clip2.y);
my_cur_state->clipmax.y = max(clip1.y, clip2.y);
}
} /* end set_clipping */
/* set_foreground_color */
/* Set the SVDI foreground color */
static void set_foreground_color(surf_statelist *surf_state, int *colors)
{
int zero = 0;
int one = 1;
/* if color selection mode is in error, ignore function */
if (surf_state->csm == -1) {
return;
}
/* indexed or direct color? */
/* --vector SVDI only does indexed color */
if (surf_state->csm == CINDEX || dev_descrip.svdi_type == 0) {
/* does foreground need to be updated? */
if (colors[0] != cur_state->vdi_attrib.fg_color) {
/* color index mappings:
* if set index 0 --> set bg_index
* if set index 1 --> set fg_index
* if set bg_index --> set 0
* if set fg_index --> set 1
*/
if (colors[0] == 0) {
vdstfc(&cur_state->bg_index);
}
else if (colors[0] == 1) {
vdstfc(&cur_state->fg_index);
}
else if (colors[0] == cur_state->bg_index) {
vdstfc(&zero);
}
else if (colors[0] == cur_state->fg_index) {
vdstfc(&one);
}
else {
vdstfc(&colors[0]);
}
/* update att_array */
cur_state->vdi_attrib.fg_color = colors[0];
/* flag (direct) that foreground color has changed */
/* do i need to do this? */
cur_state->vdi_attrib.fg_rgb[0] = -1.0;
cur_state->vdi_attrib.fg_rgb[1] = -1.0;
cur_state->vdi_attrib.fg_rgb[2] = -1.0;
} /* end does foreground... */
} /* end indexed color */
else /* direct color */
/* does foreground need to be updated? */
/* -- i need to check this out - might need to store as int */
if (colors[0] != (int)(cur_state->vdi_attrib.fg_rgb[0] * 255.0f) ||
colors[1] != (int)(cur_state->vdi_attrib.fg_rgb[1] * 255.0f) ||
colors[2] != (int)(cur_state->vdi_attrib.fg_rgb[2] * 255.0f)) {
/* update att_array */
cur_state->vdi_attrib.fg_rgb[0] = (float)colors[0] / 255.0f;
cur_state->vdi_attrib.fg_rgb[1] = (float)colors[1] / 255.0f;
cur_state->vdi_attrib.fg_rgb[2] = (float)colors[2] / 255.0f;
/* set new foreground color */
vdfrgb(&cur_state->vdi_attrib.fg_rgb[0], &cur_state->vdi_attrib.fg_rgb[1],
&cur_state->vdi_attrib.fg_rgb[2]);
/* flag (indexed) that foreground color has changed */
/* do i need to do this? */
cur_state->vdi_attrib.fg_color = -1;
} /* end does foreground... */
} /* end set_foreground_color */
/* set_background_color */
/* Set the SVDI background color */
static void set_background_color(surf_statelist *surf_state, int *colors)
{
int i; /* loop index */
int index = 0; /* color index */
float dr, dg, db, dmin, dist; /* for finding the closet index */
int one = 1;
float epsilon = .001;
/* does background need to be updated */
/* --background color is saved in att_array, even for vector */
if (colors[0] != (int)(cur_state->vdi_attrib.bg_rgb[0] * 255.0f) ||
colors[1] != (int)(cur_state->vdi_attrib.bg_rgb[1] * 255.0f) ||
colors[2] != (int)(cur_state->vdi_attrib.bg_rgb[2] * 255.0f)) {
/* store new values in att_array */
cur_state->vdi_attrib.bg_rgb[0] = (float)colors[0] / 255.0f;
cur_state->vdi_attrib.bg_rgb[1] = (float)colors[1] / 255.0f;
cur_state->vdi_attrib.bg_rgb[2] = (float)colors[2] / 255.0f;
/* set the cgi state color table - index 0 */
cur_state->color_table[0].r = colors[0];
cur_state->color_table[0].g = colors[1];
cur_state->color_table[0].b = colors[2];
/* has the SVDI color table ever been set */
if (!surf_state->color_set) { /* has never been set */
/* find out if default SVDI table contains this color */
if (dev_descrip.svdi_type == 1) { /* raster SVDI */
vdiqci(&cur_state->vdi_attrib.bg_rgb[0], &cur_state->vdi_attrib.bg_rgb[1],
&cur_state->vdi_attrib.bg_rgb[2], &i);
/* does it match */
dr = cur_state->vdi_attrib.bg_rgb[0] - dev_descrip.color_array[i][0];
dg = cur_state->vdi_attrib.bg_rgb[1] - dev_descrip.color_array[i][1];
db = cur_state->vdi_attrib.bg_rgb[2] - dev_descrip.color_array[i][2];
dmin = dr * dr + dg * dg + db * db;
} /* end raster SVDI */
else { /* vector SVDI */
for (i = 0; i < 8; i++) {
dr = cur_state->vdi_attrib.bg_rgb[0] - dev_descrip.color_array[i][0];
dg = cur_state->vdi_attrib.bg_rgb[1] - dev_descrip.color_array[i][1];
db = cur_state->vdi_attrib.bg_rgb[2] - dev_descrip.color_array[i][2];
dist = dr * dr + dg * dg + db * db;
if (i == 0 || dist < dmin) {
dmin = dist;
index = i;
}
} /* end for i */
} /* end vector SVDI */
/* is it close enough? */
if (dmin <= epsilon) {
cur_state->bg_index = index;
}
else { /* not close enough, set SVDI color table */
cur_state->bg_index = 0;
vdstco(&one, &dev_descrip.index_array[cur_state->bg_index], &cur_state->vdi_attrib.bg_rgb,
&dev_descrip.col_mode);
cur_state->color_set = TRUE; /* flag that CT has been set */
} /* end else not close enough */
} /* end has never been set */
else { /* color table has been set */
/* set SVDI color table */
vdstco(&one, &dev_descrip.index_array[cur_state->bg_index], &cur_state->vdi_attrib.bg_rgb,
&dev_descrip.col_mode);
} /* end else has been set */
/* set the SVDI background color */
if (dev_descrip.svdi_type == 1) { /* raster SVDI */
vdbrgb(&cur_state->vdi_attrib.bg_rgb[0], &cur_state->vdi_attrib.bg_rgb[1],
&cur_state->vdi_attrib.bg_rgb[2]);
}
else /* vector SVDI */
/* once the ct has been set, bg_index never changes */
if (!cur_state->color_set) {
vdstbc(&cur_state->bg_index);
}
} /* end does background need to be updated */
} /* end set_background_color */
/* report_error */
/* Stuff the error info into the error queue */
static void report_error(surf_statelist *surf_state, int e_class, int e_num, int f_id)
{
int err_slot; /* slot in the queue to put the error */
/* is error reporting on for this class? */
if (surf_state->err_flag[e_class - 1] == CEHON) {
/* figure out where the next slot is */
err_slot = surf_state->err_head_ptr + surf_state->err_count;
if (err_slot >= ERROR_LIST_SIZE) {
err_slot = err_slot - ERROR_LIST_SIZE;
}
/* store errors if there is room in the queue */
if (surf_state->err_count < ERROR_LIST_SIZE) {
surf_state->err_queue[err_slot].err_class = e_class;
surf_state->err_queue[err_slot].err_num = e_num;
surf_state->err_queue[err_slot].func_id = f_id;
surf_state->err_count++;
} /* end if room in the queue */
else { /* not enuff room in the queue */
/* if the most recent error is ERROR REPORTS LOST, increase count
of errors lost by one (count is stored in func_id) */
if (surf_state->err_queue[err_slot - 1].err_class == -1 &&
surf_state->err_queue[err_slot - 1].err_num == 0) {
surf_state->err_queue[err_slot - 1].func_id++;
}
else { /* create an ERROR REPORTS LOST error */
/* The format for an ERROR REPORTS LOST has not yet
* been defined. For now, use error class -1, error
* number 0, and the count in function id.
* (as defined in SRCP document)
*/
surf_state->err_queue[err_slot - 1].err_class = -1;
surf_state->err_queue[err_slot - 1].err_num = 0;
surf_state->err_queue[err_slot - 1].func_id = 2;
} /* end else create */
} /* end not enuff room in the queue */
} /* end if error reporting is on */
} /* end report_error */
/* gettoken */
/* Return one token from data record....written by Pat MaGee, LANL */
static void gettoken(int *index_p, int *numrecs_p, char *data_p, int max_chars, char *outtoken_p)
/* in: 1st char of whitespace before token */
/* out: 1st char past token */
/* in: number of data records */
/* in: 80 character records */
/* in: max # of chars to put into outtoken */
/* out: where to put output token */
{
char c; /* char from data record */
int num_chars; /* # chars put into outtoken so far */
int workstate; /* 0=whitespace,1=nonwhite,2=endofstring */
num_chars = 0;
workstate = 0;
if (*index_p >= (*numrecs_p * 80)) {
workstate = 2;
}
while (workstate == 0) { /* while scanning whitespace */
c = data_p[*index_p];
if ((c == ' ') || (c == '\t') || (c == '\r')) {
/* c is whitespace, keep scanning */
++(*index_p);
if (*index_p >= *numrecs_p * 80) {
workstate = 2;
} /* end if off end of data */
}
else {
/* c is not whitespace, is start of token */
workstate = 1;
} /* end if c is whitespace */
} /* end while skipping whitespace */
while (workstate == 1) { /* while in token */
c = data_p[*index_p];
if (num_chars >= max_chars) {
workstate = 3;
}
if ((c == ' ') || (c == '\t') || (c == '\r')) {
workstate = 0;
}
else { /* c is not whitespace, output and keep scanning */
outtoken_p[num_chars] = c;
++num_chars;
++(*index_p);
if (*index_p >= *numrecs_p * 80) {
workstate = 2;
} /* end if off end of data */
} /* end if c is whitespace */
} /* end while putting chars into outtoken */
outtoken_p[num_chars] = 0;
} /* end gettoken */
/* poly_clip */
/* Clip a polygon. Based on Sutherland - Hodgman algorithm
* Returns the new polygon vertices, and the new vertex count.
* One day, I need to make this more efficient by moving everything
* inline.
*/
static int poly_clip(point *cmin, point *cmax, float *vx, float *vy, int vlen, float *xout,
float *yout, int *lenout)
{
point s, p, t;
int i, j, bnd, curlen;
float xtemp[MAX_POLYGON];
float ytemp[MAX_POLYGON];
/* make sure there is something to clip */
if (vlen <= 0) {
return (FALSE);
}
for (bnd = 0; bnd < 4; bnd++) { /* loop through all boundaries */
/* start with last vertex */
if (bnd == 0) { /* 1st time through use original vertex list */
curlen = vlen;
*lenout = 0;
s.x = vx[curlen - 1];
s.y = vy[curlen - 1];
}
else { /* after 1st time through, use new vertex list */
curlen = *lenout;
*lenout = 0;
if (curlen > 0) {
s.x = xout[curlen - 1];
s.y = yout[curlen - 1];
}
}
for (i = 0; i < curlen; i++) { /* loop through all vertices */
if (bnd == 0) {
p.x = vx[i];
p.y = vy[i];
}
else {
p.x = xout[i];
p.y = yout[i];
}
/* is vertex p 'inside' current boundary */
if (inside_bnd(&p, cmin, cmax, bnd)) {
/* is vertex s 'inside' current boundary */
if (inside_bnd(&s, cmin, cmax, bnd)) {
/* both p and s are inside, add p to vertex list */
xtemp[*lenout] = p.x;
ytemp[(*lenout)++] = p.y;
} /* end s is inside */
else { /* p is inside, s is outside, intersect */
t = intersect_bnd(&s, &p, cmin, cmax, bnd);
/* add t and p to the vertex list */
xtemp[*lenout] = t.x;
ytemp[(*lenout)++] = t.y;
xtemp[*lenout] = p.x;
ytemp[(*lenout)++] = p.y;
} /* end else intersect */
} /* end if p is inside */
else { /* p is outside, is s inside */
if (inside_bnd(&s, cmin, cmax, bnd)) {
/* p is outside, s is inside, intersect */
t = intersect_bnd(&s, &p, cmin, cmax, bnd);
/* add t to the vertex list */
xtemp[*lenout] = t.x;
ytemp[(*lenout)++] = t.y;
} /* end intersect */
} /* end else p outside, s inside */
s.x = p.x;
s.y = p.y;
} /* end for i */
for (j = 0; j < *lenout; j++) {
xout[j] = xtemp[j];
yout[j] = ytemp[j];
} /* end for j */
} /* end for bnd */
if (*lenout <= 0) {
return (FALSE);
}
return (TRUE);
} /* end poly_clip */
/* inside_bnd */
/* Used by poly_clip and returns true if the vertex is within the
* boundary. ( where the boundaries are numbered 1-4,corresponding to
* top, right, bottom, left )
*/
static int inside_bnd(point *v, point *bmin, point *bmax, int bound_num)
{
/* this routine assumes a rectangular boundary */
switch (bound_num) {
case 0: return (v->y <= bmax->y); break; /* top */
case 1: return (v->x <= bmax->x); break; /* right */
case 2: return (v->y >= bmin->y); break; /* bottom */
case 3: return (v->x >= bmin->x); break; /* left */
default: return (FALSE); break;
} /* end switch */
} /* end inside_bnd */
/* intersect_bnd */
/* Used by poly_clip. Returns the the intersection point of a polygon
* edge with a clip boundary. The clip boundary is coded 1-4, corresponding
* to top, right, bottom, and left boundary edges, respectsively.
*/
static point intersect_bnd(point *p1, point *p2, point *bmin, point *bmax, int bound_num)
{
point temp;
temp.x = temp.y = 0;
switch (bound_num) {
case 0: /* top */
temp.x = p1->x + (p2->x - p1->x) * (bmax->y - p1->y) / (p2->y - p1->y);
temp.y = bmax->y;
break;
case 1: /* right */
temp.y = p1->y + (p2->y - p1->y) * (bmax->x - p1->x) / (p2->x - p1->x);
temp.x = bmax->x;
break;
case 2: /* bottom */
temp.x = p1->x + (p2->x - p1->x) * (bmin->y - p1->y) / (p2->y - p1->y);
temp.y = bmin->y;
break;
case 3: /* left */
temp.y = p1->y + (p2->y - p1->y) * (bmin->y - p1->x) / (p2->x - p1->x);
temp.x = bmin->x;
break;
default:
/* error check ? */
break;
} /* end switch */
return (temp);
} /* end intersect_bnd */
/*-------------------------------------------------------------*/
/* >> CDR ROUTINES */
/*-------------------------------------------------------------*/
/* cur_state is global - points to current statelist */
/*
Open file for sequential access. FORTRAN unit number is ignored.
File descriptor which is returned from open is stored in current
statelist
*/
void cdrofs(int *ifilcd)
{
int errnum, errsev;
char symbol[1024];
int qdc_index;
float value;
char *devid;
char *env;
static int file_cnt = 1;
/* if user hasn't named the file, build a default */
if (!cur_state->filename[0]) { /* filename is blank */
/* get the SVDI device code */
qdc_index = 23;
vdiqdc(&qdc_index, &value);
devid = get_devid_char(value);
if (devid != NULL) {
snprintf(cur_state->filename, 100, "cgi%s%d", devid, file_cnt++);
}
else {
snprintf(cur_state->filename, 100, "cgiout%d", file_cnt++);
}
}
/* copy filename to symbol */
copy_string(symbol, cur_state->filename, 1024);
/* check the environment to see if a file name has been assigned */
env = getenv(symbol);
if (env != 0 && strlen(env) < 1024) {
snprintf(symbol, 1024, "%s", env);
}
/* open the file - if it doesn't exist, create it with mode 664 */
/* -- open returns a file descriptor which is stored in the statelist */
/* -- O_TRUNC ??? read/writing??? */
if ((cur_state->file_d = open(symbol, (O_CREAT | O_TRUNC | O_RDWR), 0664)) == -1) {
errnum = 722;
errsev = 10;
char err[50];
snprintf(err, 50, "SVDI ERROR NUMBER %d SEVERITY CODE %d", errnum, errsev);
perror(err);
}
}
/* this routine is here only for compatibility with SVDI drivers */
void cdrof3(int *ifilcd, int *idum) { cdrofs(ifilcd); }
/* this routine is here only for compatibility with SVDI drivers */
void cdroff(int *ifilcd, int *idum1, int *idum2, int *idum3) { cdrofs(ifilcd); }
/*
Try to read LENGTH words from the file. Return the actual number
of words read. FORTRAN unit number is ignored, file descriptor is
gotten from the current statelist
*/
void cdrrfs(int *ifilcd, int *length, char *buffer, int *istat)
{
/* if the file hasn't been opened, open it */
if (cur_state->file_d == -1) {
cdrofs(ifilcd);
}
/* read the data as a byte stream */
if ((*istat = read(cur_state->file_d, buffer, (*length * cdrcom.KCPW))) != -1) {
*istat = *istat / cdrcom.KCPW;
}
}
/*
Write LENGTH words from BUFFER to the file. FORTRAN unit number is
ignored, file descriptor is gotten from the current state list
*/
void cdrwfs(int *ifilcd, int *length, char *buffer, int *istat)
{
/* if the file hasn't been opened, open it */
if (cur_state->file_d == 0) {
cdrofs(ifilcd);
}
/* write out the data as a byte stream. */
if ((*istat = write(cur_state->file_d, buffer, (*length * cdrcom.KCPW))) == -1) {
*istat = 1;
}
else {
*istat = 0;
}
}
/*
Close file sequential. FORTRAN unit number is ignore and file
descriptor is gotten from current state
*/
void cdrcfs(int *ifilcd, int *eof)
{
/* close the file */
close(cur_state->file_d);
}
/* open routine for the Abekas */
void cdroab(int *ifilcd, int *frame)
{
char ic[5];
int i, inbr;
/* form the file name from the frame number */
inbr = *frame;
for (i = 3; i >= 0; i--) {
ic[i] = inbr % 10 + '0';
inbr = inbr / 10;
}
ic[4] = '\0';
/* set the file name in the state list */
snprintf(cur_state->filename, 100, "%s.RGB", ic);
cdrofs(ifilcd);
}
/*
* Postscript buffering routine. (device dependent, computer dependent)
* PST driver passes OUTARY as a character string of input data
* to this buffering routine, and a count of characters.
*/
void pstbuf(int *numwds, char *outary)
{
int i; /* loop variable */
int istat; /* error reporting */
/* cur_state is global and points to the current state */
/* check for buffer flush and if there is something to flush */
if (*numwds <= 0 && cur_state->buff_ptr > 0) {
/* write out the data as a byte stream. */
if ((istat = write(cur_state->file_d, cur_state->buffer, cur_state->buff_ptr)) == -1) {
perror("PSTBUF: write error");
}
/* reset buff pointer */
cur_state->buff_ptr = 0;
} /* end if buffer flush */
else { /* pack outary into buffer */
for (i = 0; i < *numwds; i++) {
cur_state->buffer[cur_state->buff_ptr++] = outary[i];
if (cur_state->buff_ptr >= BUFFER_SIZE) {
/* write out the data as a byte stream. */
if ((istat = write(cur_state->file_d, cur_state->buffer, cur_state->buff_ptr)) == -1) {
perror("PSTBUF: write error");
}
/* reset buff pointer */
cur_state->buff_ptr = 0;
} /* end if > BUFFER_SIZE */
} /* end for i=... */
}
} /* end pstbuf */