1 /*****************************************************************************
2 **  Copyright (C) 1998-2001  Ljubomir Milanovic & Horst Wagner
3 **  This file is part of the g2 library
4 **
5 **  This library is free software; you can redistribute it and/or
6 **  modify it under the terms of the GNU Lesser General Public
7 **  License as published by the Free Software Foundation; either
8 **  version 2.1 of the License, or (at your option) any later version.
9 **
10 **  This library is distributed in the hope that it will be useful,
11 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 **  Lesser General Public License for more details.
14 **
15 **  You should have received a copy of the GNU Lesser General Public
16 **  License along with this library; if not, write to the Free Software
17 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 ******************************************************************************/
19 #include <stdio.h>
20 
21 #include "g2_device.h"
22 #include "g2_graphic_pd.h"
23 #include "g2_util.h"
24 
25 /**
26  * \ingroup interface
27  * \defgroup graphic graphical output
28  */
29 
30 /**
31  *
32  * Move graphic cursor.
33  *
34  * \param dev device
35  * \param x x coordinate
36  * \param y y coordinate
37  *
38  * \ingroup graphic
39  */
g2_move(int dev,double x,double y)40 void g2_move(int dev, double x, double y)
41 {
42     g2_device *devp;
43     int i;
44 
45     if((devp=g2_get_device_pointer(dev))==NULL) {
46 	fprintf(stderr, "g2_move: No such device: %d\n", dev);
47 	return;
48     }
49 
50     devp->x=x;					  /* set graph. cursor */
51     devp->y=y;
52 
53     switch(devp->t) {
54       case g2_PD:
55 	break;
56       case g2_VD:
57 	for(i=0;i<devp->d.vd->N;i++)
58 	    g2_move(devp->d.vd->dix[i], x, y);
59 	break;
60       case g2_ILLEGAL:
61 	break;
62       case g2_NDEV:
63 	break;
64     }
65     __g2_last_device=dev;
66 }
67 
68 
69 
70 /**
71  *
72  * Move graphic cursor relative to the currner graphical cursor position.
73  *
74  * \param dev device
75  * \param dx x coordinate increment
76  * \param dy y coordinate increment
77  *
78  * \ingroup graphic
79  */
g2_move_r(int dev,double dx,double dy)80 void g2_move_r(int dev, double dx, double dy)
81 {
82     g2_device *devp;
83     int i;
84 
85     if((devp=g2_get_device_pointer(dev))==NULL) {
86 	fprintf(stderr, "g2_move_r: No such device: %d\n", dev);
87 	return;
88     }
89 
90     devp->x+=dx;				  /* set graph. cursor */
91     devp->y+=dy;
92 
93     switch(devp->t) {
94       case g2_PD:
95 	break;
96       case g2_VD:
97 	for(i=0;i<devp->d.vd->N;i++)
98 	    g2_move_r(devp->d.vd->dix[i], dx, dy);
99 	break;
100       case g2_ILLEGAL:
101 	break;
102       case g2_NDEV:
103 	break;
104     }
105     __g2_last_device=dev;
106 }
107 
108 
109 
110 /**
111  *
112  * Plot a point
113  *
114  * \param dev device
115  * \param x x coordinate
116  * \param y y coordinate
117  *
118  * \ingroup graphic
119  */
g2_plot(int dev,double x,double y)120 void g2_plot(int dev, double x, double y)
121 {
122     g2_device *devp;
123     int i;
124 
125     if((devp=g2_get_device_pointer(dev))==NULL) {
126 	fprintf(stderr, "g2_plot: No such device: %d\n", dev);
127 	return;
128     }
129 
130     devp->x=x;					  /* set graph. cursor */
131     devp->y=y;
132 
133     switch(devp->t) {
134       case g2_PD:
135 	g2_plot_pd(devp->d.pd, x, y);
136 	break;
137       case g2_VD:
138 	for(i=0;i<devp->d.vd->N;i++)
139 	    g2_plot(devp->d.vd->dix[i], x, y);
140 	break;
141       case g2_ILLEGAL:
142 	break;
143       case g2_NDEV:
144 	break;
145     }
146 
147     if(devp->auto_flush)
148 	g2_flush(dev);
149 
150     __g2_last_device=dev;
151 }
152 
153 
154 
155 /**
156  *
157  * Plot a point relative to graphical cursor.
158  *
159  * \param dev device
160  * \param rx relative x coordinate
161  * \param ry relative y coordinate
162  *
163  * \ingroup graphic
164  */
g2_plot_r(int dev,double rx,double ry)165 void g2_plot_r(int dev, double rx, double ry)
166 {
167     g2_device *devp;
168 
169     if((devp=g2_get_device_pointer(dev))==NULL) {
170 	fprintf(stderr, "g2_plot_r: No such device: %d\n", dev);
171 	return;
172     }
173 
174     g2_plot(dev, devp->x+rx, devp->y+ry);
175 
176     __g2_last_device=dev;
177 }
178 
179 
180 
181 /**
182  *
183  * Draw a line from \p x1, \p y1 to \p x2, \p y2.
184  *
185  * \param dev device
186  * \param x1 see above
187  * \param y1 see above
188  * \param x2 see above
189  * \param y2 see above
190  *
191  * \ingroup graphic
192  */
g2_line(int dev,double x1,double y1,double x2,double y2)193 void g2_line(int dev, double x1, double y1, double x2, double y2)
194 {
195     g2_device *devp;
196     int i;
197 
198     if((devp=g2_get_device_pointer(dev))==NULL) {
199 	fprintf(stderr, "g2_line: No such device: %d\n", dev);
200 	return;
201     }
202 
203     devp->x=x2;
204     devp->y=y2;
205 
206     switch(devp->t) {
207       case g2_PD:
208 	g2_line_pd(devp->d.pd, x1, y1, x2, y2);
209 	break;
210       case g2_VD:
211 	for(i=0;i<devp->d.vd->N;i++)
212 	    g2_line(devp->d.vd->dix[i], x1, y1, x2, y2);
213 	break;
214       case g2_ILLEGAL:
215 	break;
216       case g2_NDEV:
217 	break;
218     }
219 
220     if(devp->auto_flush)
221 	g2_flush(dev);
222 
223     __g2_last_device=dev;
224 }
225 
226 
227 
228 /**
229  *
230  * Draw line relative to the graphic cursor.
231  *
232  * \param dev device
233  * \param dx relative x coordinate
234  * \param dy relative y coordinate
235  *
236  * \ingroup graphic
237  */
g2_line_r(int dev,double dx,double dy)238 void g2_line_r(int dev, double dx, double dy)
239 {
240     g2_device *devp;
241 
242     if((devp=g2_get_device_pointer(dev))==NULL) {
243 	fprintf(stderr, "g2_line_r: No such device: %d\n", dev);
244 	return;
245     }
246     g2_line(dev, devp->x, devp->y, devp->x+dx, devp->y+dy);
247 
248     __g2_last_device=dev;
249 }
250 
251 
252 
253 /**
254  *
255  * Draw line from graphic cursor to the point \a x, \a y
256  *
257  * \param dev device
258  * \param x x coordinate
259  * \param y y coordinate
260  *
261  * \ingroup graphic
262  */
g2_line_to(int dev,double x,double y)263 void g2_line_to(int dev, double x, double y)
264 {
265     g2_device *devp;
266 
267     if((devp=g2_get_device_pointer(dev))==NULL) {
268 	fprintf(stderr, "g2_line_to: No such device: %d\n", dev);
269 	return;
270     }
271     g2_line(dev, devp->x, devp->y, x, y);
272 
273     __g2_last_device=dev;
274 }
275 
276 
277 
278 /**
279  *
280  * Draw a poly line.
281  *
282  * \param dev device
283  * \param N_pt number of points (Note: It is not size of \a points vector!)
284  * \param points vector of coordinates: x1, y1, x2, y2, ...
285  *
286  * \ingroup graphic
287  */
g2_poly_line(int dev,int N_pt,double * points)288 void g2_poly_line(int dev, int N_pt, double *points)
289 {
290     g2_device *devp;
291     int i;
292 
293     if((devp=g2_get_device_pointer(dev))==NULL) {
294 	fprintf(stderr, "g2_poly_line: No such device: %d\n", dev);
295 	return;
296     }
297 
298     devp->x=points[2*(N_pt-1)+0];
299     devp->y=points[2*(N_pt-1)+1];
300 
301     switch(devp->t) {
302       case g2_PD:
303 	g2_poly_line_pd(devp->d.pd, N_pt, points);
304 	break;
305       case g2_VD:
306 	for(i=0;i<devp->d.vd->N;i++)
307 	    g2_poly_line(devp->d.vd->dix[i], N_pt, points);
308 	break;
309       case g2_ILLEGAL:
310 	break;
311       case g2_NDEV:
312 	break;
313     }
314 
315     if(devp->auto_flush)
316 	g2_flush(dev);
317 
318     __g2_last_device=dev;
319 }
320 
321 
322 
323 /**
324  *
325  * Draw a triangle described by 3 corner points.
326  *
327  * \param dev device
328  * \param x1 x coordinate of the 1st corner
329  * \param y1 y coordinate of the 1st corner
330  * \param x2 x coordinate of the 2nd corner
331  * \param y2 y coordinate of the 2nd corner
332  * \param x3 x coordinate of the 3rd corner
333  * \param y3 y coordinate of the 3rd corner
334  *
335  * \ingroup graphic
336  */
g2_triangle(int dev,double x1,double y1,double x2,double y2,double x3,double y3)337 void g2_triangle(int dev,
338 		 double x1, double y1,
339 		 double x2, double y2,
340 		 double x3, double y3)
341 {
342     g2_device *devp;
343     int i;
344 
345     if((devp=g2_get_device_pointer(dev))==NULL) {
346 	fprintf(stderr, "g2_triangle: No such device: %d\n", dev);
347 	return;
348     }
349 
350     devp->x=x3;
351     devp->y=y3;
352 
353     switch(devp->t) {
354       case g2_PD:
355 	g2_triangle_pd(devp->d.pd,
356 		       x1, y1,
357 		       x2, y2,
358 		       x3, y3);
359 	break;
360       case g2_VD:
361 	for(i=0;i<devp->d.vd->N;i++)
362 	    g2_triangle(devp->d.vd->dix[i], x1, y1, x2, y2, x3, y3);
363 	break;
364       case g2_ILLEGAL:
365 	break;
366       case g2_NDEV:
367 	break;
368     }
369 
370     if(devp->auto_flush)
371 	g2_flush(dev);
372 
373     __g2_last_device=dev;
374 }
375 
376 
377 
378 /**
379  *
380  * Draw a filled triangle specified by the 3 corner points.
381  *
382  * \param dev device
383  * \param x1 x coordinate of the 1st corner
384  * \param y1 y coordinate of the 1st corner
385  * \param x2 x coordinate of the 2nd corner
386  * \param y2 y coordinate of the 2nd corner
387  * \param x3 x coordinate of the 3rd corner
388  * \param y3 y coordinate of the 3rd corner
389  *
390  * \ingroup graphic
391  */
g2_filled_triangle(int dev,double x1,double y1,double x2,double y2,double x3,double y3)392 void g2_filled_triangle(int dev,
393 			double x1, double y1,
394 			double x2, double y2,
395 			double x3, double y3)
396 {
397     g2_device *devp;
398     int i;
399 
400     if((devp=g2_get_device_pointer(dev))==NULL) {
401 	fprintf(stderr, "g2_filled_triangle: No such device: %d\n", dev);
402 	return;
403     }
404 
405     devp->x=x3;
406     devp->y=y3;
407 
408     switch(devp->t) {
409       case g2_PD:
410 	g2_filled_triangle_pd(devp->d.pd,
411 			      x1, y1,
412 			      x2, y2,
413 			      x3, y3);
414 	break;
415       case g2_VD:
416 	for(i=0;i<devp->d.vd->N;i++)
417 	    g2_filled_triangle(devp->d.vd->dix[i], x1, y1, x2, y2, x3, y3);
418 	break;
419       case g2_ILLEGAL:
420 	break;
421       case g2_NDEV:
422 	break;
423     }
424 
425     if(devp->auto_flush)
426 	g2_flush(dev);
427 
428     __g2_last_device=dev;
429 }
430 
431 
432 
433 /**
434  *
435  * Draw a rectangle specified by the two opposite corner points.
436  *
437  * \param dev device
438  * \param x1 x coordinate of the 1st corner
439  * \param y1 y coordinate of the 1st corner
440  * \param x2 x coordinate of the 3rd corner
441  * \param y2 y coordinate of the 3rd corner
442  *
443  * \ingroup graphic
444  */
g2_rectangle(int dev,double x1,double y1,double x2,double y2)445 void g2_rectangle(int dev, double x1, double y1, double x2, double y2)
446 {
447     g2_device *devp;
448     int i;
449 
450     if((devp=g2_get_device_pointer(dev))==NULL) {
451 	fprintf(stderr, "g2_rectangle: No such device: %d\n", dev);
452 	return;
453     }
454 
455     devp->x=x2;
456     devp->y=y2;
457 
458     switch(devp->t) {
459       case g2_PD:
460 	g2_rectangle_pd(devp->d.pd, x1, y1, x2, y2);
461 	break;
462       case g2_VD:
463 	for(i=0;i<devp->d.vd->N;i++)
464 	    g2_rectangle(devp->d.vd->dix[i], x1, y1, x2, y2);
465 	break;
466       case g2_ILLEGAL:
467 	break;
468       case g2_NDEV:
469 	break;
470     }
471 
472     if(devp->auto_flush)
473 	g2_flush(dev);
474 
475     __g2_last_device=dev;
476 }
477 
478 
479 
480 /**
481  *
482  * Draw a filled rectangle specified by the two opposite corner points.
483  *
484  * \param dev device
485  * \param x1 x coordinate of the 1st corner
486  * \param y1 y coordinate of the 1st corner
487  * \param x2 x coordinate of the 3rd corner
488  * \param y2 y coordinate of the 3rd corner
489  *
490  * \ingroup graphic
491  */
g2_filled_rectangle(int dev,double x1,double y1,double x2,double y2)492 void g2_filled_rectangle(int dev, double x1, double y1, double x2, double y2)
493 {
494     g2_device *devp;
495     int i;
496 
497     if((devp=g2_get_device_pointer(dev))==NULL) {
498 	fprintf(stderr, "g2_filled_rectangle: No such device: %d\n", dev);
499 	return;
500     }
501 
502     devp->x=x2;
503     devp->y=y2;
504 
505     switch(devp->t) {
506       case g2_PD:
507 	g2_filled_rectangle_pd(devp->d.pd, x1, y1, x2, y2);
508 	break;
509       case g2_VD:
510 	for(i=0;i<devp->d.vd->N;i++)
511 	    g2_filled_rectangle(devp->d.vd->dix[i], x1, y1, x2, y2);
512 	break;
513       case g2_ILLEGAL:
514 	break;
515       case g2_NDEV:
516 	break;
517     }
518 
519     if(devp->auto_flush)
520 	g2_flush(dev);
521 
522     __g2_last_device=dev;
523 }
524 
525 
526 
527 /**
528  *
529  * Draw a polygon.
530  *
531  * \param dev device
532  * \param N_pt number of points (Note: It is not size of \a points vector!)
533  * \param points vector of coordinates: x1, y1, x2, y2, ...
534  *
535  * \ingroup graphic
536  */
g2_polygon(int dev,int N_pt,double * points)537 void g2_polygon(int dev, int N_pt, double *points)
538 {
539     g2_device *devp;
540     int i;
541 
542     if((devp=g2_get_device_pointer(dev))==NULL) {
543 	fprintf(stderr, "g2_polygon: No such device: %d\n", dev);
544 	return;
545     }
546 
547     switch(devp->t) {
548       case g2_PD:
549 	g2_polygon_pd(devp->d.pd, N_pt, points);
550 	break;
551       case g2_VD:
552 	for(i=0;i<devp->d.vd->N;i++)
553 	    g2_polygon(devp->d.vd->dix[i], N_pt, points);
554 	break;
555       case g2_ILLEGAL:
556 	break;
557       case g2_NDEV:
558 	break;
559     }
560 
561     if(devp->auto_flush)
562 	g2_flush(dev);
563 
564     __g2_last_device=dev;
565 }
566 
567 
568 
569 /**
570  *
571  * Draw a filled polygon.
572  *
573  * \param dev device
574  * \param N_pt number of points (Note: It is not size of \a points vector!)
575  * \param points vector of coordinates: x1, y1, x2, y2, ...
576  *
577  * \ingroup graphic
578  */
g2_filled_polygon(int dev,int N_pt,double * points)579 void g2_filled_polygon(int dev, int N_pt, double *points)
580 {
581     g2_device *devp;
582     int i;
583 
584     if((devp=g2_get_device_pointer(dev))==NULL) {
585 	fprintf(stderr, "g2_filled_polygon: No such device: %d\n", dev);
586 	return;
587     }
588 
589     switch(devp->t) {
590       case g2_PD:
591 	g2_filled_polygon_pd(devp->d.pd, N_pt, points);
592 	break;
593       case g2_VD:
594 	for(i=0;i<devp->d.vd->N;i++)
595 	    g2_filled_polygon(devp->d.vd->dix[i], N_pt, points);
596 	break;
597       case g2_ILLEGAL:
598 	break;
599       case g2_NDEV:
600 	break;
601     }
602 
603     if(devp->auto_flush)
604 	g2_flush(dev);
605 
606     __g2_last_device=dev;
607 }
608 
609 
610 
611 /**
612  *
613  * Draw an ellipse.
614  *
615  * \param dev device
616  * \param x  x coordinate of the center
617  * \param y  y coordinate of the center
618  * \param r1 x radius
619  * \param r2 y radius
620  *
621  * \ingroup graphic
622  */
g2_ellipse(int dev,double x,double y,double r1,double r2)623 void g2_ellipse(int dev, double x, double y, double r1, double r2)
624 {
625     g2_device *devp;
626     int i;
627 
628     if((devp=g2_get_device_pointer(dev))==NULL) {
629 	fprintf(stderr, "g2_ellipse: No such device: %d\n", dev);
630 	return;
631     }
632 
633     devp->x=x;
634     devp->y=y;
635 
636     switch(devp->t) {
637       case g2_PD:
638 	g2_ellipse_pd(devp->d.pd, x, y, r1, r2);
639 	break;
640       case g2_VD:
641 	for(i=0;i<devp->d.vd->N;i++)
642 	    g2_ellipse(devp->d.vd->dix[i], x, y, r1, r2);
643 	break;
644       case g2_ILLEGAL:
645 	break;
646       case g2_NDEV:
647 	break;
648     }
649 
650 
651     if(devp->auto_flush)
652 	g2_flush(dev);
653 
654     __g2_last_device=dev;
655 }
656 
657 
658 
659 /**
660  *
661  * Draw a filled ellipse.
662  *
663  * \param dev device
664  * \param x  x coordinate of the center
665  * \param y  y coordinate of the center
666  * \param r1 x radius
667  * \param r2 y radius
668  *
669  * \ingroup graphic
670  */
g2_filled_ellipse(int dev,double x,double y,double r1,double r2)671 void g2_filled_ellipse(int dev, double x, double y, double r1, double r2)
672 {
673     g2_device *devp;
674     int i;
675 
676     if((devp=g2_get_device_pointer(dev))==NULL) {
677 	fprintf(stderr, "g2_filled_ellipse: No such device: %d\n", dev);
678 	return;
679     }
680 
681     devp->x=x;
682     devp->y=y;
683 
684     switch(devp->t) {
685       case g2_PD:
686 	g2_filled_ellipse_pd(devp->d.pd, x, y, r1, r2);
687 	break;
688       case g2_VD:
689 	for(i=0;i<devp->d.vd->N;i++)
690 	    g2_filled_ellipse(devp->d.vd->dix[i], x, y, r1, r2);
691 	break;
692       case g2_ILLEGAL:
693 	break;
694       case g2_NDEV:
695 	break;
696     }
697 
698 
699     if(devp->auto_flush)
700 	g2_flush(dev);
701 
702     __g2_last_device=dev;
703 }
704 
705 
706 
707 /**
708  *
709  * Draw a circle.
710  *
711  * \param dev device
712  * \param x  x coordinate of the center
713  * \param y  y coordinate of the center
714  * \param r  radius
715  *
716  * \ingroup graphic
717  */
g2_circle(int dev,double x,double y,double r)718 void g2_circle(int dev, double x, double y, double r)
719 {
720     g2_device *devp;
721     int i;
722 
723     if((devp=g2_get_device_pointer(dev))==NULL) {
724 	fprintf(stderr, "g2_circle: No such device: %d\n", dev);
725 	return;
726     }
727 
728     devp->x=x;
729     devp->y=y;
730 
731     switch(devp->t) {
732       case g2_PD:
733 	g2_circle_pd(devp->d.pd, x, y, r);
734 	break;
735       case g2_VD:
736 	for(i=0;i<devp->d.vd->N;i++)
737 	    g2_circle(devp->d.vd->dix[i], x, y, r);
738 	break;
739       case g2_ILLEGAL:
740 	break;
741       case g2_NDEV:
742 	break;
743     }
744 
745 
746     if(devp->auto_flush)
747 	g2_flush(dev);
748 
749     __g2_last_device=dev;
750 }
751 
752 
753 
754 /**
755  *
756  * Draw a filled circle.
757  *
758  * \param dev device
759  * \param x  x coordinate of the center
760  * \param y  y coordinate of the center
761  * \param r  radius
762  *
763  * \ingroup graphic
764  */
g2_filled_circle(int dev,double x,double y,double r)765 void g2_filled_circle(int dev, double x, double y, double r)
766 {
767     g2_device *devp;
768     int i;
769 
770     if((devp=g2_get_device_pointer(dev))==NULL) {
771 	fprintf(stderr, "g2_filled_circle: No such device: %d\n", dev);
772 	return;
773     }
774 
775     devp->x=x;
776     devp->y=y;
777 
778     switch(devp->t) {
779       case g2_PD:
780 	g2_filled_circle_pd(devp->d.pd, x, y, r);
781 	break;
782       case g2_VD:
783 	for(i=0;i<devp->d.vd->N;i++)
784 	    g2_filled_circle(devp->d.vd->dix[i], x, y, r);
785 	break;
786       case g2_ILLEGAL:
787 	break;
788       case g2_NDEV:
789 	break;
790     }
791 
792     if(devp->auto_flush)
793 	g2_flush(dev);
794 
795     __g2_last_device=dev;
796 }
797 
798 
799 
800 /**
801  *
802  * Draw an arc.
803  *
804  * \param dev device
805  * \param x  x coordinate of the center
806  * \param y  y coordinate of the center
807  * \param r1 x radius
808  * \param r2 y radius
809  * \param a1 starting angle (in deg. 0-360)
810  * \param a2 ending angle (in deg. 0-360)
811  *
812  * \ingroup graphic
813  */
g2_arc(int dev,double x,double y,double r1,double r2,double a1,double a2)814 void g2_arc(int dev,
815 	    double x, double y,
816 	    double r1, double r2,
817 	    double a1, double a2)
818 {
819     g2_device *devp;
820     int i;
821 
822     if((devp=g2_get_device_pointer(dev))==NULL) {
823 	fprintf(stderr, "g2_arc: No such device: %d\n", dev);
824 	return;
825     }
826 
827     devp->x=x;
828     devp->y=y;
829 
830     switch(devp->t) {
831       case g2_PD:
832 	g2_arc_pd(devp->d.pd, x, y, r1, r2, a1, a2);
833 	break;
834       case g2_VD:
835 	for(i=0;i<devp->d.vd->N;i++)
836 	    g2_arc(devp->d.vd->dix[i], x, y, r1, r2, a1, a2);
837 	break;
838       case g2_ILLEGAL:
839 	break;
840       case g2_NDEV:
841 	break;
842     }
843 
844     if(devp->auto_flush)
845 	g2_flush(dev);
846 
847     __g2_last_device=dev;
848 }
849 
850 
851 
852 /**
853  *
854  * Draw a filled arc.
855  *
856  * \param dev device
857  * \param x  x coordinate of the center
858  * \param y  y coordinate of the center
859  * \param r1 x radius
860  * \param r2 y radius
861  * \param a1 starting angle (in deg. 0-360)
862  * \param a2 ending angle (in deg. 0-360)
863  *
864  * \ingroup graphic
865  */
g2_filled_arc(int dev,double x,double y,double r1,double r2,double a1,double a2)866 void g2_filled_arc(int dev,
867 		   double x, double y,
868 		   double r1, double r2,
869 		   double a1, double a2)
870 {
871     g2_device *devp;
872     int i;
873 
874     if((devp=g2_get_device_pointer(dev))==NULL) {
875 	fprintf(stderr, "g2_filled_arc: No such device: %d\n", dev);
876 	return;
877     }
878 
879     devp->x=x;
880     devp->y=y;
881 
882     switch(devp->t) {
883       case g2_PD:
884 	g2_filled_arc_pd(devp->d.pd, x, y, r1, r2, a1, a2);
885 	break;
886       case g2_VD:
887 	for(i=0;i<devp->d.vd->N;i++)
888 	    g2_filled_arc(devp->d.vd->dix[i], x, y, r1, r2, a1, a2);
889 	break;
890       case g2_ILLEGAL:
891 	break;
892       case g2_NDEV:
893 	break;
894     }
895 
896     if(devp->auto_flush)
897 	g2_flush(dev);
898 
899     __g2_last_device=dev;
900 }
901 
902 
903 
904 /**
905  *
906  * Draw string, see also g2_set_font_size().
907  *
908  * \param dev device
909  * \param x  x coordinate
910  * \param y  y coordinate
911  * \param text null terminated string
912  *
913  * \ingroup graphic
914  */
g2_string(int dev,double x,double y,const char * text)915 void g2_string(int dev, double x, double y, const char *text)
916 {
917     g2_device *devp;
918     int i;
919 
920     if((devp=g2_get_device_pointer(dev))==NULL) {
921 	fprintf(stderr, "g2_string: No such device: %d\n", dev);
922 	return;
923     }
924 
925     devp->x=x;
926     devp->y=y;
927 
928     switch(devp->t) {
929       case g2_PD:
930 	g2_string_pd(devp->d.pd, x, y, text);
931 	break;
932       case g2_VD:
933 	for(i=0;i<devp->d.vd->N;i++)
934 	    g2_string(devp->d.vd->dix[i], x, y, text);
935 	break;
936       case g2_ILLEGAL:
937 	break;
938       case g2_NDEV:
939 	break;
940     }
941 
942     if(devp->auto_flush)
943 	g2_flush(dev);
944 
945     __g2_last_device=dev;
946 }
947 
948 
949 
950 /**
951  *
952  * Draw a pen image
953  *
954  * \param dev device
955  * \param x  x coordinate
956  * \param y  y coordinate
957  * \param x_size  x size
958  * \param y_size  y size
959  * \param pens vector of x_size*y_size pens: p11, p21, ... pxy, ...
960  *
961  * \ingroup graphic
962  */
g2_image(int dev,double x,double y,int x_size,int y_size,int * pens)963 void g2_image(int dev, double x, double y, int x_size, int y_size, int *pens)
964 {
965     g2_device *devp;
966     int i;
967 
968     if((devp=g2_get_device_pointer(dev))==NULL) {
969 	fprintf(stderr, "g2_image: No such device: %d\n", dev);
970 	return;
971     }
972 
973     devp->x=x;
974     devp->y=y;
975 
976     switch(devp->t) {
977       case g2_PD:
978 	g2_image_pd(devp->d.pd, x, y, x_size, y_size, pens);
979 	break;
980       case g2_VD:
981 	for(i=0;i<devp->d.vd->N;i++)
982 	    g2_image(devp->d.vd->dix[i], x, y, x_size, y_size, pens);
983 	break;
984       case g2_ILLEGAL:
985 	break;
986       case g2_NDEV:
987 	break;
988     }
989 
990     if(devp->auto_flush)
991 	g2_flush(dev);
992 
993     __g2_last_device=dev;
994 }
995 
996 
997 
998 /**
999  *
1000  * Quasi Pixel fake. Quasi pixel is introduced to make easier
1001  * plotting of cellular automata and related pictures. QP is simple a big pixel as
1002  * specified by g2_set_QP(). Coordinates are skaled accordingly, so no recalculation
1003  * is needed on client side.
1004  *
1005  * \param dev device
1006  * \param x  x coordinate
1007  * \param y  y coordinate
1008  *
1009  * \ingroup graphic
1010  */
g2_plot_QP(int dev,double x,double y)1011 void g2_plot_QP(int dev, double x, double y)
1012 {
1013     g2_device *devp;
1014     double d;
1015 
1016     if((devp=g2_get_device_pointer(dev))==NULL) {
1017 	fprintf(stderr, "g2_plot_QP: No such device: %d\n", dev);
1018 	return;
1019     }
1020 
1021     x=dtoi(x);
1022     y=dtoi(y);
1023     d=devp->QPd;
1024     switch(devp->QPshape) {
1025       case QPrect:
1026 	g2_filled_rectangle(dev, x*d-d/2, y*d-d/2, x*d+d/2, y*d+d/2);
1027 	break;
1028       case QPcirc:
1029 	g2_filled_circle(dev, x*d, y*d, d/2.0);
1030 	break;
1031       default:
1032 	fprintf(stderr, "g2: QP: unknown shape\n");
1033 	break;
1034     }
1035     if(devp->auto_flush)
1036         g2_flush(dev);
1037 
1038     __g2_last_device=dev;
1039 }
1040 
1041 
1042 
1043 
1044 
1045 
1046