PLplot: plctrl.c Source File

PLplot 5.15.0

plctrl.c
Go to the documentation of this file.
1 // Misc. control routines, like begin, end, exit, change graphics/text
2 // mode, change color. Includes some spillage from plcore.c. If you
3 // don't know where it should go, put it here.
4 //
5 // Copyright (C) 1993-2005 Maurice LeBrun
6 // Copyright (C) 1995-2002 Geoffrey Furnish
7 // Copyright (C) 1996 Rady Shouman
8 // Copyright (C) 2000-2019 Alan W. Irwin
9 // Copyright (C) 2001-2003 Joao Cardoso
10 // Copyright (C) 2001-2005 Rafael Laboissiere
11 // Copyright (C) 2002 Vince Darley
12 // Copyright (C) 2002-2007 Andrew Roach
13 // Copyright (C) 2004-2013 Andrew Ross
14 // Copyright (C) 2005 Thomas Duck
15 // Copyright (C) 2006-2011 Arjen Markus
16 // Copyright (C) 2006-2011 Hazen Babcock
17 // Copyright (C) 2008-2009 Werner Smekal
18 // Copyright (C) 2009-2011 Hezekiah M. Carty
19 // Copyright (C) 2015-2018 Phil Rosenberg
20 //
21 // This file is part of PLplot.
22 //
23 // PLplot is free software; you can redistribute it and/or modify
24 // it under the terms of the GNU Library General Public License as published
25 // by the Free Software Foundation; either version 2 of the License, or
26 // (at your option) any later version.
27 //
28 // PLplot is distributed in the hope that it will be useful,
29 // but WITHOUT ANY WARRANTY; without even the implied warranty of
30 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 // GNU Library General Public License for more details.
32 //
33 // You should have received a copy of the GNU Library General Public License
34 // along with PLplot; if not, write to the Free Software
35 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
36 //
37 //
38
44
45 #define DEBUG
46
47 #define NEED_PLDEBUG
48 #include "plplotP.h"
49 #ifdef macintosh
50 #include "mac.h"
51 // for plMacLibOpen prototype; used in plLibOpen
52 #endif
53
54 #ifdef DJGPP // dos386/djgpp
55 #ifdef __unix
56 #undef __unix
57 #endif
58 #endif
59
60 #ifdef __unix
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #ifdef PL_HAVE_UNISTD_H
64 #include <unistd.h>
65 #endif
66 #include <errno.h>
67 #endif
68
69 // Random number generator (Mersenne Twister)
70 #include "mt19937ar.h"
71
72 #define BUFFER_SIZE 256
73 #define COLLEN 30
74 #define PALLEN 160
75 #define MSGLEN 1024
76
77 // small epsilon for fuzzy range checks that is still large enough to
78 // work even in the single precision floating point case.
79 #define FUZZ_EPSILON 1.e-4
80
81 // Used by any external init code to suggest a path
82 char PLDLLIMPEXP * plplotLibDir = 0;
83
84 // Static functions
85
86 static void
87 limit_rgba_range( PLCHAR_VECTOR message, PLINT_NC_SCALAR r, PLINT_NC_SCALAR g, PLINT_NC_SCALAR b, PLFLT_NC_SCALAR alpha );
88
89 static void
90 color_set( PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, PLCHAR_VECTOR name );
91
92 static void
93 strcat_delim( char *dirspec );
94
95 static int
96 ( *exit_handler )( PLCHAR_VECTOR errormsg );
97
98 static void
99 ( *abort_handler )( PLCHAR_VECTOR errormsg );
100
101 static void
102 plcmap0_def( int imin, int imax );
103
104 static void
105 plcmap1_def( void );
106
107 static PLFLT
108 value( double n1, double n2, double hue );
109
110 static char *
111 read_line( char *buffer, int length, FILE *fp );
112
113 static void
114 cmap0_palette_read( PLCHAR_VECTOR filename,
115 int *number_colors, unsigned int **r, unsigned int **g,
116 unsigned int **b, double **a );
117
118 // An additional hardwired location for lib files.
119 // I have no plans to change these again, ever.
120
121 #if defined ( DJGPP )
122 #ifndef PLLIBDEV
123 #define PLLIBDEV "c:/plplot/lib"
124 #endif
125
126 #elif defined ( MSDOS )
127 #ifndef PLLIBDEV
128 #define PLLIBDEV "c:\\plplot\\lib"
129 #endif
130
131 #else
132
133 // Anything else is assumed to be Unix
134
135 #ifndef PLLIBDEV
136 #define PLLIBDEV "/usr/local/plplot/lib"
137 #endif
138
139 #endif
140
141 //--------------------------------------------------------------------------
142 // Routines that deal with colors & color maps.
143 //--------------------------------------------------------------------------
144
145 //--------------------------------------------------------------------------
146 // plcol0()
147 //
152
153 void
154 c_plcol0( PLINT icol0 )
155 {
156 if ( plsc->level < 1 )
157 {
158 plabort( "plcol0: Please call plinit first" );
159 return;
160 }
161 if ( icol0 < 0 || icol0 >= plsc->ncol0 )
162 {
163 char buffer[BUFFER_SIZE];
164 snprintf( buffer, BUFFER_SIZE, "plcol0: Invalid color map entry: %d", (int) icol0 );
165 plabort( buffer );
166 return;
167 }
168
169 plsc->icol0 = icol0;
170 plsc->curcolor.r = plsc->cmap0[icol0].r;
171 plsc->curcolor.g = plsc->cmap0[icol0].g;
172 plsc->curcolor.b = plsc->cmap0[icol0].b;
173 plsc->curcolor.a = plsc->cmap0[icol0].a;
174
175 plsc->curcmap = 0;
176 plP_state( PLSTATE_COLOR0 );
177 }
178
179 //--------------------------------------------------------------------------
180 // plcol1()
181 //
186
187 void
188 c_plcol1( PLFLT col1 )
189 {
190 PLINT icol1;
191
192 if ( plsc->level < 1 )
193 {
194 plabort( "plcol1: Please call plinit first" );
195 return;
196 }
197 if ( col1 < MIN_PLFLT_CMAP1 || col1 > MAX_PLFLT_CMAP1 || isnan( col1 ) )
198 {
199 plwarn( "plcol1: Invalid cmap1 index" );
200 fprintf( stderr, "%s\n", "Further information relevant to this warning:" );
201 fprintf( stderr, "%s%e\n", "Invalid index = ", col1 );
202 col1 = MIN_PLFLT_CMAP1;
203 fprintf( stderr, "%s%e\n", "Corrected index = ", col1 );
204 }
205
206 icol1 = (PLINT) ( col1 * plsc->ncol1 );
207 icol1 = MIN( icol1, plsc->ncol1 - 1 );
208
209 plsc->icol1 = icol1;
210 plsc->curcolor.r = plsc->cmap1[plsc->icol1].r;
211 plsc->curcolor.g = plsc->cmap1[plsc->icol1].g;
212 plsc->curcolor.b = plsc->cmap1[plsc->icol1].b;
213 plsc->curcolor.a = plsc->cmap1[plsc->icol1].a;
214
215 plsc->curcmap = 1;
216 plP_state( PLSTATE_COLOR1 );
217 }
218
219 //--------------------------------------------------------------------------
220 // plscolbg()
221 //
227
228 void
229 c_plscolbg( PLINT r, PLINT g, PLINT b )
230 {
231 plscol0( 0, r, g, b );
232 }
233
234 //--------------------------------------------------------------------------
235 // plscolbga()
236 //
244
245 //--------------------------------------------------------------------------
246
247 void
248 c_plscolbga( PLINT r, PLINT g, PLINT b, PLFLT alpha )
249 {
250 plscol0a( 0, r, g, b, alpha );
251 }
252
253 //--------------------------------------------------------------------------
254 // plgcolbg()
255 //
261
262 void
263 c_plgcolbg( PLINT *r, PLINT *g, PLINT *b )
264 {
265 plgcol0( 0, r, g, b );
266 }
267
268 //--------------------------------------------------------------------------
269 // plgcolbga()
270 //
277
278 void
279 c_plgcolbga( PLINT *r, PLINT *g, PLINT *b, PLFLT *alpha )
280 {
281 plgcol0a( 0, r, g, b, alpha );
282 }
283
284 //--------------------------------------------------------------------------
285 // plscol0()
286 //
294
295 void
296 c_plscol0( PLINT icol0, PLINT r, PLINT g, PLINT b )
297 {
298 if ( plsc->cmap0 == NULL )
299 plscmap0n( 0 );
300 if ( icol0 < 0 || icol0 >= plsc->ncol0 )
301 {
302 char buffer[BUFFER_SIZE];
303 snprintf( buffer, BUFFER_SIZE, "plscol0: Illegal color table value: %d", (int) icol0 );
304 plabort( buffer );
305 return;
306 }
307
308 limit_rgba_range( "plscol0: invalid cmap0 RGB color has been corrected", &r, &g, &b, NULL );
309
310 plscol0a( icol0, r, g, b, MAX_PLFLT_ALPHA );
311 }
312
313 //--------------------------------------------------------------------------
314 // plscol0a()
315 //
324
325 void
326 c_plscol0a( PLINT icol0, PLINT r, PLINT g, PLINT b, PLFLT alpha )
327 {
328 if ( plsc->cmap0 == NULL )
329 plscmap0n( 0 );
330 if ( icol0 < 0 || icol0 >= plsc->ncol0 )
331 {
332 char buffer[BUFFER_SIZE];
333 snprintf( buffer, BUFFER_SIZE, "plscol0a: Illegal color table value: %d", (int) icol0 );
334 plabort( buffer );
335 return;
336 }
337 limit_rgba_range( "plscol0a: invalid cmap0 RGBA color has been corrected", &r, &g, &b, &alpha );
338 plsc->cmap0[icol0].r = (unsigned char) r;
339 plsc->cmap0[icol0].g = (unsigned char) g;
340 plsc->cmap0[icol0].b = (unsigned char) b;
341 plsc->cmap0[icol0].a = alpha;
342
343 if ( plsc->level > 0 )
344 plP_state( PLSTATE_CMAP0 );
345 }
346
347 //--------------------------------------------------------------------------
348 // plgcol0()
349 //
357
358 void
359 c_plgcol0( PLINT icol0, PLINT *r, PLINT *g, PLINT *b )
360 {
361 if ( plsc->cmap0 == NULL )
362 plscmap0n( 0 );
363
364 *r = -1;
365 *g = -1;
366 *b = -1;
367
368 if ( icol0 < 0 || icol0 > plsc->ncol0 )
369 {
370 char buffer[BUFFER_SIZE];
371 snprintf( buffer, BUFFER_SIZE, "plgcol0: Invalid color index: %d", (int) icol0 );
372 plabort( buffer );
373 return;
374 }
375
376 *r = plsc->cmap0[icol0].r;
377 *g = plsc->cmap0[icol0].g;
378 *b = plsc->cmap0[icol0].b;
379
380 return;
381 }
382
383 //--------------------------------------------------------------------------
384 // plgcol0a()
385 //
394
395 void
396 c_plgcol0a( PLINT icol0, PLINT *r, PLINT *g, PLINT *b, PLFLT *alpha )
397 {
398 if ( plsc->cmap0 == NULL )
399 plscmap0n( 0 );
400
401 if ( icol0 < 0 || icol0 > plsc->ncol0 )
402 {
403 char buffer[BUFFER_SIZE];
404 snprintf( buffer, BUFFER_SIZE, "plgcol0: Invalid color index: %d. Return opaque red as a warning of this condition.", (int) icol0 );
405 *r = MAX_PLINT_RGB;
406 *g = MIN_PLINT_RGB;
407 *b = MIN_PLINT_RGB;
408 *alpha = MAX_PLFLT_ALPHA;
409
410 plabort( buffer );
411 return;
412 }
413
414 *r = plsc->cmap0[icol0].r;
415 *g = plsc->cmap0[icol0].g;
416 *b = plsc->cmap0[icol0].b;
417 *alpha = plsc->cmap0[icol0].a;
418
419 return;
420 }
421
422 //--------------------------------------------------------------------------
423 // plscmap0()
424 //
432
433 void
434 c_plscmap0( PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLINT ncol0 )
435 {
436 int i;
437 PLINT nc_r, nc_g, nc_b;
438
439 plscmap0n( ncol0 );
440
441 for ( i = 0; i < plsc->ncol0; i++ )
442 {
443 // Need these assignments so that r[i], g[i], and b[i] remain
444 // unchanged as per their PLINT_VECTOR types.
445 nc_r = r[i];
446 nc_g = g[i];
447 nc_b = b[i];
448 limit_rgba_range( "plscmap0: invalid cmap0 RGB color has been corrected", &nc_r, &nc_g, &nc_b, NULL );
449 plsc->cmap0[i].r = (unsigned char) nc_r;
450 plsc->cmap0[i].g = (unsigned char) nc_g;
451 plsc->cmap0[i].b = (unsigned char) nc_b;
452 plsc->cmap0[i].a = MAX_PLFLT_ALPHA;
453 }
454
455 if ( plsc->level > 0 )
456 plP_state( PLSTATE_CMAP0 );
457 }
458
459 //--------------------------------------------------------------------------
460 // plscmap0a()
461 //
470
471 void
472 c_plscmap0a( PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLFLT_VECTOR alpha, PLINT ncol0 )
473 {
474 int i;
475 PLINT nc_r, nc_g, nc_b;
476 PLFLT nc_alpha;
477
478
479 plscmap0n( ncol0 );
480
481 for ( i = 0; i < plsc->ncol0; i++ )
482 {
483 // Need these assignments so that r[i], g[i], b[i], and
484 // alpha[i] remain unchanged as per their PLINT_VECTOR and
485 // PLFLT_VECTOR types.
486 nc_r = r[i];
487 nc_g = g[i];
488 nc_b = b[i];
489 nc_alpha = alpha[i];
490 limit_rgba_range( "plscmap0a: invalid cmap0 RGBA color has been corrected", &nc_r, &nc_g, &nc_b, &nc_alpha );
491 plsc->cmap0[i].r = (unsigned char) nc_r;
492 plsc->cmap0[i].g = (unsigned char) nc_g;
493 plsc->cmap0[i].b = (unsigned char) nc_b;
494 plsc->cmap0[i].a = nc_alpha;
495 }
496
497 if ( plsc->level > 0 )
498 plP_state( PLSTATE_CMAP0 );
499 }
500
501 //--------------------------------------------------------------------------
502 // plscmap1()
503 //
511
512 void
513 c_plscmap1( PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLINT ncol1 )
514 {
515 int i;
516 PLINT nc_r, nc_g, nc_b;
517
518 plscmap1n( ncol1 );
519
520 for ( i = 0; i < plsc->ncol1; i++ )
521 {
522 // Need these assignments so that r[i], g[i], and b[i] remain
523 // unchanged as per their PLINT_VECTOR PLINT_VECTOR types.
524 nc_r = r[i];
525 nc_g = g[i];
526 nc_b = b[i];
527 limit_rgba_range( "plscmap1: invalid cmap1 RGB color has been corrected", &nc_r, &nc_g, &nc_b, NULL );
528 plsc->cmap1[i].r = (unsigned char) nc_r;
529 plsc->cmap1[i].g = (unsigned char) nc_g;
530 plsc->cmap1[i].b = (unsigned char) nc_b;
531 plsc->cmap1[i].a = MAX_PLFLT_ALPHA;
532 }
533
534 if ( plsc->level > 0 )
535 plP_state( PLSTATE_CMAP1 );
536 }
537
538 //--------------------------------------------------------------------------
539 // plscmap1a()
540 //
549
550 void
551 c_plscmap1a( PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLFLT_VECTOR alpha, PLINT ncol1 )
552 {
553 int i;
554 PLINT nc_r, nc_g, nc_b;
555 PLFLT nc_alpha;
556
557 plscmap1n( ncol1 );
558
559 for ( i = 0; i < plsc->ncol1; i++ )
560 {
561 // Need these assignments so that r[i], g[i], b[i], and
562 // alpha[i] remain unchanged as per their PLINT_VECTOR and
563 // PLFLT_VECTOR types.
564 nc_r = r[i];
565 nc_g = g[i];
566 nc_b = b[i];
567 nc_alpha = alpha[i];
568 limit_rgba_range( "plscmap1a: invalid cmap1 RGBA color has been corrected", &nc_r, &nc_g, &nc_b, &nc_alpha );
569 plsc->cmap1[i].r = (unsigned char) nc_r;
570 plsc->cmap1[i].g = (unsigned char) nc_g;
571 plsc->cmap1[i].b = (unsigned char) nc_b;
572 plsc->cmap1[i].a = nc_alpha;
573 }
574
575 if ( plsc->level > 0 )
576 plP_state( PLSTATE_CMAP1 );
577 }
578
579 //--------------------------------------------------------------------------
580 // plscmap1l()
581 //
630
631 void
632 c_plscmap1l( PLINT itype, PLINT npts, PLFLT_VECTOR intensity,
633 PLFLT_VECTOR coord1, PLFLT_VECTOR coord2, PLFLT_VECTOR coord3, PLINT_VECTOR alt_hue_path )
634 {
635 int n;
636
637 if ( npts < 2 )
638 {
639 plabort( "plscmap1l: Must specify at least two control points" );
640 return;
641 }
642
643 if ( ( intensity[0] != MIN_PLFLT_CMAP1 ) || ( intensity[npts - 1] != MAX_PLFLT_CMAP1 ) )
644 {
645 plabort( "plscmap1l: First and last control points must correspond to minimum and maximum cmap1 color index" );
646 return;
647 }
648
649 if ( npts > PL_MAX_CMAP1CP )
650 {
651 plabort( "plscmap1l: exceeded maximum number of control points" );
652 return;
653 }
654
655 // Allocate if not done yet
656
657 if ( plsc->cmap1 == NULL )
658 plscmap1n( 0 );
659
660 // Save control points
661
662 plsc->cmap1cp_is_rgb = itype == 0 ? 0 : 1;
663 plsc->ncp1 = npts;
664
665 for ( n = 0; n < npts; n++ )
666 {
667 plsc->cmap1cp[n].c1 = coord1[n];
668 plsc->cmap1cp[n].c2 = coord2[n];
669 plsc->cmap1cp[n].c3 = coord3[n];
670 plsc->cmap1cp[n].p = intensity[n];
671 plsc->cmap1cp[n].a = MAX_PLFLT_ALPHA;
672
673 if ( alt_hue_path == NULL )
674 plsc->cmap1cp[n].alt_hue_path = 0;
675 else if ( n != npts - 1 )
676 plsc->cmap1cp[n].alt_hue_path = alt_hue_path[n];
677 else
678 // Note final element is unused, so we set to zero for completeness.
679 plsc->cmap1cp[n].alt_hue_path = 0;
680 }
681
682 // Calculate and set color map
683
684 plcmap1_calc();
685 }
686
687 //--------------------------------------------------------------------------
688 // plscmap1la()
689 //
701
702 void
703 c_plscmap1la( PLINT itype, PLINT npts, PLFLT_VECTOR intensity,
704 PLFLT_VECTOR coord1, PLFLT_VECTOR coord2, PLFLT_VECTOR coord3, PLFLT_VECTOR alpha, PLINT_VECTOR alt_hue_path )
705 {
706 int n;
707
708 if ( npts < 2 )
709 {
710 plabort( "plscmap1la: Must specify at least two control points" );
711 return;
712 }
713
714 if ( ( intensity[0] != MIN_PLFLT_CMAP1 ) || ( intensity[npts - 1] != MAX_PLFLT_CMAP1 ) )
715 {
716 plabort( "plscmap1la: First, last control points must lie on boundary" );
717 return;
718 }
719
720 if ( npts > PL_MAX_CMAP1CP )
721 {
722 plabort( "plscmap1la: exceeded maximum number of control points" );
723 return;
724 }
725
726 // Allocate if not done yet
727
728 if ( plsc->cmap1 == NULL )
729 plscmap1n( 0 );
730
731 // Save control points
732
733 plsc->cmap1cp_is_rgb = itype == 0 ? 0 : 1;
734 plsc->ncp1 = npts;
735
736 for ( n = 0; n < npts; n++ )
737 {
738 plsc->cmap1cp[n].c1 = coord1[n];
739 plsc->cmap1cp[n].c2 = coord2[n];
740 plsc->cmap1cp[n].c3 = coord3[n];
741 plsc->cmap1cp[n].p = intensity[n];
742 plsc->cmap1cp[n].a = alpha[n];
743
744 if ( alt_hue_path == NULL )
745 plsc->cmap1cp[n].alt_hue_path = 0;
746 else if ( n != npts - 1 )
747 plsc->cmap1cp[n].alt_hue_path = alt_hue_path[n];
748 else
749 // Note final element is unused, so we set to zero for completeness.
750 plsc->cmap1cp[n].alt_hue_path = 0;
751 }
752
753 // Calculate and set color map
754
755 plcmap1_calc();
756 }
757
758 //--------------------------------------------------------------------------
759 // plcmap1_calc()
760 //
762
763 void
764 plcmap1_calc( void )
765 {
766 int i, n;
767 PLFLT delta, dp, dh, dl, ds, da, dr, dg, db;
768 PLFLT h, l, s, p, r, g, b, a;
769
770 // Loop over all control point pairs
771 if ( !plsc->cmap1cp_is_rgb )
772 {
773 for ( n = 0; n < plsc->ncp1 - 1; n++ )
774 {
775 if ( plsc->cmap1cp[n].p == plsc->cmap1cp[n + 1].p )
776 continue;
777
778 // Differences in p, h, l, s between ctrl pts
779
780 dp = plsc->cmap1cp[n + 1].p - plsc->cmap1cp[n].p;
781 dh = plsc->cmap1cp[n + 1].c1 - plsc->cmap1cp[n].c1;
782 dl = plsc->cmap1cp[n + 1].c2 - plsc->cmap1cp[n].c2;
783 ds = plsc->cmap1cp[n + 1].c3 - plsc->cmap1cp[n].c3;
784 da = plsc->cmap1cp[n + 1].a - plsc->cmap1cp[n].a;
785
786 // Adjust dh if we are to go around "the back side"
787
788 if ( plsc->cmap1cp[n].alt_hue_path )
789 dh = ( dh > 0 ) ? dh - 360 : dh + 360;
790
791 // Loop over all color cells. Only interested in cells located (in
792 // cmap1 space) between n_th and n+1_th control points
793
794 for ( i = 0; i < plsc->ncol1; i++ )
795 {
796 p = (double) i / ( plsc->ncol1 - 1.0 );
797 if ( ( p < plsc->cmap1cp[n].p ) ||
798 ( p > plsc->cmap1cp[n + 1].p ) )
799 continue;
800
801 // Interpolate based on position of color cell in cmap1 space
802
803 delta = ( p - plsc->cmap1cp[n].p ) / dp;
804
805 // Linearly interpolate to get color cell h, l, s values
806
807 h = plsc->cmap1cp[n].c1 + dh * delta;
808 l = plsc->cmap1cp[n].c2 + dl * delta;
809 s = plsc->cmap1cp[n].c3 + ds * delta;
810 a = plsc->cmap1cp[n].a + da * delta;
811
812 while ( h >= 360. )
813 h -= 360.;
814
815 while ( h < 0. )
816 h += 360.;
817
818 c_plhlsrgb( h, l, s, &r, &g, &b );
819
820 plsc->cmap1[i].r = (unsigned char) MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, (int) ( ( MAX_PLINT_RGB + 1 ) * r ) ) );
821 plsc->cmap1[i].g = (unsigned char) MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, (int) ( ( MAX_PLINT_RGB + 1 ) * g ) ) );
822 plsc->cmap1[i].b = (unsigned char) MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, (int) ( ( MAX_PLINT_RGB + 1 ) * b ) ) );
823 plsc->cmap1[i].a = MAX( MIN_PLFLT_ALPHA, MIN( MAX_PLFLT_ALPHA, a ) );
824 }
825 }
826 }
827 else
828 {
829 for ( n = 0; n < plsc->ncp1 - 1; n++ )
830 {
831 if ( plsc->cmap1cp[n].p == plsc->cmap1cp[n + 1].p )
832 continue;
833
834 // Differences in p, h, l, s between ctrl pts
835
836 dp = plsc->cmap1cp[n + 1].p - plsc->cmap1cp[n].p;
837 dr = plsc->cmap1cp[n + 1].c1 - plsc->cmap1cp[n].c1;
838 dg = plsc->cmap1cp[n + 1].c2 - plsc->cmap1cp[n].c2;
839 db = plsc->cmap1cp[n + 1].c3 - plsc->cmap1cp[n].c3;
840 da = plsc->cmap1cp[n + 1].a - plsc->cmap1cp[n].a;
841
842 // Loop over all color cells. Only interested in cells located (in
843 // cmap1 space) between n_th and n+1_th control points
844
845 for ( i = 0; i < plsc->ncol1; i++ )
846 {
847 p = (double) i / ( plsc->ncol1 - 1.0 );
848 if ( ( p < plsc->cmap1cp[n].p ) ||
849 ( p > plsc->cmap1cp[n + 1].p ) )
850 continue;
851
852 // Interpolate based on position of color cell in cmap1 space
853
854 delta = ( p - plsc->cmap1cp[n].p ) / dp;
855
856 // Linearly interpolate to get color cell h, l, s values
857
858 r = plsc->cmap1cp[n].c1 + dr * delta;
859 g = plsc->cmap1cp[n].c2 + dg * delta;
860 b = plsc->cmap1cp[n].c3 + db * delta;
861 a = plsc->cmap1cp[n].a + da * delta;
862
863 plsc->cmap1[i].r = (unsigned char) MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, (int) ( ( MAX_PLINT_RGB + 1 ) * r ) ) );
864 plsc->cmap1[i].g = (unsigned char) MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, (int) ( ( MAX_PLINT_RGB + 1 ) * g ) ) );
865 plsc->cmap1[i].b = (unsigned char) MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, (int) ( ( MAX_PLINT_RGB + 1 ) * b ) ) );
866 plsc->cmap1[i].a = MAX( MIN_PLFLT_ALPHA, MIN( MAX_PLFLT_ALPHA, a ) );
867 }
868 }
869 }
870
871 if ( plsc->level > 0 )
872 plP_state( PLSTATE_CMAP1 );
873 }
874
875 //--------------------------------------------------------------------------
889 //--------------------------------------------------------------------------
890
891 void
892 c_plscmap1_range( PLFLT min_color, PLFLT max_color )
893 {
894 if ( min_color >= max_color || max_color <= MIN_PLFLT_CMAP1 || min_color >= MAX_PLFLT_CMAP1 )
895 {
896 plwarn( "plscmap1_range called with completely invalid color range so min_color = MIN_PLFLT_CMAP1 and max_color = MAX_PLFLT_CMAP1 used instead." );
897 min_color = MIN_PLFLT_CMAP1;
898 max_color = MAX_PLFLT_CMAP1;
899 }
900 // At this stage, the following conditions have been met:
901 // min_color < max_color, max_color > MIN_PLFLT_CMAP1, and min_color < MAX_PLFLT_CMAP1.
902 if ( min_color < MIN_PLFLT_CMAP1 )
903 {
904 plwarn( "plscmap1_range called with min_color < MIN_PLFLT_CMAP1. min_color = MIN_PLFLT_CMAP1 < max_color is used instead." );
905 min_color = MIN_PLFLT_CMAP1;
906 }
907 if ( max_color > MAX_PLFLT_CMAP1 )
908 {
909 plwarn( "plscmap1_range called with max_color > MAX_PLFLT_CMAP1. max_color = MAX_PLFLT_CMAP1 > min_color is used instead" );
910 max_color = MAX_PLFLT_CMAP1;
911 }
912 plsc->cmap1_min = min_color;
913 plsc->cmap1_max = max_color;
914 }
915
916 //--------------------------------------------------------------------------
921 //--------------------------------------------------------------------------
922
923 void
924 c_plgcmap1_range( PLFLT *min_color, PLFLT *max_color )
925 {
926 *min_color = plsc->cmap1_min;
927 *max_color = plsc->cmap1_max;
928 }
929
930 //--------------------------------------------------------------------------
931 // plscmap0n()
932 //
940
941 void
942 c_plscmap0n( PLINT ncol0 )
943 {
944 int ncol, size, imin, imax;
945
946 // No change
947
948 if ( ncol0 > 0 && plsc->ncol0 == ncol0 )
949 return;
950
951 // Handle all possible startup conditions
952
953 if ( plsc->ncol0 <= 0 && ncol0 <= 0 )
954 ncol = PL_DEFAULT_NCOL0;
955 else if ( ncol0 <= 0 )
956 ncol = plsc->ncol0;
957 else
958 ncol = ncol0;
959
960 imax = ncol - 1;
961 size = ncol * (int) sizeof ( PLColor );
962
963 // Allocate the space
964
965 if ( plsc->cmap0 == NULL )
966 {
967 if ( ( plsc->cmap0 = (PLColor *) calloc( 1, (size_t) size ) ) == NULL )
968 {
969 plexit( "c_plscmap0n: Insufficient memory" );
970 }
971 imin = 0;
972 }
973 else
974 {
975 if ( ( plsc->cmap0 = (PLColor *) realloc( plsc->cmap0, (size_t) size ) ) == NULL )
976 {
977 plexit( "c_plscmap0n: Insufficient memory" );
978 }
979 imin = plsc->ncol0;
980 }
981
982 // Fill in default entries
983
984 plsc->ncol0 = ncol;
985 plcmap0_def( imin, imax );
986
987 if ( plsc->level > 0 )
988 plP_state( PLSTATE_CMAP0 );
989 }
990
991 //--------------------------------------------------------------------------
992 // color_set()
993 //
1002
1003 static void
1004 color_set( PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, PLCHAR_VECTOR name )
1005 {
1006 plsc->cmap0[i].r = r;
1007 plsc->cmap0[i].g = g;
1008 plsc->cmap0[i].b = b;
1009 plsc->cmap0[i].a = a;
1010 plsc->cmap0[i].name = name;
1011 }
1012
1013 #define color_def( i, r, g, b, a, n ) \
1014 if ( i >= imin && i <= imax ) color_set( i, r, g, b, a, n );
1015
1016 //--------------------------------------------------------------------------
1017 // plcmap0_def()
1018 //
1024
1025 static void
1026 plcmap0_def( int imin, int imax )
1027 {
1028 int i;
1029 unsigned int *r, *g, *b;
1030 double *a;
1031 int number_colors;
1032 if ( imin <= imax )
1033 {
1034 cmap0_palette_read( "", &number_colors, &r, &g, &b, &a );
1035 for ( i = imin; i <= MIN( ( number_colors - 1 ), imax ); i++ )
1036 color_def( i, (U_CHAR) r[i], (U_CHAR) g[i], (U_CHAR) b[i], a[i],
1037 "colors defined by default cmap0 palette file" );
1038 free( r );
1039 free( g );
1040 free( b );
1041 free( a );
1042 }
1043 else
1044 {
1045 number_colors = 0;
1046 }
1047
1048 // Initialize all colours undefined by the default colour palette file
1049 // to opaque red as a warning.
1050 for ( i = MAX( number_colors, imin ); i <= imax; i++ )
1051 color_def( i, MAX_PLINT_RGB, MIN_PLINT_RGB, MIN_PLINT_RGB, MAX_PLFLT_ALPHA,
1052 "opaque red colour to mark not defined by palette file" );
1053 }
1054
1055 //--------------------------------------------------------------------------
1056 // plscmap1n()
1057 //
1065
1066 void
1067 c_plscmap1n( PLINT ncol1 )
1068 {
1069 PLINT ncol;
1070 size_t size;
1071
1072 // No change
1073
1074 if ( ncol1 > 0 && plsc->ncol1 == ncol1 )
1075 return;
1076
1077 // Handle all possible startup conditions
1078
1079 if ( plsc->ncol1 <= 0 && ncol1 <= 0 )
1080 ncol = PL_DEFAULT_NCOL1;
1081 else if ( ncol1 <= 0 )
1082 ncol = plsc->ncol1;
1083 else
1084 ncol = ncol1;
1085
1086 size = (size_t) ncol * sizeof ( PLColor );
1087
1088 // Allocate the space
1089
1090 if ( plsc->ncol1 > 0 )
1091 {
1092 if ( ( plsc->cmap1 = (PLColor *) realloc( plsc->cmap1, size ) ) == NULL )
1093 {
1094 plexit( "c_plscmap1n: Insufficient memory" );
1095 }
1096 }
1097 else
1098 {
1099 if ( ( plsc->cmap1 = (PLColor *) calloc( (size_t) ncol, sizeof ( PLColor ) ) ) == NULL )
1100 {
1101 plexit( "c_plscmap1n: Insufficient memory" );
1102 }
1103 }
1104
1105 // Fill in default entries
1106
1107 plsc->ncol1 = ncol;
1108 if ( plsc->ncp1 == 0 )
1109 plcmap1_def();
1110 else
1111 plcmap1_calc();
1112 }
1113
1114 //--------------------------------------------------------------------------
1115 // plcmap1_def()
1116 //
1126
1127 static void
1128 plcmap1_def( void )
1129 {
1130 PLFLT i[6], h[6], l[6], s[6], midpt = 0., vertex = 0.;
1131
1132 // Positions of control points
1133
1134 i[0] = 0; // left boundary
1135 i[1] = 0.44; // a little left of center
1136 i[2] = 0.50; // at center
1137 i[3] = 0.50; // at center
1138 i[4] = 0.56; // a little right of center
1139 i[5] = 1; // right boundary
1140
1141 // For center control points, pick black or white, whichever is closer to bg
1142 // Be careful to pick just short of top or bottom else hue info is lost
1143
1144 if ( plsc->cmap0 != NULL )
1145 vertex = ( (PLFLT) plsc->cmap0[0].r +
1146 (PLFLT) plsc->cmap0[0].g +
1147 (PLFLT) plsc->cmap0[0].b ) / 3. / (PLFLT) MAX_PLINT_RGB;
1148
1149 if ( vertex < 0.5 )
1150 {
1151 vertex = 0.01;
1152 midpt = 0.10;
1153 }
1154 else
1155 {
1156 vertex = 0.99;
1157 midpt = 0.90;
1158 }
1159
1160 // Set hue
1161
1162 h[0] = 260; // low: blue-violet
1163 h[1] = 260; // only change as we go over vertex
1164 h[2] = 260; // only change as we go over vertex
1165 h[3] = 0; // high: red
1166 h[4] = 0; // high: red
1167 h[5] = 0; // keep fixed
1168
1169 // Set lightness
1170
1171 l[0] = 0.5; // low
1172 l[1] = midpt; // midpoint value
1173 l[2] = vertex; // bg
1174 l[3] = vertex; // bg
1175 l[4] = midpt; // midpoint value
1176 l[5] = 0.5; // high
1177
1178 // Set saturation -- keep at maximum
1179
1180 s[0] = 1;
1181 s[1] = 1;
1182 s[2] = 1;
1183 s[3] = 1;
1184 s[4] = 1;
1185 s[5] = 1;
1186
1187 c_plscmap1l( 0, 6, i, h, l, s, NULL );
1188
1189 if ( plsc->level > 0 )
1190 plP_state( PLSTATE_CMAP1 );
1191 }
1192
1193 //--------------------------------------------------------------------------
1194 // plscolor()
1195 //
1199 //--------------------------------------------------------------------------
1200
1201 void
1202 c_plscolor( PLINT color )
1203 {
1204 plsc->colorset = 1;
1205 plsc->color = color;
1206 }
1207
1208 //--------------------------------------------------------------------------
1209 // void value()
1210 //
1216 //--------------------------------------------------------------------------
1217
1218 static PLFLT
1219 value( double n1, double n2, double hue )
1220 {
1221 PLFLT val;
1222
1223 while ( hue >= 360. )
1224 hue -= 360.;
1225 while ( hue < 0. )
1226 hue += 360.;
1227
1228 if ( hue < 60. )
1229 val = n1 + ( n2 - n1 ) * hue / 60.;
1230 else if ( hue < 180. )
1231 val = n2;
1232 else if ( hue < 240. )
1233 val = n1 + ( n2 - n1 ) * ( 240. - hue ) / 60.;
1234 else
1235 val = n1;
1236
1237 return ( val );
1238 }
1239
1240 //--------------------------------------------------------------------------
1241 // void c_plhlsrgb()
1242 //
1259
1260 void
1261 c_plhlsrgb( PLFLT h, PLFLT l, PLFLT s, PLFLT *p_r, PLFLT *p_g, PLFLT *p_b )
1262 {
1263 PLFLT m1, m2;
1264
1265 if ( l <= .5 )
1266 m2 = l * ( s + 1. );
1267 else
1268 m2 = l + s - l * s;
1269
1270 m1 = 2 * l - m2;
1271
1272 *p_r = value( m1, m2, h + 120. );
1273 *p_g = value( m1, m2, h );
1274 *p_b = value( m1, m2, h - 120. );
1275 }
1276
1277 //--------------------------------------------------------------------------
1278 // void c_plrgbhls()
1279 //
1292
1293 void
1294 c_plrgbhls( PLFLT r, PLFLT g, PLFLT b, PLFLT *p_h, PLFLT *p_l, PLFLT *p_s )
1295 {
1296 PLFLT h, l, s, d, rc, gc, bc, rgb_min, rgb_max;
1297
1298 rgb_min = MIN( r, MIN( g, b ) );
1299 rgb_max = MAX( r, MAX( g, b ) );
1300
1301 l = ( rgb_min + rgb_max ) / 2.0;
1302
1303 if ( rgb_min == rgb_max )
1304 {
1305 s = 0;
1306 h = 0;
1307 }
1308 else
1309 {
1310 d = rgb_max - rgb_min;
1311 if ( l < 0.5 )
1312 s = 0.5 * d / l;
1313 else
1314 s = 0.5 * d / ( 1. - l );
1315
1316 rc = ( rgb_max - r ) / d;
1317 gc = ( rgb_max - g ) / d;
1318 bc = ( rgb_max - b ) / d;
1319
1320 if ( r == rgb_max )
1321 h = bc - gc;
1322 else if ( g == rgb_max )
1323 h = rc - bc + 2;
1324 else
1325 h = gc - rc - 2;
1326
1327 h = h * 60;
1328 if ( h < 0 )
1329 h = h + 360;
1330 else if ( h >= 360 )
1331 h = h - 360;
1332 }
1333 *p_h = h;
1334 *p_l = l;
1335 *p_s = s;
1336 }
1337
1338 //--------------------------------------------------------------------------
1339 // read_line()
1340 //
1350
1351 static char *
1352 read_line( char *buffer, int length, FILE *fp )
1353 {
1354 char *pchr;
1355
1356 // Read the string
1357 if ( fgets( buffer, length, fp ) == NULL )
1358 {
1359 return NULL;
1360 }
1361
1362 // Sanitize the string we read - it may contain EOL characters
1363 // Make sure file reading starts at the next line
1364 pchr = strchr( buffer, '\n' );
1365 if ( pchr != NULL )
1366 {
1367 *pchr = '\0';
1368 }
1369 else
1370 {
1371 if ( fscanf( fp, "%*[^\n]\n" ) == EOF && ferror( fp ) )
1372 {
1373 return NULL;
1374 }
1375 }
1376
1377
1378 pchr = strchr( buffer, '\r' );
1379 if ( pchr != NULL )
1380 {
1381 *pchr = '\0';
1382 }
1383
1384 // Remove trailing blanks
1385 pchr = buffer + strlen( buffer ) - 1;
1386 while ( pchr != buffer && *pchr == ' ' )
1387 {
1388 *pchr = '\0';
1389 pchr--;
1390 }
1391
1392 return buffer;
1393 }
1394
1395 //--------------------------------------------------------------------------
1396 // cmap0_palette_read()
1397 //
1407
1408 static void
1409 cmap0_palette_read( PLCHAR_VECTOR filename,
1410 int *number_colors, unsigned int **r, unsigned int **g, unsigned int **b, double **a )
1411 {
1412 int i, err = 0;
1413 char color_info[COLLEN];
1414 char msgbuf[MSGLEN];
1415 FILE *fp;
1416 char * save_locale = plsave_set_locale();
1417
1418 if ( strlen( filename ) == 0 )
1419 {
1420 fp = plLibOpen( PL_DEFAULT_CMAP0_FILE );
1421 if ( fp == NULL )
1422 {
1423 snprintf( msgbuf, MSGLEN, "Unable to open cmap0 file %s\n", PL_DEFAULT_CMAP0_FILE );
1424 plwarn( msgbuf );
1425 err = 1;
1426 }
1427 }
1428 else
1429 {
1430 fp = plLibOpen( filename );
1431 if ( fp == NULL )
1432 {
1433 snprintf( msgbuf, MSGLEN, "Unable to open cmap0 file %s\n", filename );
1434 plwarn( msgbuf );
1435 err = 1;
1436 }
1437 }
1438 if ( !err && ( fscanf( fp, "%d\n", number_colors ) != 1 || *number_colors < 1 ) )
1439 {
1440 fclose( fp );
1441 snprintf( msgbuf, MSGLEN, "Unrecognized cmap0 header\n" );
1442 plwarn( msgbuf );
1443 err = 1;
1444 }
1445
1446 if ( !err )
1447 {
1448 // Allocate arrays to hold r, g, b, and a data for calling routine.
1449 // The caller must free these after it is finished with them.
1450 if ( ( ( *r = (unsigned int *) malloc( (size_t) ( *number_colors ) * sizeof ( unsigned int ) ) ) == NULL ) ||
1451 ( ( *g = (unsigned int *) malloc( (size_t) ( *number_colors ) * sizeof ( unsigned int ) ) ) == NULL ) ||
1452 ( ( *b = (unsigned int *) malloc( (size_t) ( *number_colors ) * sizeof ( unsigned int ) ) ) == NULL ) ||
1453 ( ( *a = (double *) malloc( (size_t) ( *number_colors ) * sizeof ( double ) ) ) == NULL ) )
1454 {
1455 fclose( fp );
1456 plexit( "cmap0_palette_read: insufficient memory" );
1457 }
1458
1459 for ( i = 0; i < *number_colors; i++ )
1460 {
1461 if ( read_line( color_info, COLLEN, fp ) == NULL )
1462 {
1463 err = 1;
1464 break;
1465 }
1466
1467 // Get the color data
1468 if ( strlen( color_info ) == 7 )
1469 {
1470 if ( sscanf( color_info, "#%2x%2x%2x",
1471 (unsigned int *) ( *r + i ), (unsigned int *) ( *g + i ),
1472 (unsigned int *) ( *b + i ) ) != 3 )
1473 {
1474 err = 1;
1475 break;
1476 }
1477 *( *a + i ) = 1.0;
1478 }
1479 else if ( strlen( color_info ) > 9 )
1480 {
1481 if ( sscanf( color_info, "#%2x%2x%2x %lf",
1482 (unsigned int *) ( *r + i ), (unsigned int *) ( *g + i ),
1483 (unsigned int *) ( *b + i ), (double *) ( *a + i ) ) != 4 )
1484 {
1485 err = 1;
1486 break;
1487 }
1488 // fuzzy range check.
1489 if ( *( *a + i ) < -FUZZ_EPSILON || *( *a + i ) > ( 1. + FUZZ_EPSILON ) )
1490 {
1491 err = 1;
1492 break;
1493 }
1494 else if ( *( *a + i ) < 0. )
1495 {
1496 *( *a + i ) = 0.;
1497 }
1498 else if ( *( *a + i ) > 1. )
1499 {
1500 *( *a + i ) = 1.;
1501 }
1502 }
1503 else
1504 {
1505 err = 1;
1506 break;
1507 }
1508 }
1509 fclose( fp );
1510 if ( err )
1511 {
1512 snprintf( msgbuf, MSGLEN, "Unrecognized cmap0 format data line. Line is %s\n",
1513 color_info );
1514 plwarn( msgbuf );
1515 free( *r );
1516 free( *g );
1517 free( *b );
1518 free( *a );
1519 }
1520 }
1521 // Fall back to opaque red on opaque white as visual warning of any
1522 // error above.
1523 if ( err )
1524 {
1525 *number_colors = 16;
1526 if ( ( ( *r = (unsigned int *) malloc( (size_t) ( *number_colors ) * sizeof ( int ) ) ) == NULL ) ||
1527 ( ( *g = (unsigned int *) malloc( (size_t) ( *number_colors ) * sizeof ( unsigned int ) ) ) == NULL ) ||
1528 ( ( *b = (unsigned int *) malloc( (size_t) ( *number_colors ) * sizeof ( unsigned int ) ) ) == NULL ) ||
1529 ( ( *a = (double *) malloc( (size_t) ( *number_colors ) * sizeof ( double ) ) ) == NULL ) )
1530 {
1531 plexit( "cmap0_palette_read: insufficient memory" );
1532 }
1533 **r = MAX_PLINT_RGB;
1534 **g = MAX_PLINT_RGB;
1535 **b = MAX_PLINT_RGB;
1536 **a = MAX_PLFLT_ALPHA;
1537 for ( i = 1; i < *number_colors; i++ )
1538 {
1539 *( *r + i ) = MAX_PLINT_RGB;
1540 *( *g + i ) = MIN_PLINT_RGB;
1541 *( *b + i ) = MIN_PLINT_RGB;
1542 *( *a + i ) = MAX_PLFLT_ALPHA;
1543 }
1544 }
1545
1546 plrestore_locale( save_locale );
1547 }
1548
1549 //--------------------------------------------------------------------------
1550 // void c_plspal0(filename)
1551 //
1556
1557 void
1558 c_plspal0( PLCHAR_VECTOR filename )
1559 {
1560 int i;
1561 unsigned int *r, *g, *b;
1562 double *a;
1563 int number_colors;
1564 cmap0_palette_read( filename, &number_colors, &r, &g, &b, &a );
1565 // Allocate default number of cmap0 colours if cmap0 allocation not
1566 // done already.
1567 plscmap0n( 0 );
1568 // Allocate sufficient cmap0 colours to contain present data.
1569 if ( number_colors > plsc->ncol0 )
1570 {
1571 plscmap0n( number_colors );
1572 }
1573 for ( i = 0; i < number_colors; i++ )
1574 {
1575 c_plscol0a( i, (PLINT) r[i], (PLINT) g[i], (PLINT) b[i], a[i] );
1576 }
1577 free( r );
1578 free( g );
1579 free( b );
1580 free( a );
1581 }
1582
1592 #define fuzzy_range_check( value, min, max, fuzz, err_number ) \
1593 if ( value < ( min - fuzz ) || value > ( max + fuzz ) ) { \
1594 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format data line. Error number is %d. Line is %s\n", err_number, color_info ); \
1595 plwarn( msgbuf ); \
1596 err = 1; \
1597 break; \
1598 } else if ( value < min ) { \
1599 value = min; \
1600 } else if ( value > max ) { \
1601 value = max; \
1602 }
1603
1604 //--------------------------------------------------------------------------
1605 // void c_plspal1(filename)
1606 //
1612
1613 void
1614 c_plspal1( PLCHAR_VECTOR filename, PLBOOL interpolate )
1615 {
1616 int i;
1617 int number_colors;
1618 int format_version, err;
1619 PLBOOL rgb;
1620 char color_info[PALLEN];
1621 unsigned int r_i, g_i, b_i;
1622 int pos_i, alt_hue_path_i;
1623 double r_d, g_d, b_d, a_d, pos_d;
1624 PLFLT *r, *g, *b, *a, *pos;
1625 PLINT *ri, *gi, *bi;
1626 PLBOOL *alt_hue_path;
1627 FILE *fp;
1628 char msgbuf[MSGLEN];
1629 char * save_locale = plsave_set_locale();
1630
1631 rgb = TRUE;
1632 err = 0;
1633 format_version = 0;
1634 if ( strlen( filename ) == 0 )
1635 {
1636 fp = plLibOpen( PL_DEFAULT_CMAP1_FILE );
1637 if ( fp == NULL )
1638 {
1639 snprintf( msgbuf, MSGLEN, "Unable to open cmap1 .pal file %s\n", PL_DEFAULT_CMAP1_FILE );
1640 plwarn( msgbuf );
1641 goto finish;
1642 }
1643 }
1644 else
1645 {
1646 fp = plLibOpen( filename );
1647 if ( fp == NULL )
1648 {
1649 snprintf( msgbuf, MSGLEN, "Unable to open cmap1 .pal file %s\n", filename );
1650 plwarn( msgbuf );
1651 goto finish;
1652 }
1653 }
1654 // Check for new file format
1655 if ( read_line( color_info, PALLEN, fp ) == NULL )
1656 {
1657 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
1658 plwarn( msgbuf );
1659 fclose( fp );
1660 goto finish;
1661 }
1662 if ( strncmp( color_info, "v2 ", 2 ) == 0 )
1663 {
1664 format_version = 1;
1665 if ( strncmp( &color_info[3], "hls", 3 ) == 0 )
1666 rgb = FALSE;
1667 else if ( strncmp( &color_info[3], "rgb", 3 ) == 0 )
1668 rgb = TRUE;
1669 else
1670 {
1671 snprintf( msgbuf, MSGLEN, "Invalid color space %s - assuming RGB\n", &color_info[3] );
1672 plwarn( msgbuf );
1673 rgb = TRUE;
1674 }
1675 if ( read_line( color_info, PALLEN, fp ) == NULL )
1676 {
1677 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
1678 plwarn( msgbuf );
1679 fclose( fp );
1680 goto finish;
1681 }
1682 }
1683
1684 if ( sscanf( color_info, "%d\n", &number_colors ) != 1 || number_colors < 2 )
1685 {
1686 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format (wrong number of colors) %s\n", color_info );
1687 plwarn( msgbuf );
1688 fclose( fp );
1689 goto finish;
1690 }
1691
1692 r = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1693 g = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1694 b = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1695 ri = (PLINT *) malloc( (size_t) number_colors * sizeof ( PLINT ) );
1696 gi = (PLINT *) malloc( (size_t) number_colors * sizeof ( PLINT ) );
1697 bi = (PLINT *) malloc( (size_t) number_colors * sizeof ( PLINT ) );
1698 a = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1699 pos = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1700 alt_hue_path = (PLBOOL *) malloc( (size_t) ( number_colors - 1 ) * sizeof ( PLBOOL ) );
1701
1702 if ( format_version == 0 )
1703 {
1704 int return_sscanf = -1, return_sscanf_old = 0;
1705 // Old tk file format
1706 for ( i = 0; i < number_colors; i++ )
1707 {
1708 if ( read_line( color_info, PALLEN, fp ) == NULL )
1709 {
1710 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
1711 plwarn( msgbuf );
1712 fclose( fp );
1713 goto finish;
1714 }
1715 // Ensure string is null terminated if > 160 characters
1716 color_info[PALLEN - 1] = '\0';
1717 return_sscanf = sscanf( color_info, "#%2x%2x%2x %d %d", &r_i, &g_i, &b_i, &pos_i, &alt_hue_path_i );
1718 if ( return_sscanf < 4 || ( return_sscanf_old != 0 && return_sscanf != return_sscanf_old ) )
1719 {
1720 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format (wrong number of items for version 1 of format) %s\n", color_info );
1721 plwarn( msgbuf );
1722 err = 1;
1723 break;
1724 }
1725 return_sscanf_old = return_sscanf;
1726 // For old format, input colours range from 0 to 255 and
1727 // need to be renormalized to the range from 0. to 1..
1728 r[i] = (PLFLT) r_i / 255.;
1729 g[i] = (PLFLT) g_i / 255.;
1730 b[i] = (PLFLT) b_i / 255.;
1731 a[i] = 1.0;
1732 pos[i] = 0.01 * (PLFLT) pos_i;
1733 fuzzy_range_check( r[i], 0., 1., FUZZ_EPSILON, 1 );
1734 fuzzy_range_check( g[i], 0., 1., FUZZ_EPSILON, 2 );
1735 fuzzy_range_check( b[i], 0., 1., FUZZ_EPSILON, 3 );
1736 fuzzy_range_check( pos[i], 0., 1., FUZZ_EPSILON, 4 );
1737 if ( ( return_sscanf == 5 ) && ( i != number_colors - 1 ) )
1738 {
1739 // Next to oldest tk format with alt_hue_path specified.
1740 alt_hue_path[i] = (PLBOOL) alt_hue_path_i;
1741 }
1742 }
1743 if ( return_sscanf == 4 )
1744 {
1745 // Oldest tk format. No alt_hue_path specified.
1746 free( alt_hue_path );
1747 alt_hue_path = NULL;
1748 }
1749 }
1750 else
1751 {
1752 // New floating point file version with support for alpha and alt_hue_path values
1753 for ( i = 0; i < number_colors; i++ )
1754 {
1755 if ( read_line( color_info, PALLEN, fp ) == NULL )
1756 {
1757 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
1758 plwarn( msgbuf );
1759 fclose( fp );
1760 goto finish;
1761 }
1762 if ( sscanf( color_info, "%lf %lf %lf %lf %lf %d", &pos_d, &r_d, &g_d, &b_d, &a_d, &alt_hue_path_i ) != 6 )
1763 {
1764 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format (wrong number of items for version 2 of format) %s\n", color_info );
1765 plwarn( msgbuf );
1766 err = 1;
1767 break;
1768 }
1769
1770 r[i] = (PLFLT) r_d;
1771 g[i] = (PLFLT) g_d;
1772 b[i] = (PLFLT) b_d;
1773 a[i] = (PLFLT) a_d;
1774 pos[i] = (PLFLT) pos_d;
1775 // Check that all rgba and pos data within range from 0. to
1776 // 1. except for the hls colour space case where the first
1777 // coordinate is checked within range from 0. to 360.
1778 if ( rgb )
1779 {
1780 fuzzy_range_check( r[i], 0., 1., FUZZ_EPSILON, 5 );
1781 }
1782 else
1783 {
1784 fuzzy_range_check( r[i], 0., 360., ( 360. * FUZZ_EPSILON ), 6 );
1785 }
1786 fuzzy_range_check( g[i], 0., 1., FUZZ_EPSILON, 7 );
1787 fuzzy_range_check( b[i], 0., 1., FUZZ_EPSILON, 8 );
1788 fuzzy_range_check( a[i], 0., 1., FUZZ_EPSILON, 9 );
1789 fuzzy_range_check( pos[i], 0., 1., FUZZ_EPSILON, 10 );
1790
1791 if ( i != number_colors - 1 )
1792 alt_hue_path[i] = (PLBOOL) alt_hue_path_i;
1793 }
1794 }
1795 fclose( fp );
1796
1797 if ( !err )
1798 {
1799 if ( interpolate )
1800 {
1801 c_plscmap1la( rgb, number_colors, pos, r, g, b, a, alt_hue_path );
1802 }
1803 else
1804 {
1805 for ( i = 0; i < number_colors; i++ )
1806 {
1807 ri[i] = (PLINT) ( r[i] * MAX_PLINT_RGB );
1808 gi[i] = (PLINT) ( g[i] * MAX_PLINT_RGB );
1809 bi[i] = (PLINT) ( b[i] * MAX_PLINT_RGB );
1810 }
1811 c_plscmap1a( ri, gi, bi, a, number_colors );
1812 }
1813 }
1814 else
1815 {
1816 // Fall back to red scale as visual warning if some problem occurred
1817 // above.
1818 free( r );
1819 free( g );
1820 free( b );
1821 free( pos );
1822 number_colors = 2;
1823 r = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1824 g = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1825 b = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1826 pos = (PLFLT *) malloc( (size_t) number_colors * sizeof ( PLFLT ) );
1827 r[0] = 0.;
1828 r[1] = 1.;
1829 g[0] = 0.;
1830 g[1] = 0.;
1831 b[0] = 0.;
1832 b[1] = 0.;
1833 pos[0] = 0.;
1834 pos[1] = 1.;
1835 c_plscmap1l( TRUE, number_colors, pos, r, g, b, NULL );
1836 }
1837
1838 free( r );
1839 free( g );
1840 free( b );
1841 free( ri );
1842 free( gi );
1843 free( bi );
1844 free( a );
1845 free( pos );
1846 free( alt_hue_path );
1847
1848 finish: plrestore_locale( save_locale );
1849 }
1850
1851 //--------------------------------------------------------------------------
1852 // A grab-bag of various control routines.
1853 //--------------------------------------------------------------------------
1854
1855 //--------------------------------------------------------------------------
1856 // void plwarn()
1857 //
1861
1862 void
1863 plwarn( PLCHAR_VECTOR errormsg )
1864 {
1865 int was_gfx = 0;
1866
1867 if ( plsc->graphx == 1 )
1868 {
1869 was_gfx = 1;
1870 pltext();
1871 }
1872
1873 fprintf( stderr, "\n*** PLPLOT WARNING ***\n" );
1874 if ( *errormsg != '\0' )
1875 fprintf( stderr, "%s\n", errormsg );
1876
1877 if ( was_gfx == 1 )
1878 plgra();
1879 }
1880
1881 //--------------------------------------------------------------------------
1882 // void plabort()
1883 //
1892
1893 void
1894 plabort( PLCHAR_VECTOR errormsg )
1895 {
1896 if ( abort_handler != NULL )
1897 ( *abort_handler )( errormsg );
1898
1899 if ( plsc->errcode != NULL )
1900 *( plsc->errcode ) = 1;
1901
1902 if ( plsc->errmsg != NULL )
1903 {
1904 sprintf( plsc->errmsg, "\n*** PLPLOT ERROR, ABORTING OPERATION ***\n" );
1905 if ( *errormsg != '\0' )
1906 sprintf( plsc->errmsg, "%s, aborting operation\n", errormsg );
1907 }
1908 else
1909 {
1910 int was_gfx = 0;
1911
1912 if ( plsc->graphx == 1 )
1913 {
1914 was_gfx = 1;
1915 pltext();
1916 }
1917
1918 fprintf( stderr, "\n*** PLPLOT ERROR, ABORTING OPERATION ***\n" );
1919 if ( *errormsg != '\0' )
1920 fprintf( stderr, "%s, aborting operation\n", errormsg );
1921
1922 if ( was_gfx == 1 )
1923 plgra();
1924 }
1925 }
1926
1927
1928 //--------------------------------------------------------------------------
1929 // void plsabort()
1930 //
1935 //--------------------------------------------------------------------------
1936
1937 void
1938 plsabort( void ( *handler )( PLCHAR_VECTOR ) )
1939 {
1940 abort_handler = handler;
1941 }
1942
1943 //--------------------------------------------------------------------------
1944 // void plexit()
1945 //
1955 //--------------------------------------------------------------------------
1956
1957 void
1958 plexit( PLCHAR_VECTOR errormsg )
1959 {
1960 int status = 1;
1961
1962 if ( exit_handler != NULL )
1963 status = ( *exit_handler )( errormsg );
1964
1965 plsc->nopause = 1;
1966 if ( *errormsg != '\0' )
1967 {
1968 fprintf( stderr, "\n*** PLPLOT ERROR, IMMEDIATE EXIT ***\n" );
1969 fprintf( stderr, "%s\n", errormsg );
1970 }
1971 plend();
1972
1973 fprintf( stderr, "Program aborted\n" );
1974 exit( status );
1975 }
1976
1977 //--------------------------------------------------------------------------
1978 // void plsexit()
1979 //
1984 //--------------------------------------------------------------------------
1985
1986 void
1987 plsexit( int ( *handler )( PLCHAR_VECTOR ) )
1988 {
1989 exit_handler = handler;
1990 }
1991
1992 //--------------------------------------------------------------------------
1993 // void plgra()
1994 //
2000 //--------------------------------------------------------------------------
2001
2002 void
2003 c_plgra( void )
2004 {
2005 if ( plsc->level > 0 )
2006 plP_esc( PLESC_GRAPH, NULL );
2007 }
2008
2009 //--------------------------------------------------------------------------
2010 // void plxormod()
2011 //
2016
2017 void
2018 c_plxormod( PLINT mode, PLINT *status ) // xor mode
2019 {
2020 static int ostate = 0;
2021
2022 if ( !plsc->dev_xor )
2023 {
2024 *status = 0;
2025 return;
2026 }
2027
2028 if ( plsc->level > 0 )
2029 {
2030 plP_esc( PLESC_XORMOD, &mode );
2031 if ( mode )
2032 {
2033 ostate = plsc->plbuf_write;
2034 plsc->plbuf_write = 0;
2035 }
2036 else
2037 plsc->plbuf_write = ostate;
2038 }
2039 *status = 1;
2040 }
2041
2042 //--------------------------------------------------------------------------
2047 void
2048 c_plsdrawmode( PLINT mode )
2049 {
2050 if ( !plsc->dev_modeset )
2051 {
2052 plwarn( "plsdrawmode: Mode setting is not supported by this device" );
2053 }
2054 else if ( plsc->level > 0 )
2055 {
2056 plP_esc( PLESC_MODESET, &mode );
2057 }
2058 else
2059 {
2060 plwarn( "plsdrawmode: Initialize PLplot first" );
2061 }
2062 return;
2063 }
2064
2065 //--------------------------------------------------------------------------
2070 PLINT
2071 c_plgdrawmode( void )
2072 {
2073 PLINT mode;
2074
2075 if ( !plsc->dev_modeset )
2076 {
2077 plwarn( "plgdrawmode: Mode getting is not supported by this device" );
2078 mode = PL_DRAWMODE_UNKNOWN;
2079 }
2080 else if ( plsc->level > 0 )
2081 {
2082 plP_esc( PLESC_MODEGET, &mode );
2083 }
2084 else
2085 {
2086 plwarn( "plsdrawmode: Initialize PLplot first" );
2087 mode = PL_DRAWMODE_UNKNOWN;
2088 }
2089
2090 return ( mode );
2091 }
2092
2093 //--------------------------------------------------------------------------
2094 // void pltext()
2095 //
2097 //--------------------------------------------------------------------------
2098
2099 void
2100 c_pltext( void )
2101 {
2102 if ( plsc->level > 0 )
2103 plP_esc( PLESC_TEXT, NULL );
2104 }
2105
2106 //--------------------------------------------------------------------------
2107 // void pl_cmd()
2108 //
2115 //--------------------------------------------------------------------------
2116
2117 void
2118 pl_cmd( PLINT op, void *ptr )
2119 {
2120 if ( plsc->level > 0 )
2121 plP_esc( op, ptr );
2122 }
2123
2124 //--------------------------------------------------------------------------
2125 // char *plFindCommand
2126 //
2143 //--------------------------------------------------------------------------
2144
2145 char *
2146 plFindCommand( PLCHAR_VECTOR fn )
2147 {
2148 char *fs = NULL, *dn;
2149
2150 //*** see if in build tree **
2151 if ( plInBuildTree() == 1 )
2152 {
2153 plGetName( BUILD_DIR, "bindings/tk", fn, &fs );
2154 if ( !plFindName( fs ) )
2155 return fs;
2156 else
2157 {
2158 plGetName( SOURCE_DIR, "scripts", fn, &fs );
2159 if ( !plFindName( fs ) )
2160 return fs;
2161 }
2162 }
2163
2164 // PLPLOT_BIN_ENV = $(PLPLOT_BIN)
2165
2166 #if defined ( PLPLOT_BIN_ENV )
2167 if ( ( dn = getenv( PLPLOT_BIN_ENV ) ) != NULL )
2168 {
2169 plGetName( dn, "", fn, &fs );
2170 if ( !plFindName( fs ) )
2171 return fs;
2172 fprintf( stderr, PLPLOT_BIN_ENV "=\"%s\"\n", dn ); // what IS set?
2173 }
2174 #endif // PLPLOT_BIN_ENV
2175
2176 // Current directory
2177
2178 plGetName( ".", "", fn, &fs );
2179 if ( !plFindName( fs ) )
2180 return fs;
2181
2182 // PLPLOT_HOME_ENV/bin = $(PLPLOT_HOME)/bin
2183
2184 #if defined ( PLPLOT_HOME_ENV )
2185 if ( ( dn = getenv( PLPLOT_HOME_ENV ) ) != NULL )
2186 {
2187 plGetName( dn, "bin", fn, &fs );
2188 if ( !plFindName( fs ) )
2189 return fs;
2190 fprintf( stderr, PLPLOT_HOME_ENV "=\"%s\"\n", dn ); // what IS set?
2191 }
2192 #endif // PLPLOT_HOME_ENV
2193
2194 // BIN_DIR
2195
2196 #if defined ( BIN_DIR )
2197 plGetName( BIN_DIR, "", fn, &fs );
2198 if ( !plFindName( fs ) )
2199 return fs;
2200 #endif
2201
2202 // Crapped out
2203
2204 free_mem( fs );
2205 fprintf( stderr, "plFindCommand: cannot locate command: %s\n", fn );
2206 #if defined ( BIN_DIR )
2207 fprintf( stderr, "bin dir=\"" BIN_DIR "\"\n" ); // what WAS set?
2208 #endif // BIN_DIR
2209 return NULL;
2210 }
2211
2212 //--------------------------------------------------------------------------
2213 // FILE *plLibOpen(fn)
2214 //
2226 //--------------------------------------------------------------------------
2227
2228 FILE *
2229 plLibOpen( PLCHAR_VECTOR fn )
2230 {
2231 FILE *ret = NULL;
2232
2233 PDFstrm *pdfs = plLibOpenPdfstrm( fn );
2234 if ( pdfs == NULL )
2235 {
2236 return NULL;
2237 }
2238 if ( pdfs->file != NULL )
2239 {
2240 ret = pdfs->file;
2241 pdfs->file = NULL;
2242 }
2243 pdf_close( pdfs );
2244 return ret;
2245 }
2246
2247 //--------------------------------------------------------------------------
2248 // FILE *plLibOpenPdfstrm(fn)
2249 //
2261 //--------------------------------------------------------------------------
2262 PDFstrm *
2263 plLibOpenPdfstrm( PLCHAR_VECTOR fn )
2264 {
2265 PDFstrm *file;
2266 char *fs = NULL, *dn = NULL;
2267
2268 //*** search build tree ***
2269
2270 if ( plInBuildTree() == 1 )
2271 {
2272 plGetName( SOURCE_DIR, "data", fn, &fs );
2273
2274 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
2275 goto done;
2276 }
2277
2278 //*** search PLPLOT_LIB_ENV = $(PLPLOT_LIB) ***
2279
2280 #if defined ( PLPLOT_LIB_ENV )
2281 if ( ( dn = getenv( PLPLOT_LIB_ENV ) ) != NULL )
2282 {
2283 plGetName( dn, "", fn, &fs );
2284
2285 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
2286 goto done;
2287 fprintf( stderr, PLPLOT_LIB_ENV "=\"%s\"\n", dn ); // what IS set?
2288 }
2289 #endif // PLPLOT_LIB_ENV
2290
2291 //*** search current directory ***
2292
2293 if ( ( file = pdf_fopen( fn, "rb" ) ) != NULL )
2294 {
2295 pldebug( "plLibOpenPdfstr", "Found file %s in current directory.\n", fn );
2296 free_mem( fs );
2297 return ( file );
2298 }
2299
2300 //*** search PLPLOT_HOME_ENV/lib = $(PLPLOT_HOME)/lib ***
2301
2302 #if defined ( PLPLOT_HOME_ENV )
2303 if ( ( dn = getenv( PLPLOT_HOME_ENV ) ) != NULL )
2304 {
2305 plGetName( dn, "lib", fn, &fs );
2306
2307 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
2308 goto done;
2309 fprintf( stderr, PLPLOT_HOME_ENV "=\"%s\"\n", dn ); // what IS set?
2310 }
2311 #endif // PLPLOT_HOME_ENV/lib
2312
2313 //*** search installed location ***
2314
2315 #if defined ( DATA_DIR )
2316 plGetName( DATA_DIR, "", fn, &fs );
2317
2318 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
2319 goto done;
2320 #endif // DATA_DIR
2321
2322 //*** search hardwired location ***
2323
2324 #ifdef PLLIBDEV
2325 plGetName( PLLIBDEV, "", fn, &fs );
2326
2327 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
2328 goto done;
2329 #endif // PLLIBDEV
2330
2331 #ifdef macintosh
2332 file = plMacLibOpen( fn );
2333 if ( file != NULL )
2334 goto done;
2335 #endif // macintosh
2336
2337 if ( plplotLibDir != NULL )
2338 {
2339 plGetName( plplotLibDir, "", fn, &fs );
2340 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
2341 goto done;
2342 }
2343
2344 //*** not found, give up ***
2345 pldebug( "plLibOpenPdfstr", "File %s not found.\n", fn );
2346 free_mem( fs );
2347 return NULL;
2348
2349 done:
2350 pldebug( "plLibOpenPdfstr", "Found file %s\n", fs );
2351 free_mem( fs );
2352 return ( file );
2353 }
2354
2355 //--------------------------------------------------------------------------
2356 // PLINR plFindName
2357 //
2375 //--------------------------------------------------------------------------
2376
2377 #ifdef __unix
2378 PLINT
2379 plFindName( char *p )
2380 {
2381 ssize_t n;
2382 char buf[PLPLOT_MAX_PATH], *cp;
2383 struct stat sbuf;
2384
2385 pldebug( "plFindName", "Trying to find %s\n", p );
2386 while ( ( n = readlink( p, buf, PLPLOT_MAX_PATH ) ) > 0 )
2387 {
2388 pldebug( "plFindName", "Readlink read %d chars at: %s\n", n, p );
2389 if ( buf[0] == '/' )
2390 {
2391 // Link is an absolute path
2392
2393 strncpy( p, buf, (size_t) n );
2394 p[n] = '\0';
2395 pldebug( "plFindName", "Link is absolute: %s\n", p );
2396 }
2397 else
2398 {
2399 // Link is relative to its directory; make it absolute
2400
2401 cp = 1 + strrchr( p, '/' );
2402 strncpy( cp, buf, (size_t) n );
2403 cp[n] = '\0';
2404 pldebug( "plFindName",
2405 "Link is relative: %s\n\tTotal path:%s\n", cp, p );
2406 }
2407 }
2408
2409 // This macro not defined on the NEC SX-3
2410
2411 #ifdef SX
2412 #define S_ISREG( mode ) ( mode & S_IFREG )
2413 #endif
2414
2415 // SGI machines return ENXIO instead of EINVAL Dubois 11/92
2416
2417 if ( errno == EINVAL || errno == ENXIO )
2418 {
2419 pldebug( "plFindName", "%s may be the one...\n", p );
2420 if ( ( stat( p, &sbuf ) == 0 ) && S_ISREG( sbuf.st_mode ) )
2421 {
2422 pldebug( "plFindName", "%s is a regular file\n", p );
2423 return ( access( p, X_OK ) );
2424 }
2425 }
2426 pldebug( "plFindName", "%s found but is not executable\n", p );
2427 return ( errno ? errno : -1 );
2428 }
2429
2430 #else
2431 PLINT
2432 plFindName( char *p )
2433 {
2434 return 1;
2435 }
2436 #endif
2437
2438 //--------------------------------------------------------------------------
2439 // void plGetName()
2440 //
2450 //--------------------------------------------------------------------------
2451
2452 void
2453 plGetName( PLCHAR_VECTOR dir, PLCHAR_VECTOR subdir, PLCHAR_VECTOR filename, char **filespec )
2454 {
2455 size_t lfilespec;
2456
2457 // Malloc space for filespec
2458
2459 free_mem( *filespec );
2460 // Be slightly generous since 3 (two delimiters + NULL byte) should be
2461 // enough.
2462 lfilespec = strlen( dir ) + strlen( subdir ) + strlen( filename ) + 10;
2463 if ( ( *filespec = (char *) malloc( lfilespec ) ) == NULL )
2464 {
2465 plexit( "plGetName: Insufficient memory" );
2466 }
2467
2468 strcpy( *filespec, dir );
2469
2470 if ( *subdir != '\0' )
2471 {
2472 strcat_delim( *filespec );
2473 strcat( *filespec, subdir );
2474 }
2475 if ( *filename != '\0' )
2476 {
2477 strcat_delim( *filespec );
2478 strcat( *filespec, filename );
2479 }
2480 #ifdef _WIN32
2481 // According to http://msdn.microsoft.com/en-us/library/vstudio/tcxf1dw6.aspx
2482 // and also Wine tests, Microsoft does not support the c99 standard %zu
2483 // format. Instead, %lu is recommended for size_t.
2484 pldebug( "plGetName", "Maximum length of full pathname of file to be found is %lu\n", lfilespec - 1 );
2485 #else
2486 pldebug( "plGetName", "Maximum length of full pathname of file to be found is %zu\n", lfilespec - 1 );
2487 #endif
2488 pldebug( "plGetName", "Full pathname of file to be found is %s\n", *filespec );
2489 }
2490
2491 //--------------------------------------------------------------------------
2492 // void strcat_delim()
2493 //
2498 //--------------------------------------------------------------------------
2499
2500 static void
2501 strcat_delim( char *dirspec )
2502 {
2503 size_t ldirspec = strlen( dirspec );
2504 #if defined ( MSDOS ) || defined ( _WIN32 )
2505 if ( dirspec[ldirspec - 1] != '\\' )
2506 strcat( dirspec, "\\" );
2507 #elif defined ( macintosh )
2508 if ( dirspec[ldirspec - 1] != ':' )
2509 strcat( dirspec, ":" );
2510 #else // unix is the default
2511 if ( dirspec[ldirspec - 1] != '/' )
2512 strcat( dirspec, "/" );
2513 #endif
2514 }
2515
2516 //--------------------------------------------------------------------------
2517 // plcol_interp()
2518 //
2527 //--------------------------------------------------------------------------
2528
2529 void
2530 plcol_interp( PLStream *pls, PLColor *newcolor, int i, int ncol )
2531 {
2532 PLFLT x, delta;
2533 int il, ir;
2534
2535 x = (double) ( i * ( pls->ncol1 - 1 ) ) / (double) ( ncol - 1 );
2536 il = (int) x;
2537 ir = il + 1;
2538 delta = x - il;
2539
2540 if ( ir > pls->ncol1 || il < 0 )
2541 fprintf( stderr, "Invalid color\n" );
2542
2543 else if ( ir == pls->ncol1 || ( delta == 0. ) )
2544 {
2545 newcolor->r = pls->cmap1[il].r;
2546 newcolor->g = pls->cmap1[il].g;
2547 newcolor->b = pls->cmap1[il].b;
2548 newcolor->a = pls->cmap1[il].a;
2549 }
2550 else
2551 {
2552 newcolor->r = (unsigned char) ( ( 1. - delta ) * pls->cmap1[il].r + delta * pls->cmap1[ir].r );
2553 newcolor->g = (unsigned char) ( ( 1. - delta ) * pls->cmap1[il].g + delta * pls->cmap1[ir].g );
2554 newcolor->b = (unsigned char) ( ( 1. - delta ) * pls->cmap1[il].b + delta * pls->cmap1[ir].b );
2555 newcolor->a = ( 1. - delta ) * pls->cmap1[il].a + delta * pls->cmap1[ir].a;
2556 }
2557 }
2558
2559 //--------------------------------------------------------------------------
2560 // plOpenFile()
2561 //
2567 //--------------------------------------------------------------------------
2568
2569 #define MAX_NUM_TRIES 10
2570 void
2571 plOpenFile( PLStream *pls )
2572 {
2573 int i = 0, count = 0;
2574 size_t len;
2575 char line[BUFFER_SIZE];
2576
2577 while ( pls->OutFile == NULL )
2578 {
2579 // Setting pls->FileName = NULL forces creation of a new family member
2580 // You should also free the memory associated with it if you do this
2581
2582 if ( pls->family && pls->BaseName != NULL )
2583 plP_getmember( pls );
2584
2585 // Prompt if filename still not known
2586
2587 if ( pls->FileName == NULL )
2588 {
2589 do
2590 {
2591 fprintf( stdout, "Enter graphics output file name: " );
2592 plio_fgets( line, sizeof ( line ), stdin );
2593 len = strlen( line );
2594 if ( len )
2595 len--;
2596 line[len] = '\0'; // strip new-line
2597 count++; // count zero entries
2598 } while ( !len && count < MAX_NUM_TRIES );
2599 plP_sfnam( pls, line );
2600 }
2601
2602 // If name is "-", send to stdout
2603
2604 if ( !strcmp( pls->FileName, "-" ) )
2605 {
2606 pls->OutFile = stdout;
2607 pls->output_type = 1;
2608 break;
2609 }
2610
2611 // Need this here again, for prompted family initialization
2612
2613 if ( pls->family && pls->BaseName != NULL )
2614 plP_getmember( pls );
2615
2616 if ( i++ > 10 )
2617 plexit( "Too many tries." );
2618
2619 if ( ( pls->OutFile = fopen( pls->FileName, "wb+" ) ) == NULL )
2620 fprintf( stderr, "Can't open %s.\n", pls->FileName );
2621 else
2622 pldebug( "plOpenFile", "Opened %s\n", pls->FileName );
2623 }
2624 }
2625
2626 //--------------------------------------------------------------------------
2627 // plCloseFile()
2628 //
2632 //--------------------------------------------------------------------------
2633
2634 void
2635 plCloseFile( PLStream *pls )
2636 {
2637 if ( pls->OutFile != NULL )
2638 {
2639 // Don't close if the output file was stdout
2640 if ( pls->FileName && strcmp( pls->FileName, "-" ) == 0 )
2641 return;
2642
2643 fclose( pls->OutFile );
2644 pls->OutFile = NULL;
2645 }
2646 }
2647
2648 //--------------------------------------------------------------------------
2649 // plP_getmember()
2650 //
2654 //--------------------------------------------------------------------------
2655
2656 void
2657 plP_getmember( PLStream *pls )
2658 {
2659 char tmp[BUFFER_SIZE];
2660 char prefix[BUFFER_SIZE];
2661 char * suffix;
2662 char num[BUFFER_SIZE];
2663 size_t maxlen;
2664
2665 maxlen = strlen( pls->BaseName ) + 10;
2666 if ( pls->FileName == NULL )
2667 {
2668 if ( ( pls->FileName = (char *) malloc( maxlen ) ) == NULL )
2669 {
2670 plexit( "plP_getmember: Insufficient memory" );
2671 }
2672 }
2673
2674 suffix = strstr( pls->BaseName, "%n" );
2675
2676 snprintf( tmp, BUFFER_SIZE, "%%0%1ii", (int) pls->fflen );
2677 snprintf( num, BUFFER_SIZE, tmp, pls->member );
2678
2679 if ( suffix == NULL )
2680 snprintf( pls->FileName, maxlen, "%s.%s", pls->BaseName, num );
2681 else
2682 {
2683 strncpy( prefix, pls->BaseName, BUFFER_SIZE - 1 );
2684 prefix [( suffix - pls->BaseName < BUFFER_SIZE ) ? ( suffix - pls->BaseName ) : BUFFER_SIZE - 1] = '\0';
2685 snprintf( pls->FileName, maxlen, "%s%s%s", prefix, num, suffix + 2 );
2686 }
2687 }
2688
2689 //--------------------------------------------------------------------------
2690 // plP_sfnam()
2691 //
2697 //--------------------------------------------------------------------------
2698
2699 void
2700 plP_sfnam( PLStream *pls, PLCHAR_VECTOR fnam )
2701 {
2702 char prefix[BUFFER_SIZE];
2703 char * suffix;
2704 size_t maxlen;
2705 pls->OutFile = NULL;
2706
2707 if ( pls->FileName != NULL )
2708 free( (void *) pls->FileName );
2709
2710 maxlen = 10 + strlen( fnam );
2711 if ( ( pls->FileName = (char *) malloc( maxlen ) ) == NULL )
2712 {
2713 plexit( "plP_sfnam: Insufficient memory" );
2714 }
2715
2716 suffix = strstr( fnam, "%n" );
2717
2718 if ( suffix == NULL )
2719 {
2720 strncpy( pls->FileName, fnam, maxlen - 1 );
2721 pls->FileName[maxlen - 1] = '\0';
2722 }
2723 else
2724 {
2725 strncpy( prefix, fnam, BUFFER_SIZE - 1 );
2726 prefix [( suffix - fnam ) < BUFFER_SIZE ? ( suffix - fnam ) : BUFFER_SIZE - 1] = '\0';
2727 snprintf( pls->FileName, maxlen, "%s%s", prefix, suffix + 2 );
2728 }
2729
2730 if ( pls->BaseName != NULL )
2731 free( (void *) pls->BaseName );
2732
2733 if ( ( pls->BaseName = (char *) malloc( maxlen ) ) == NULL )
2734 {
2735 plexit( "plP_sfnam: Insufficient memory" );
2736 }
2737
2738 strncpy( pls->BaseName, fnam, maxlen - 1 );
2739 pls->BaseName[maxlen - 1] = '\0';
2740 }
2741
2742 //--------------------------------------------------------------------------
2743 // plFamInit()
2744 //
2748 //--------------------------------------------------------------------------
2749
2750 void
2751 plFamInit( PLStream *pls )
2752 {
2753 if ( pls->family )
2754 {
2755 pls->bytecnt = 0;
2756 if ( !pls->member )
2757 pls->member = 1;
2758 if ( !pls->finc )
2759 pls->finc = 1;
2760 if ( !pls->fflen )
2761 pls->fflen = 1;
2762 if ( !pls->bytemax )
2763 pls->bytemax = PL_FILESIZE_KB * 1000;
2764 }
2765 }
2766
2767 //--------------------------------------------------------------------------
2768 // plGetFam()
2769 //
2777 //--------------------------------------------------------------------------
2778
2779 void
2780 plGetFam( PLStream *pls )
2781 {
2782 PLFLT xpmm_loc, ypmm_loc;
2783 if ( pls->family )
2784 {
2785 if ( pls->bytecnt > pls->bytemax || pls->famadv )
2786 {
2787 PLINT local_page_status = pls->page_status;
2788 plP_tidy();
2789 pls->member += pls->finc;
2790 pls->famadv = 0;
2791 plP_init();
2792 // Restore page status (normally AT_BOP) that was changed
2793 // to AT_EOP by plP_init.
2794 pls->page_status = local_page_status;
2795
2796 // Apply compensating factor to original xpmm and ypmm so that
2797 // character aspect ratio is preserved when overall aspect ratio
2798 // is changed.
2799 plP_gpixmm( &xpmm_loc, &ypmm_loc );
2800 plP_setpxl( xpmm_loc * plsc->caspfactor, ypmm_loc / plsc->caspfactor );
2801 return;
2802 }
2803 }
2804 }
2805
2806 //--------------------------------------------------------------------------
2807 // plRotPhy()
2808 //
2821 //--------------------------------------------------------------------------
2822
2823 void
2824 plRotPhy( PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax,
2825 PLINT *px, PLINT *py )
2826 {
2827 int x, y;
2828
2829 x = *px;
2830 y = *py;
2831
2832 switch ( orient % 4 )
2833 {
2834 case 1:
2835 *px = xmin + ( y - ymin );
2836 *py = ymin + ( xmax - x );
2837 break;
2838
2839 case 2:
2840 *px = xmin + ( xmax - x );
2841 *py = ymin + ( ymax - y );
2842 break;
2843
2844 case 3:
2845 *px = xmin + ( ymax - y );
2846 *py = ymin + ( x - xmin );
2847 break;
2848
2849 default:
2850 break; // do nothing
2851 }
2852 }
2853
2854 //--------------------------------------------------------------------------
2855 // plAllocDev()
2856 //
2863 //--------------------------------------------------------------------------
2864
2865 PLDev *
2866 plAllocDev( PLStream *pls )
2867 {
2868 if ( pls->dev != NULL )
2869 free( (void *) pls->dev );
2870
2871 pls->dev = calloc( 1, (size_t) sizeof ( PLDev ) );
2872 if ( pls->dev == NULL )
2873 plexit( "plAllocDev: cannot allocate memory\n" );
2874
2875 return (PLDev *) pls->dev;
2876 }
2877
2878 //--------------------------------------------------------------------------
2879 // plGinInit()
2880 //
2884 //--------------------------------------------------------------------------
2885
2886 void
2887 plGinInit( PLGraphicsIn *gin )
2888 {
2889 gin->type = 0;
2890 gin->state = 0;
2891 gin->keysym = 0;
2892 gin->button = 0;
2893 gin->string[0] = '\0';
2894 gin->pX = gin->pY = -1;
2895 gin->dX = gin->dY = 0.;
2896 gin->wX = gin->wY = 0.;
2897 }
2898
2899 //--------------------------------------------------------------------------
2900 // plGetInt()
2901 //
2907 //--------------------------------------------------------------------------
2908
2909 PLINT
2910 plGetInt( PLCHAR_VECTOR s )
2911 {
2912 int m;
2913 int i = 0;
2914 char line[BUFFER_SIZE];
2915
2916 while ( i++ < 10 )
2917 {
2918 fputs( s, stdout );
2919 plio_fgets( line, sizeof ( line ), stdin );
2920
2921 #ifdef MSDOS
2922 m = atoi( line );
2923 return ( m );
2924 #else
2925 if ( sscanf( line, "%d", &m ) == 1 )
2926 return ( m );
2927 fprintf( stdout, "No value or value out of range; please try again\n" );
2928 #endif
2929 }
2930 plexit( "Too many tries." );
2931 return ( 0 );
2932 }
2933
2934 //--------------------------------------------------------------------------
2935 // plGetFlt()
2936 //
2942 //--------------------------------------------------------------------------
2943
2944 PLFLT
2945 plGetFlt( PLCHAR_VECTOR s )
2946 {
2947 PLFLT m;
2948 double m1;
2949 int i = 0;
2950 char line[BUFFER_SIZE];
2951
2952 while ( i++ < 10 )
2953 {
2954 fputs( s, stdout );
2955 plio_fgets( line, sizeof ( line ), stdin );
2956
2957 #ifdef MSDOS
2958 m = atof( line );
2959 return ( m );
2960 #else
2961 if ( sscanf( line, "%lf", &m1 ) == 1 )
2962 {
2963 m = (PLFLT) m1;
2964 return ( m );
2965 }
2966 fprintf( stdout, "No value or value out of range; please try again\n" );
2967 #endif
2968 }
2969 plexit( "Too many tries." );
2970 return ( 0. );
2971 }
2972
2973 //--------------------------------------------------------------------------
2974 // plstrdup()
2975 //
2982 //--------------------------------------------------------------------------
2983
2984 char PLDLLIMPEXP *
2985 plstrdup( PLCHAR_VECTOR src )
2986 {
2987 char *dest = (char *) malloc( ( strlen( src ) + 1 ) * sizeof ( char ) );
2988 if ( dest != NULL )
2989 strcpy( dest, src );
2990 else
2991 plabort( "Out of memory" );
2992
2993 return dest;
2994 }
2995
2996 #ifndef PL_HAVE_SNPRINTF
2997 //--------------------------------------------------------------------------
2998 // plsnprintf()
2999 //
3010 //--------------------------------------------------------------------------
3011
3012 int
3013 plsnprintf( char *buffer, int n, PLCHAR_VECTOR format, ... )
3014 {
3015 int ret;
3016
3017 va_list args;
3018 va_start( args, format );
3019 ret = vsprintf( buffer, format, args );
3020 va_end( args );
3021
3022 // Check if overrun occured
3023 if ( ret > n - 1 )
3024 plabort( "plsnprintf: buffer overrun" );
3025
3026 return ret;
3027 }
3028
3029 //--------------------------------------------------------------------------
3030 // plsnscanf()
3031 //
3042 //--------------------------------------------------------------------------
3043
3044 int
3045 plsnscanf( PLCHAR_VECTOR buffer, int n, PLCHAR_VECTOR format, ... )
3046 {
3047 int ret;
3048
3049 va_list args;
3050 va_start( args, format );
3051 ret = vsscanf( buffer, format, args );
3052 va_end( args );
3053
3054 return ret;
3055 }
3056
3057 #endif // PL_HAVE_SNPRINTF
3058
3059 //--------------------------------------------------------------------------
3060 // plseed()
3061 //
3065 //--------------------------------------------------------------------------
3066
3067 void
3068 c_plseed( unsigned int seed )
3069 {
3070 init_genrand( seed );
3071 }
3072
3073 //--------------------------------------------------------------------------
3074 // plrandd()
3075 //
3078 //--------------------------------------------------------------------------
3079
3080 PLFLT
3081 c_plrandd( void )
3082 {
3083 return (PLFLT) ( genrand_real1() );
3084 }
3085
3086 //--------------------------------------------------------------------------
3087 // plsave_set_locale()
3088 //
3098 //--------------------------------------------------------------------------
3099
3100 char *
3101 plsave_set_locale( void )
3102 {
3103 char * setlocale_ptr;
3104 char * saved_lc_numeric_locale;
3105
3106 if ( !( saved_lc_numeric_locale = (char *) malloc( 100 * sizeof ( char ) ) ) )
3107 {
3108 plexit( "plsave_set_locale: out of memory" );
3109 }
3110
3111 //save original LC_NUMERIC locale for restore below.
3112 if ( !( setlocale_ptr = setlocale( LC_NUMERIC, NULL ) ) )
3113 {
3114 plexit( "plsave_set_locale: LC_NUMERIC locale could not be determined for NULL locale.\n" );
3115 }
3116 strncpy( saved_lc_numeric_locale, setlocale_ptr, 100 );
3117 saved_lc_numeric_locale[99] = '\0';
3118
3119 // Do not use pldebug since get overflowed stack (infinite recursion)
3120 // if device is interactive (i.e., pls->termin is set).
3121 // comment out fprintf (unless there is some emergency debugging to do)
3122 // because output is too voluminous.
3123 //
3124 // fprintf(stderr, "plsave_set_locale: saved LC_NUMERIC locale is \"%s\"\n", saved_lc_numeric_locale);
3125 //
3126
3127 if ( !( setlocale( LC_NUMERIC, "C" ) ) )
3128 {
3129 plexit( "plsave_set_locale: LC_NUMERIC locale could not be set to \"C\"" );
3130 }
3131 return saved_lc_numeric_locale;
3132 }
3133
3134 //--------------------------------------------------------------------------
3135 // plrestore_locale()
3136 //
3142 //--------------------------------------------------------------------------
3143
3144 void
3145 plrestore_locale( char *saved_lc_numeric_locale )
3146 {
3147 // Do not use pldebug since get overflowed stack (infinite recursion)
3148 // if device is interactive (i.e., pls->termin is set).
3149 // comment out fprintf (unless there is some emergency debugging to do)
3150 // because output is too voluminous.
3151 //
3152 // fprintf(stderr, "plrestore_locale: restored LC_NUMERIC locale is \"%s\"\n", saved_lc_numeric_locale);
3153 //
3154
3155 if ( !( setlocale( LC_NUMERIC, saved_lc_numeric_locale ) ) )
3156 {
3157 char msgbuf[1024];
3158 snprintf( msgbuf, 1024, "plrestore_locale: LC_NUMERIC could not be restored to the default \"%s\" locale.\n", saved_lc_numeric_locale );
3159 plexit( msgbuf );
3160 }
3161 free( saved_lc_numeric_locale );
3162 }
3163
3164 static void
3165 limit_rgba_range( PLCHAR_VECTOR message, PLINT_NC_SCALAR r, PLINT_NC_SCALAR g, PLINT_NC_SCALAR b, PLFLT_NC_SCALAR alpha )
3166 {
3167 if ( ( *r < MIN_PLINT_RGB || *r > MAX_PLINT_RGB ) ||
3168 ( *g < MIN_PLINT_RGB || *g > MAX_PLINT_RGB ) ||
3169 ( *b < MIN_PLINT_RGB || *b > MAX_PLINT_RGB ) ||
3170 ( alpha != NULL && ( isnan( *alpha ) || ( *alpha < MIN_PLFLT_ALPHA || *alpha > MAX_PLFLT_ALPHA ) ) ) )
3171 {
3172 plwarn( message );
3173 fprintf( stderr, "%s\n", "Further information relevant to this warning:" );
3174 if ( alpha != NULL )
3175 {
3176 fprintf( stderr, "Invalid RGBA color: %d, %d, %d, %e\n", (int) *r, (int) *g, (int) *b, (double) *alpha );
3177 *r = MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, *r ) );
3178 *g = MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, *g ) );
3179 *b = MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, *b ) );
3180 if ( isnan( *alpha ) )
3181 *alpha = MAX_PLFLT_ALPHA;
3182 *alpha = MAX( MIN_PLFLT_ALPHA, MIN( MAX_PLFLT_ALPHA, *alpha ) );
3183 fprintf( stderr, "Corrected RGBA color: %d, %d, %d, %e\n", (int) *r, (int) *g, (int) *b, (double) *alpha );
3184 }
3185 else
3186
3187 {
3188 fprintf( stderr, "Invalid RGB color: %d, %d, %d\n", (int) *r, (int) *g, (int) *b );
3189 *r = MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, *r ) );
3190 *g = MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, *g ) );
3191 *b = MAX( MIN_PLINT_RGB, MIN( MAX_PLINT_RGB, *b ) );
3192 fprintf( stderr, "Corrected RGB color: %d, %d, %d\n", (int) *r, (int) *g, (int) *b );
3193 }
3194 }
3195 }
plplotP.h
MAX_PLFLT_ALPHA
#define MAX_PLFLT_ALPHA
Definition: plplot.h:542
PLSTATE_CMAP0
#define PLSTATE_CMAP0
Definition: plplotP.h:366
name
static const char * name
Definition: tkMain.c:135
PLColor
Definition: plplot.h:546
plplot::maxlen
integer(kind=private_plint), parameter, private maxlen
Definition: plplot.f90:48
PL_DEFAULT_NCOL0
#define PL_DEFAULT_NCOL0
Definition: plplot.h:532
c_plscolbga
void c_plscolbga(PLINT r, PLINT g, PLINT b, PLFLT alpha)
Definition: plctrl.c:248
exit_handler
static int(* exit_handler)(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:96
PLESC_XORMOD
#define PLESC_XORMOD
Definition: plplot.h:286
PLFLT_NC_SCALAR
PLFLT * PLFLT_NC_SCALAR
Definition: plplot.h:233
plGetInt
PLINT plGetInt(PLCHAR_VECTOR s)
Definition: plctrl.c:2910
plexit
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
plGetName
void plGetName(PLCHAR_VECTOR dir, PLCHAR_VECTOR subdir, PLCHAR_VECTOR filename, char **filespec)
Definition: plctrl.c:2453
plP_esc
void plP_esc(PLINT op, void *ptr)
Definition: plcore.c:273
PL_DEFAULT_CMAP1_FILE
#define PL_DEFAULT_CMAP1_FILE
Definition: plplot_config.h:36
init_genrand
void init_genrand(unsigned long s)
Definition: mt19937ar.c:68
plFindName
PLINT plFindName(char *p)
Definition: plctrl.c:2432
PL_FILESIZE_KB
#define PL_FILESIZE_KB
Definition: plplotP.h:386
PLColor::b
unsigned char b
Definition: plplot.h:550
c_plscmap1_range
void c_plscmap1_range(PLFLT min_color, PLFLT max_color)
Definition: plctrl.c:892
PLGraphicsIn::dX
PLFLT dX
Definition: plplot.h:442
PLStream::OutFile
FILE * OutFile
Definition: plstrm.h:575
PDFstrm
Definition: pdf.h:49
plOpenFile
void plOpenFile(PLStream *pls)
Definition: plctrl.c:2571
color_set
static void color_set(PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, PLCHAR_VECTOR name)
Definition: plctrl.c:1004
FUZZ_EPSILON
#define FUZZ_EPSILON
Definition: plctrl.c:79
plCloseFile
void plCloseFile(PLStream *pls)
Definition: plctrl.c:2635
PLINT_NC_SCALAR
PLINT * PLINT_NC_SCALAR
Definition: plplot.h:229
plGetFam
void plGetFam(PLStream *pls)
Definition: plctrl.c:2780
c_plscmap1l
void c_plscmap1l(PLINT itype, PLINT npts, PLFLT_VECTOR intensity, PLFLT_VECTOR coord1, PLFLT_VECTOR coord2, PLFLT_VECTOR coord3, PLINT_VECTOR alt_hue_path)
Definition: plctrl.c:632
plP_getmember
void plP_getmember(PLStream *pls)
Definition: plctrl.c:2657
plGinInit
void plGinInit(PLGraphicsIn *gin)
Definition: plctrl.c:2887
SOURCE_DIR
#define SOURCE_DIR
Definition: plplot_config.h:273
pdf_fopen
PDFstrm * pdf_fopen(PLCHAR_VECTOR filename, PLCHAR_VECTOR mode)
Definition: pdfutils.c:74
PLCHAR_VECTOR
const char * PLCHAR_VECTOR
Definition: plplot.h:243
c_plcol0
void c_plcol0(PLINT icol0)
Definition: plctrl.c:154
plcol_interp
void plcol_interp(PLStream *pls, PLColor *newcolor, int i, int ncol)
Definition: plctrl.c:2530
isnan
#define isnan(x)
Definition: plplotP.h:262
read_line
static char * read_line(char *buffer, int length, FILE *fp)
Definition: plctrl.c:1352
plcmap1_calc
void plcmap1_calc(void)
Bin up cmap 1 space and assign colors to make inverse mapping easy.
Definition: plctrl.c:764
c_plgra
void c_plgra(void)
Definition: plctrl.c:2003
c_plscmap1n
void c_plscmap1n(PLINT ncol1)
Definition: plctrl.c:1067
PLESC_TEXT
#define PLESC_TEXT
Definition: plplot.h:277
c_plgcolbg
void c_plgcolbg(PLINT *r, PLINT *g, PLINT *b)
Definition: plctrl.c:263
MAX
#define MAX(a, b)
Definition: dsplint.c:28
plP_tidy
void plP_tidy(void)
Definition: plcore.c:231
plsave_set_locale
char * plsave_set_locale(void)
Definition: plctrl.c:3101
PLColor::a
PLFLT a
Definition: plplot.h:551
PL_MAX_CMAP1CP
#define PL_MAX_CMAP1CP
Definition: plstrm.h:521
plscmap1n
#define plscmap1n
Definition: plplot.h:798
PLSTATE_COLOR0
#define PLSTATE_COLOR0
Definition: plplotP.h:363
PLStream::page_status
PLINT page_status
Definition: plstrm.h:665
plabort
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1894
mt19937ar.h
PLSTATE_COLOR1
#define PLSTATE_COLOR1
Definition: plplotP.h:364
plP_gpixmm
void plP_gpixmm(PLFLT *p_x, PLFLT *p_y)
Definition: plcore.c:4229
color_def
#define color_def(i, r, g, b, a, n)
Definition: plctrl.c:1013
PLPLOT_MAX_PATH
#define PLPLOT_MAX_PATH
Definition: plplotP.h:446
c_plscmap1a
void c_plscmap1a(PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLFLT_VECTOR alpha, PLINT ncol1)
Definition: plctrl.c:551
c_plspal0
void c_plspal0(PLCHAR_VECTOR filename)
Definition: plctrl.c:1558
plsabort
void plsabort(void(*handler)(PLCHAR_VECTOR))
Definition: plctrl.c:1938
BUILD_DIR
#define BUILD_DIR
Definition: plplot_config.h:24
PLStream::cmap1
PLColor * cmap1
Definition: plstrm.h:545
plend
#define plend
Definition: plplot.h:709
c_plxormod
void c_plxormod(PLINT mode, PLINT *status)
Definition: plctrl.c:2018
c_plseed
void c_plseed(unsigned int seed)
Definition: plctrl.c:3068
c_plgcol0a
void c_plgcol0a(PLINT icol0, PLINT *r, PLINT *g, PLINT *b, PLFLT *alpha)
Definition: plctrl.c:396
plFamInit
void plFamInit(PLStream *pls)
Definition: plctrl.c:2751
plAllocDev
PLDev * plAllocDev(PLStream *pls)
Definition: plctrl.c:2866
color
static int color
Definition: ps.c:78
PLINT
int PLINT
Definition: plplot.h:181
MIN
#define MIN(a, b)
Definition: dsplint.c:29
PLBOOL
PLINT PLBOOL
Definition: plplot.h:204
c_plscmap0n
void c_plscmap0n(PLINT ncol0)
Definition: plctrl.c:942
plrestore_locale
void plrestore_locale(char *saved_lc_numeric_locale)
Definition: plctrl.c:3145
c_plspal1
void c_plspal1(PLCHAR_VECTOR filename, PLBOOL interpolate)
Definition: plctrl.c:1614
PLColor::g
unsigned char g
Definition: plplot.h:549
line
Definition: plsdef.c:27
PLStream::bytemax
PLINT bytemax
Definition: plstrm.h:570
PL_DEFAULT_CMAP0_FILE
#define PL_DEFAULT_CMAP0_FILE
Definition: plplot_config.h:33
plP_sfnam
void plP_sfnam(PLStream *pls, PLCHAR_VECTOR fnam)
Definition: plctrl.c:2700
plio_fgets
void plio_fgets(char *buf, int size, FILE *stream)
Definition: plstdio.c:142
snprintf
#define snprintf
Definition: plplotP.h:235
PLSTATE_CMAP1
#define PLSTATE_CMAP1
Definition: plplotP.h:367
c_plrandd
PLFLT c_plrandd(void)
Definition: plctrl.c:3081
PLStream::BaseName
char * BaseName
Definition: plstrm.h:576
c_plhlsrgb
void c_plhlsrgb(PLFLT h, PLFLT l, PLFLT s, PLFLT *p_r, PLFLT *p_g, PLFLT *p_b)
Definition: plctrl.c:1261
c_plscmap1
void c_plscmap1(PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLINT ncol1)
Definition: plctrl.c:513
PLESC_MODESET
#define PLESC_MODESET
Definition: plplot.h:306
PLGraphicsIn::type
int type
Definition: plplot.h:435
TRUE
#define TRUE
Definition: plplotP.h:176
PLESC_GRAPH
#define PLESC_GRAPH
Definition: plplot.h:278
PLStream::FileName
char * FileName
Definition: plstrm.h:576
PLDev
Definition: plstrm.h:40
c_plcol1
void c_plcol1(PLFLT col1)
Definition: plctrl.c:188
FALSE
#define FALSE
Definition: plplotP.h:177
plsnprintf
int plsnprintf(char *buffer, int n, PLCHAR_VECTOR format,...)
Definition: plctrl.c:3013
PLStream::fflen
PLINT fflen
Definition: plstrm.h:570
plFindCommand
char * plFindCommand(PLCHAR_VECTOR fn)
Definition: plctrl.c:2146
PL_DRAWMODE_UNKNOWN
#define PL_DRAWMODE_UNKNOWN
Definition: plplot.h:1318
COLLEN
#define COLLEN
Definition: plctrl.c:73
MIN_PLINT_RGB
#define MIN_PLINT_RGB
Definition: plplot.h:535
MAX_NUM_TRIES
#define MAX_NUM_TRIES
Definition: plctrl.c:2569
c_plrgbhls
void c_plrgbhls(PLFLT r, PLFLT g, PLFLT b, PLFLT *p_h, PLFLT *p_l, PLFLT *p_s)
Definition: plctrl.c:1294
plInBuildTree
int plInBuildTree()
Definition: plcore.c:2888
buffer
static PLINT * buffer
Definition: plfill.c:74
c_plscolbg
void c_plscolbg(PLINT r, PLINT g, PLINT b)
Definition: plctrl.c:229
plP_setpxl
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
Definition: plcore.c:4238
PLLIBDEV
#define PLLIBDEV
Definition: plctrl.c:136
pl_cmd
void pl_cmd(PLINT op, void *ptr)
Definition: plctrl.c:2118
MAX_PLFLT_CMAP1
#define MAX_PLFLT_CMAP1
Definition: plplot.h:539
pltext
#define pltext
Definition: plplot.h:855
PL_DEFAULT_NCOL1
#define PL_DEFAULT_NCOL1
Definition: plplot.h:533
PLINT_VECTOR
const PLINT * PLINT_VECTOR
Definition: plplot.h:241
plscol0a
#define plscol0a
Definition: plplot.h:801
plsexit
void plsexit(int(*handler)(PLCHAR_VECTOR))
Definition: plctrl.c:1987
c_plscmap0a
void c_plscmap0a(PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLFLT_VECTOR alpha, PLINT ncol0)
Definition: plctrl.c:472
PLGraphicsIn::keysym
unsigned int keysym
Definition: plplot.h:437
BIN_DIR
#define BIN_DIR
Definition: plplot_config.h:21
value
static PLFLT value(double n1, double n2, double hue)
Definition: plctrl.c:1219
buf
static char buf[200]
Definition: tclAPI.c:873
PLStream::famadv
PLINT famadv
Definition: plstrm.h:570
pls
static PLStream * pls[PL_NSTREAMS]
Definition: plcore.h:88
c_plscol0a
void c_plscol0a(PLINT icol0, PLINT r, PLINT g, PLINT b, PLFLT alpha)
Definition: plctrl.c:326
PLESC_MODEGET
#define PLESC_MODEGET
Definition: plplot.h:307
c_plgcolbga
void c_plgcolbga(PLINT *r, PLINT *g, PLINT *b, PLFLT *alpha)
Definition: plctrl.c:279
PLStream::family
PLINT family
Definition: plstrm.h:570
PLPLOT_HOME_ENV
#define PLPLOT_HOME_ENV
Definition: plplotP.h:443
limit_rgba_range
static void limit_rgba_range(PLCHAR_VECTOR message, PLINT_NC_SCALAR r, PLINT_NC_SCALAR g, PLINT_NC_SCALAR b, PLFLT_NC_SCALAR alpha)
Definition: plctrl.c:3165
plsnscanf
int plsnscanf(PLCHAR_VECTOR buffer, int n, PLCHAR_VECTOR format,...)
Definition: plctrl.c:3045
PLStream::member
PLINT member
Definition: plstrm.h:570
c_plscolor
void c_plscolor(PLINT color)
Definition: plctrl.c:1202
PDFstrm::file
FILE * file
Definition: pdf.h:51
PLStream
Definition: plstrm.h:523
PLGraphicsIn::wX
PLFLT wX
Definition: plplot.h:443
plstrdup
char PLDLLIMPEXP * plstrdup(PLCHAR_VECTOR src)
Definition: plctrl.c:2985
strcat_delim
static void strcat_delim(char *dirspec)
Definition: plctrl.c:2501
plcmap1_def
static void plcmap1_def(void)
Definition: plctrl.c:1128
plP_state
void plP_state(PLINT op)
Definition: plcore.c:256
BUFFER_SIZE
#define BUFFER_SIZE
Definition: plctrl.c:72
c_plgdrawmode
PLINT c_plgdrawmode(void)
Definition: plctrl.c:2071
fuzzy_range_check
#define fuzzy_range_check(value, min, max, fuzz, err_number)
Definition: plctrl.c:1592
PLGraphicsIn::pX
int pX
Definition: plplot.h:441
plcmap0_def
static void plcmap0_def(int imin, int imax)
Definition: plctrl.c:1026
PLFLT
float PLFLT
Definition: plplot.h:163
plscol0
#define plscol0
Definition: plplot.h:800
pdf_close
int pdf_close(PDFstrm *pdfs)
Definition: pdfutils.c:238
MSGLEN
#define MSGLEN
Definition: plctrl.c:75
plgcol0a
#define plgcol0a
Definition: plplot.h:725
MIN_PLFLT_ALPHA
#define MIN_PLFLT_ALPHA
Definition: plplot.h:541
free_mem
#define free_mem(a)
Definition: plplotP.h:182
c_plgcmap1_range
void c_plgcmap1_range(PLFLT *min_color, PLFLT *max_color)
Definition: plctrl.c:924
PLPLOT_BIN_ENV
#define PLPLOT_BIN_ENV
Definition: plplotP.h:440
plLibOpen
FILE * plLibOpen(PLCHAR_VECTOR fn)
Definition: plctrl.c:2229
plRotPhy
void plRotPhy(PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax, PLINT *px, PLINT *py)
Definition: plctrl.c:2824
c_pltext
void c_pltext(void)
Switches to text screen.
Definition: plctrl.c:2100
c_plscmap0
void c_plscmap0(PLINT_VECTOR r, PLINT_VECTOR g, PLINT_VECTOR b, PLINT ncol0)
Definition: plctrl.c:434
PLGraphicsIn::state
unsigned int state
Definition: plplot.h:436
PLColor::r
unsigned char r
Definition: plplot.h:548
PLPLOT_LIB_ENV
#define PLPLOT_LIB_ENV
Definition: plplotP.h:441
plwarn
void plwarn(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1863
access
int access(char *filename, int flag)
Definition: plfreetype.c:70
plscmap0n
#define plscmap0n
Definition: plplot.h:793
plP_init
void plP_init(void)
Definition: plcore.c:145
plgcol0
#define plgcol0
Definition: plplot.h:724
plGetFlt
PLFLT plGetFlt(PLCHAR_VECTOR s)
Definition: plctrl.c:2945
c_plscol0
void c_plscol0(PLINT icol0, PLINT r, PLINT g, PLINT b)
Definition: plctrl.c:296
PLGraphicsIn::button
unsigned int button
Definition: plplot.h:438
c_plsdrawmode
void c_plsdrawmode(PLINT mode)
Definition: plctrl.c:2048
PLDLLIMPEXP
#define PLDLLIMPEXP
Definition: pldll.h:49
PLGraphicsIn::dY
PLFLT dY
Definition: plplot.h:442
PALLEN
#define PALLEN
Definition: plctrl.c:74
abort_handler
static void(* abort_handler)(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:99
c_plgcol0
void c_plgcol0(PLINT icol0, PLINT *r, PLINT *g, PLINT *b)
Definition: plctrl.c:359
DATA_DIR
#define DATA_DIR
Definition: plplot_config.h:27
MIN_PLFLT_CMAP1
#define MIN_PLFLT_CMAP1
Definition: plplot.h:538
PLStream::ncol1
PLINT ncol1
Definition: plstrm.h:539
PLFLT_VECTOR
const PLFLT * PLFLT_VECTOR
Definition: plplot.h:244
plplotLibDir
char PLDLLIMPEXP * plplotLibDir
Definition: plctrl.c:82
PLGraphicsIn::pY
int pY
Definition: plplot.h:441
plLibOpenPdfstrm
PDFstrm * plLibOpenPdfstrm(PLCHAR_VECTOR fn)
Definition: plctrl.c:2263
PLGraphicsIn::wY
PLFLT wY
Definition: plplot.h:443
PLStream::finc
PLINT finc
Definition: plstrm.h:570
PLStream::dev
void * dev
Definition: plstrm.h:594
PLGraphicsIn::string
char string[PL_MAXKEY]
Definition: plplot.h:440
PLStream::bytecnt
PLINT bytecnt
Definition: plstrm.h:578
plgra
#define plgra
Definition: plplot.h:740
PLStream::output_type
int output_type
Definition: plstrm.h:577
U_CHAR
#define U_CHAR
Definition: pdf.h:26
c_plscmap1la
void c_plscmap1la(PLINT itype, PLINT npts, PLFLT_VECTOR intensity, PLFLT_VECTOR coord1, PLFLT_VECTOR coord2, PLFLT_VECTOR coord3, PLFLT_VECTOR alpha, PLINT_VECTOR alt_hue_path)
Definition: plctrl.c:703
MAX_PLINT_RGB
#define MAX_PLINT_RGB
Definition: plplot.h:536
genrand_real1
double genrand_real1(void)
Definition: mt19937ar.c:181
cmap0_palette_read
static void cmap0_palette_read(PLCHAR_VECTOR filename, int *number_colors, unsigned int **r, unsigned int **g, unsigned int **b, double **a)
Definition: plctrl.c:1409
PLGraphicsIn
Definition: plplot.h:433