1 /*****************************************************************************
2 ** This is part of the CTSim program
3 ** Copyright (C) 1983-2000 Kevin Rosenberg
5 ** $Id: sgp.cpp,v 1.1 2000/06/19 18:05:03 kevin Exp $
7 ** Revision 1.1 2000/06/19 18:05:03 kevin
10 ** Revision 1.1 2000/06/13 16:20:31 kevin
11 ** finished c++ conversions
13 ** Revision 1.4 2000/05/24 22:49:01 kevin
14 ** Updated SGP: first function X-windows version
16 ** Revision 1.3 2000/05/11 14:07:23 kevin
17 ** Fixed compilation warnings
19 ** Revision 1.2 2000/05/08 20:08:15 kevin
20 ** *** empty log message ***
22 ** Revision 1.1.1.1 2000/04/28 13:02:44 kevin
23 ** Initial CVS import for first public release
27 ** This program is free software; you can redistribute it and/or modify
28 ** it under the terms of the GNU General Public License (version 2) as
29 ** published by the Free Software Foundation.
31 ** This program is distributed in the hope that it will be useful,
32 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
33 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 ** GNU General Public License for more details.
36 ** You should have received a copy of the GNU General Public License
37 ** along with this program; if not, write to the Free Software
38 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 ******************************************************************************/
41 /*-----------------------------------------------------------------------------
44 * Name: sgp.c Simple Graphics Package
45 * Programmer: Kevin Rosenberg
47 *---------------------------------------------------------------------------*/
54 static SGP_ID _sgp2_cwin = NULL;
56 extern CHARSPEC cspec;
60 * sgp2_init Initialize 2 graphics system
67 sgp2_init (int xsize, int ysize, const char *win_title )
79 gid->pw_xsize = xsize;
80 gid->pw_ysize = ysize;
81 strncpy(gid->title, win_title, sizeof(gid->title));
83 gid->recalc_mc_to_ndc = TRUE;
84 gid->recalc_ndc_to_mc = TRUE;
85 ident_gmtx_2 (gid->wc_to_ndc_x);
86 ident_gmtx_2 (gid->mc_to_ndc_x);
87 ident_gmtx_2 (gid->ndc_to_mc_x);
88 ident_gmtx_2 (gid->ctm_2_x);
90 sgp2_window (0., 0., 1., 1.);
91 sgp2_viewport (0., 0., 1., 1.);
93 sgp2_move_abs (0., 0.);
96 gid->g2_id = g2_open_X11X (gid->pw_xsize, gid->pw_ysize, 10, 10, gid->title, gid->title, NULL, -1, -1);
99 _sgp2_init_dev (_sgp2_cwin);
106 sgp2_close (SGP_ID gid)
109 g2_close (gid->g2_id);
111 if (gid == _sgp2_cwin)
118 sgp2_set_active_win (SGP_ID gid)
124 sgp2_get_active_win (void)
131 * sgp2_clear Clear window
138 if (_sgp_cwin != NULL)
139 g2_clear (gid->g2_id);
144 * sgp2_window Set window in world coordinates
148 sgp2_window (double xmin, double ymin, double xmax, double ymax)
150 if (_sgp2_cwin == NULL)
153 if (xmin >= xmax || ymin >= ymax) {
154 sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_window]");
158 _sgp2_cwin->xw_min = xmin;
159 _sgp2_cwin->yw_min = ymin;
160 _sgp2_cwin->xw_max = xmax;
161 _sgp2_cwin->yw_max = ymax;
167 * sgp2_viewport Set viewport in NDC
171 sgp2_viewport (double xmin, double ymin, double xmax, double ymax)
173 if (_sgp2_cwin == NULL)
176 if (xmin >= xmax || ymin >= ymax) {
177 sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_viewport]");
181 _sgp2_cwin->xv_min = xmin;
182 _sgp2_cwin->yv_min = ymin;
183 _sgp2_cwin->xv_max = xmax;
184 _sgp2_cwin->yv_max = ymax;
187 _sgp2_cwin->view[0] = xmin; /* Array for clip_rect() */
188 _sgp2_cwin->view[1] = ymin;
189 _sgp2_cwin->view[2] = xmax;
190 _sgp2_cwin->view[3] = ymax;
195 * sgp2_frame_vpt draw box around viewport
199 sgp2_frame_vpt (void)
201 if (_sgp2_cwin == NULL)
204 _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_min, _sgp2_cwin->yv_min, 0);
205 _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_max, _sgp2_cwin->yv_min, 1);
206 _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_max, _sgp2_cwin->yv_max, 1);
207 _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_min, _sgp2_cwin->yv_max, 1);
208 _sgp2_stylus (_sgp2_cwin, _sgp2_cwin->xv_min, _sgp2_cwin->yv_min, 1);
213 * calc_wc_to_ndc Calculate transform matrix
217 calc_wc_to_ndc (void)
221 if (_sgp2_cwin == NULL)
224 sx = (_sgp2_cwin->xv_max - _sgp2_cwin->xv_min) / (_sgp2_cwin->xw_max - _sgp2_cwin->xw_min);
225 sy = (_sgp2_cwin->yv_max - _sgp2_cwin->yv_min) / (_sgp2_cwin->yw_max - _sgp2_cwin->yw_min);
227 ident_gmtx_2 (_sgp2_cwin->wc_to_ndc_x);
228 _sgp2_cwin->wc_to_ndc_x[0][0] = sx;
229 _sgp2_cwin->wc_to_ndc_x[2][0] = _sgp2_cwin->xv_min - sx * _sgp2_cwin->xw_min;
230 _sgp2_cwin->wc_to_ndc_x[1][1] = sy;
231 _sgp2_cwin->wc_to_ndc_x[2][1] = _sgp2_cwin->yv_min - sy * _sgp2_cwin->yw_min;
233 _sgp2_cwin->recalc_mc_to_ndc = TRUE;
234 _sgp2_cwin->recalc_ndc_to_mc = TRUE;
239 calc_ndc_to_mc (void)
241 if (_sgp2_cwin == NULL)
244 if (_sgp2_cwin->recalc_mc_to_ndc) {
245 mult_gmtx_2 (_sgp2_cwin->ctm_2_x, _sgp2_cwin->wc_to_ndc_x, _sgp2_cwin->mc_to_ndc_x);
246 _sgp2_cwin->recalc_mc_to_ndc = FALSE;
249 invert_gmtx_2 (_sgp2_cwin->mc_to_ndc_x, _sgp2_cwin->ndc_to_mc_x);
250 _sgp2_cwin->recalc_ndc_to_mc = FALSE;
255 * wc_to_ndc Map from world coordinates to NDC
259 wc_to_ndc (double xw, double yw, double *xn, double *yn)
261 if (_sgp2_cwin == NULL)
264 if (_sgp2_cwin->recalc_mc_to_ndc) {
265 mult_gmtx_2 (_sgp2_cwin->ctm_2_x, _sgp2_cwin->wc_to_ndc_x, _sgp2_cwin->mc_to_ndc_x);
266 _sgp2_cwin->recalc_mc_to_ndc = FALSE;
269 *xn = xw * _sgp2_cwin->mc_to_ndc_x[0][0] + yw * _sgp2_cwin->mc_to_ndc_x[1][0] + _sgp2_cwin->mc_to_ndc_x[2][0];
270 *yn = xw * _sgp2_cwin->mc_to_ndc_x[0][1] + yw * _sgp2_cwin->mc_to_ndc_x[1][1] + _sgp2_cwin->mc_to_ndc_x[2][1];
274 /*==============================================================*/
275 /* map from normalized device coords. to world coordinates */
276 /*==============================================================*/
278 ndc_to_wc (double xn, double yn, double *xw, double *yw)
280 if (_sgp2_cwin == NULL)
283 if (_sgp2_cwin->recalc_ndc_to_mc) {
285 _sgp2_cwin->recalc_ndc_to_mc = FALSE;
288 *xw = xn * _sgp2_cwin->ndc_to_mc_x[0][0] + yn * _sgp2_cwin->ndc_to_mc_x[1][0] + _sgp2_cwin->ndc_to_mc_x[2][0];
289 *yw = xn * _sgp2_cwin->ndc_to_mc_x[0][1] + yn * _sgp2_cwin->ndc_to_mc_x[1][1] + _sgp2_cwin->ndc_to_mc_x[2][1];
293 /*==============================================================*/
295 /*==============================================================*/
297 sgp2_color (int icol)
302 /*==============================================================*/
303 /* set line style. Pass 16 bit repeating pattern */
304 /*==============================================================*/
306 sgp2_line_style (int style)
311 /*==============================================================*/
312 /* absolute draw to */
313 /*==============================================================*/
315 sgp2_line_abs (double x, double y)
317 double x1, y1, x2, y2;
319 if (_sgp2_cwin == NULL)
322 wc_to_ndc (_sgp2_cwin->curx, _sgp2_cwin->cury, &x1, &y1);
323 wc_to_ndc (x, y, &x2, &y2);
325 if (clip_rect (x1, y1, x2, y2, _sgp2_cwin->view) == TRUE) { /* clip to viewport */
326 _sgp2_stylus (_sgp2_cwin, x1, y1, 0); /* move to first point */
327 _sgp2_stylus (_sgp2_cwin, x2, y2, 1); /* draw to second point */
330 _sgp2_cwin->curx = x;
331 _sgp2_cwin->cury = y;
334 /*==============================================================*/
335 /* absolute move to */
336 /*==============================================================*/
338 sgp2_move_abs (double x, double y)
340 if (_sgp2_cwin == NULL)
343 _sgp2_cwin->curx = x;
344 _sgp2_cwin->cury = y; /* moves are not clipped */
347 /*==============================================================*/
349 /*==============================================================*/
351 sgp2_line_rel (double x, double y)
353 if (_sgp2_cwin != NULL)
354 sgp2_line_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
357 /*==============================================================*/
359 /*==============================================================*/
361 sgp2_move_rel (double x, double y)
363 if (_sgp2_cwin != NULL)
364 sgp2_move_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
367 /*==============================================================*/
369 /*==============================================================*/
371 sgp2_draw_text (char *message)
374 if (_sgp2_cwin == NULL)
377 wc_to_ndc (_sgp2_cwin->curx, _sgp2_cwin->cury, &sx, &sy);
378 _sgp2_stylus (_sgp2_cwin, sx, sy, 0); /* move to location */
379 _sgp2_dev_text (_sgp2_cwin, message);
383 charsize (double wid, double height)
385 _sgp2_set_text (_sgp2_cwin, wid, height, cspec.textangle, cspec.font);
389 textangle (double angle)
391 _sgp2_set_text (_sgp2_cwin, cspec.width, cspec.height, angle, cspec.font);
395 sgp2_polyline_abs (double x[], double y[], int n)
397 double x1, y1, x2, y2;
401 if (_sgp2_cwin == NULL || n < 2)
404 wc_to_ndc (x[0], y[0], &x1, &y1);
405 wc_to_ndc (x[1], y[1], &x2, &y2);
407 xt = x2; /* don't pass (x2,y2) to clip, we need them */
408 yt = y2; /* as the beginning point of the next line */
410 if (clip_rect (x1, y1, xt, yt, _sgp2_cwin->view) == TRUE) {
411 _sgp2_stylus (_sgp2_cwin, x1, y1, 0);
412 _sgp2_stylus (_sgp2_cwin, xt, yt, 1);
415 for (i = 2; i < n; i++) {
416 x1 = x2; /* NDC endpoint of last line */
418 wc_to_ndc (x[i], y[i], &x2, &y2);
421 if (clip_rect (x1, y1, xt, yt, _sgp2_cwin->view) == TRUE) {
422 _sgp2_stylus (_sgp2_cwin, x1, y1, 0);
423 _sgp2_stylus (_sgp2_cwin, xt, yt, 1);
430 sgp2_mark_abs (double x, double y)
434 if (_sgp2_cwin == NULL)
437 wc_to_ndc (x, y, &xndc, &yndc);
438 markndc (_sgp2_cwin, xndc, yndc);
439 _sgp2_cwin->curx = x;
440 _sgp2_cwin->cury = y;
445 sgp2_mark_rel (double x, double y)
447 sgp2_mark_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
452 sgp2_point_abs (double x, double y)
456 if (_sgp2_cwin == NULL)
459 wc_to_ndc (x, y, &xndc, &yndc);
460 pntndc (_sgp2_cwin, xndc, yndc);
461 _sgp2_cwin->curx = x;
462 _sgp2_cwin->cury = y;
467 sgp2_point_rel (double x, double y)
469 sgp2_point_abs (x + _sgp2_cwin->curx, y + _sgp2_cwin->cury);
473 /*----------------------------------------------------------------------*/
474 /* Current Transformation Matrix Routine */
475 /*----------------------------------------------------------------------*/
479 * ctm_clr_2 Clear current transformation matrix
500 * OUT GRFMTX_2D m Copy of ctm
504 ctm_get_2 (GRFMTX_2D m)
508 if (_sgp2_cwin == NULL)
511 for (x = 0; x < 3; x++)
512 for (y = 0; y < 3; y++)
513 m[x][y] = _sgp2_cwin->ctm_2_x[x][y];
518 * ctm_set_2 Set ctm to a matrix
522 * IN GRFMTX m New ctm
526 ctm_set_2 (GRFMTX_2D m)
529 if (_sgp2_cwin == NULL)
532 for (x = 0; x < 3; x++)
533 for (y = 0; y < 3; y++)
534 _sgp2_cwin->ctm_2_x[x][y] = m[x][y];
536 _sgp2_cwin->recalc_ndc_to_mc = TRUE;
537 _sgp2_cwin->recalc_mc_to_ndc = TRUE;
542 ctm_pre_mult_2 (GRFMTX_2D m)
546 mult_gmtx_2 (m, _sgp2_cwin->ctm_2_x, new_ctm);
552 ctm_post_mult_2 (GRFMTX_2D m)
556 mult_gmtx_2 (_sgp2_cwin->ctm_2_x, m, new_ctm);