1 
2 /*
3    PGPLOT.xs
4 
5    A few routines in C to speed up PDL access to PGPLOT primitives.
6 
7 */
8 
9 #include "EXTERN.h"   /* std perl include */
10 #include "perl.h"     /* std perl include */
11 #include "XSUB.h"     /* XSUB include */
12 #include "ppport.h"   /* for backwards comaptibility */
13 
14 struct PGPLOT_function_handle {
15    I32 binversion;
16    void (*cpgmove) (float x, float y);
17    void (*cpgdraw) (float x, float y);
18    void (*cpgqcir) (int *icilo, int *icihi);
19    void (*cpgsci)  (int ci);
20    void (*cpgpt1)  (float x, float y, int sym);
21 };
22 
23 typedef struct PGPLOT_function_handle PGPLOT_function_handle;
24 
25 static I32 PGPLOT_structure_version = 20000302;  /* The date the PGPLOT structure changed */
26 static PGPLOT_function_handle  *myhandle;
27 SV *ptr;
28 
29 MODULE = PDL::Graphics::PGPLOT::Window     PACKAGE = PDL::Graphics::PGPLOT::Window
30 
31 void
pggapline(n,msgval,xpts,ypts)32 pggapline(n,msgval,xpts,ypts)
33   int	n
34   float msgval
35   float *	xpts
36   float *	ypts
37   CODE:
38     { int i;
39       int start = 0;
40       while (xpts[start] == msgval) start++;  /* make sure we have a good starting point */
41       myhandle->cpgmove (xpts[start], ypts[start]);
42       for (i=start+1;i<n;i++) {
43         if (ypts[i] == msgval) {
44            /* check we are not at end of array and we don't move to a missing value */
45            if (i != n-1 && ypts[i+1] != msgval) {
46              myhandle->cpgmove (xpts[i+1], ypts[i+1]);
47            }
48         }
49         else {
50           myhandle->cpgdraw (xpts[i], ypts[i]);
51         }
52       }
53     }
54 
55 
56 
57 void
pgcolorpnts(n,x,y,z,sym)58 pgcolorpnts(n,x,y,z,sym)
59   int	n
60   float *	x
61   float *	y
62   float *	z
63   int   sym
64   CODE:
65     {
66       /* find range of color pallette */
67       int icilo, icihi, i, cirange, ci;
68       float minz, maxz, zrange;
69 
70       /* If the structure read from the PGPLOT module is too old */
71       if (myhandle->binversion < PGPLOT_structure_version) {
72 	char msg[128];
73         sprintf (msg, "This function requires PGPLOT with a structure version at least %d.\nPlease upgrade your PGPLOT package.",
74                        PGPLOT_structure_version);
75 
76         Perl_croak(aTHX_ "%s", msg);
77       }
78 
79       myhandle->cpgqcir(&icilo, &icihi);
80 
81       /* find min and max values of zpts variable */
82       minz =  9.99e30;
83       maxz = -9.99e30;
84       for (i=0;i<n;i++) {
85 	if (z[i] < minz) minz = z[i];
86 	if (z[i] > maxz) maxz = z[i];
87       }
88 
89       /* determine range of available z indices and range of input 'z' values */
90       cirange = icihi - icilo;
91       zrange  = maxz  - minz;
92 
93       /* printf ("cilo = %d, cihi = %d\n", icilo, icihi); */
94 
95       /* for each input point, compute a scaled color index and plot the point */
96       for (i=0;i<n;i++) {
97 	ci = (int)(icilo + (z[i] - minz) * (float)(cirange/zrange));
98 	/* printf ("x = %f, y = %f, ci = %d\n", x[i], y[i], ci); */
99 	myhandle->cpgsci(ci);
100 	myhandle->cpgpt1(x[i], y[i], sym);
101       }
102     }
103 
104 
105 
106 BOOT:
107 
108 	/* Get pointer to structure of core shared C routines */
109 	ptr = get_sv("PGPLOT::HANDLE",FALSE | GV_ADDMULTI);  /* SV* value */
110 #ifndef aTHX_
111 #define aTHX_
112 #endif
113 	if (ptr==NULL)
114 	  Perl_croak(aTHX_ "This module requires PGPLOT version 2.16 or later.\nPlease install/upgrade PGPLOT (see the PDL/DEPENDENCIES file).");
115 	myhandle = INT2PTR(PGPLOT_function_handle*,SvIV( ptr ));
116 
117 
118 
119