00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define DEBUG
00036 #define NEED_PLDEBUG
00037 #include "plcore.h"
00038
00039 #ifdef ENABLE_DYNDRIVERS
00040 #ifndef LTDL_WIN32
00041 #include <ltdl.h>
00042 #else
00043 #include "ltdl_win32.h"
00044 #endif
00045 #endif
00046
00047 #if HAVE_DIRENT_H
00048
00049
00050
00051 # ifdef NEED_SYS_TYPE_H
00052 # include <sys/types.h>
00053 # endif
00054 # include <dirent.h>
00055 # define NAMLEN( dirent ) strlen( ( dirent )->d_name )
00056 #else
00057 # if defined ( _MSC_VER )
00058 # include "dirent_msvc.h"
00059 # else
00060 # define dirent direct
00061 # define NAMLEN( dirent ) ( dirent )->d_namlen
00062 # if HAVE_SYS_NDIR_H
00063 # include <sys/ndir.h>
00064 # endif
00065 # if HAVE_SYS_DIR_H
00066 # include <sys/dir.h>
00067 # endif
00068 # if HAVE_NDIR_H
00069 # include <ndir.h>
00070 # endif
00071 # endif
00072 #endif
00073
00074
00075
00076
00077
00078
00079
00080 #if defined ( _MSC_VER )
00081 # include <direct.h>
00082 # define getcwd _getcwd
00083 # define chdir _chdir
00084 #endif
00085
00086 #define BUFFER_SIZE 80
00087 #define BUFFER2_SIZE 300
00088 #define DRVSPEC_SIZE 400
00089
00090 #include <errno.h>
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 enum { AT_BOP, DRAWING, AT_EOP };
00122
00123
00124
00125
00126
00127
00128
00129
00130 const char plP_greek_mnemonic[] = "ABGDEZYHIKLMNCOPRSTUFXQWabgdezyhiklmncoprstufxqw";
00131
00132 void
00133 plP_init( void )
00134 {
00135 char * save_locale;
00136 plsc->page_status = AT_EOP;
00137 plsc->stream_closed = FALSE;
00138
00139 save_locale = plsave_set_locale();
00140 ( *plsc->dispatch_table->pl_init )( (struct PLStream_struct *) plsc );
00141 plrestore_locale( save_locale );
00142
00143 if ( plsc->plbuf_write )
00144 plbuf_init( plsc );
00145 }
00146
00147
00148
00149
00150
00151 void
00152 plP_eop( void )
00153 {
00154 int skip_driver_eop = 0;
00155
00156 if ( plsc->page_status == AT_EOP )
00157 return;
00158
00159 plsc->page_status = AT_EOP;
00160
00161 if ( plsc->plbuf_write )
00162 plbuf_eop( plsc );
00163
00164
00165
00166 if ( plsc->eop_handler != NULL )
00167 ( *plsc->eop_handler )( plsc->eop_data, &skip_driver_eop );
00168
00169 if ( !skip_driver_eop )
00170 {
00171 char *save_locale = plsave_set_locale();
00172 if ( !plsc->stream_closed )
00173 {
00174 ( *plsc->dispatch_table->pl_eop )( (struct PLStream_struct *) plsc );
00175 }
00176 plrestore_locale( save_locale );
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185 void
00186 plP_bop( void )
00187 {
00188 int skip_driver_bop = 0;
00189
00190 plP_subpInit();
00191 if ( plsc->page_status == AT_BOP )
00192 return;
00193
00194 plsc->page_status = AT_BOP;
00195 plsc->nplwin = 0;
00196
00197
00198
00199 if ( plsc->bop_handler != NULL )
00200 ( *plsc->bop_handler )( plsc->bop_data, &skip_driver_bop );
00201
00202 if ( !skip_driver_bop )
00203 {
00204 char *save_locale = plsave_set_locale();
00205 if ( !plsc->stream_closed )
00206 {
00207 ( *plsc->dispatch_table->pl_bop )( (struct PLStream_struct *) plsc );
00208 }
00209 plrestore_locale( save_locale );
00210 }
00211
00212 if ( plsc->plbuf_write )
00213 plbuf_bop( plsc );
00214 }
00215
00216
00217
00218 void
00219 plP_tidy( void )
00220 {
00221 char * save_locale;
00222 if ( plsc->tidy )
00223 {
00224 ( *plsc->tidy )( plsc->tidy_data );
00225 plsc->tidy = NULL;
00226 plsc->tidy_data = NULL;
00227 }
00228
00229 save_locale = plsave_set_locale();
00230 if ( !plsc->stream_closed )
00231 {
00232 ( *plsc->dispatch_table->pl_tidy )( (struct PLStream_struct *) plsc );
00233 }
00234 plrestore_locale( save_locale );
00235
00236 if ( plsc->plbuf_write )
00237 {
00238 plbuf_tidy( plsc );
00239 }
00240
00241 plsc->OutFile = NULL;
00242 }
00243
00244
00245
00246 void
00247 plP_state( PLINT op )
00248 {
00249 char * save_locale;
00250 if ( plsc->plbuf_write )
00251 plbuf_state( plsc, op );
00252
00253 save_locale = plsave_set_locale();
00254 if ( !plsc->stream_closed )
00255 {
00256 ( *plsc->dispatch_table->pl_state )( (struct PLStream_struct *) plsc, op );
00257 }
00258 plrestore_locale( save_locale );
00259 }
00260
00261
00262
00263 void
00264 plP_esc( PLINT op, void *ptr )
00265 {
00266 char * save_locale;
00267 PLINT clpxmi, clpxma, clpymi, clpyma;
00268 EscText* args;
00269
00270
00271 if ( plsc->plbuf_write )
00272 plbuf_esc( plsc, op, ptr );
00273
00274
00275 if ( ( op == PLESC_HAS_TEXT && plsc->dev_unicode ) ||
00276 ( op == PLESC_END_TEXT && plsc->alt_unicode ) )
00277 {
00278
00279 if ( plsc->difilt )
00280 {
00281 args = (EscText *) ptr;
00282 difilt( &( args->x ), &( args->y ), 1, &clpxmi, &clpxma, &clpymi, &clpyma );
00283 }
00284 }
00285
00286 save_locale = plsave_set_locale();
00287 if ( !plsc->stream_closed )
00288 {
00289 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc, op, ptr );
00290 }
00291 plrestore_locale( save_locale );
00292 }
00293
00294
00295
00296
00297
00298 void
00299 plP_swin( PLWindow *plwin )
00300 {
00301 PLWindow *w;
00302 PLINT clpxmi, clpxma, clpymi, clpyma;
00303
00304
00305
00306 if ( plsc->plbuf_write )
00307 plbuf_esc( plsc, PLESC_SWIN, (void *) plwin );
00308
00309 w = &plsc->plwin[plsc->nplwin++ % PL_MAXWINDOWS];
00310
00311 w->dxmi = plwin->dxmi;
00312 w->dxma = plwin->dxma;
00313 w->dymi = plwin->dymi;
00314 w->dyma = plwin->dyma;
00315
00316 if ( plsc->difilt )
00317 {
00318 xscl[0] = plP_dcpcx( w->dxmi );
00319 xscl[1] = plP_dcpcx( w->dxma );
00320 yscl[0] = plP_dcpcy( w->dymi );
00321 yscl[1] = plP_dcpcy( w->dyma );
00322
00323 difilt( xscl, yscl, 2, &clpxmi, &clpxma, &clpymi, &clpyma );
00324
00325 w->dxmi = plP_pcdcx( xscl[0] );
00326 w->dxma = plP_pcdcx( xscl[1] );
00327 w->dymi = plP_pcdcy( yscl[0] );
00328 w->dyma = plP_pcdcy( yscl[1] );
00329 }
00330
00331 w->wxmi = plwin->wxmi;
00332 w->wxma = plwin->wxma;
00333 w->wymi = plwin->wymi;
00334 w->wyma = plwin->wyma;
00335
00336
00337
00338
00339 if ( plsc->dev_swin )
00340 {
00341 char *save_locale = plsave_set_locale();
00342 if ( !plsc->stream_closed )
00343 {
00344 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
00345 PLESC_SWIN, NULL );
00346 }
00347 plrestore_locale( save_locale );
00348 }
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358 void
00359 plP_line( short *x, short *y )
00360 {
00361 PLINT i, npts = 2, clpxmi, clpxma, clpymi, clpyma;
00362
00363 plsc->page_status = DRAWING;
00364
00365 if ( plsc->plbuf_write )
00366 plbuf_line( plsc, x[0], y[0], x[1], y[1] );
00367
00368 if ( plsc->difilt )
00369 {
00370 for ( i = 0; i < npts; i++ )
00371 {
00372 xscl[i] = x[i];
00373 yscl[i] = y[i];
00374 }
00375 difilt( xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma );
00376 plP_pllclp( xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma, grline );
00377 }
00378 else
00379 {
00380 grline( x, y, npts );
00381 }
00382 }
00383
00384
00385
00386
00387 void
00388 plP_polyline( short *x, short *y, PLINT npts )
00389 {
00390 PLINT i, clpxmi, clpxma, clpymi, clpyma;
00391
00392 plsc->page_status = DRAWING;
00393
00394 if ( plsc->plbuf_write )
00395 plbuf_polyline( plsc, x, y, npts );
00396
00397 if ( plsc->difilt )
00398 {
00399 for ( i = 0; i < npts; i++ )
00400 {
00401 xscl[i] = x[i];
00402 yscl[i] = y[i];
00403 }
00404 difilt( xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma );
00405 plP_pllclp( xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma,
00406 grpolyline );
00407 }
00408 else
00409 {
00410 grpolyline( x, y, npts );
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419 static int foo;
00420
00421 void
00422 plP_fill( short *x, short *y, PLINT npts )
00423 {
00424 PLINT i, clpxmi, clpxma, clpymi, clpyma;
00425
00426 plsc->page_status = DRAWING;
00427
00428 if ( plsc->plbuf_write )
00429 {
00430 plsc->dev_npts = npts;
00431 plsc->dev_x = x;
00432 plsc->dev_y = y;
00433 plbuf_esc( plsc, PLESC_FILL, NULL );
00434 }
00435
00436
00437
00438 if ( plsc->patt == 0 && !plsc->dev_fill0 )
00439 {
00440 if ( !foo )
00441 {
00442 plwarn( "Driver does not support hardware solid fills, switching to software fill.\n" );
00443 foo = 1;
00444 }
00445 plsc->patt = 8;
00446 plpsty( plsc->patt );
00447 }
00448 if ( plsc->dev_fill1 )
00449 {
00450 plsc->patt = -ABS( plsc->patt );
00451 }
00452
00453
00454
00455
00456
00457
00458 if ( plsc->patt > 0 )
00459 plfill_soft( x, y, npts );
00460
00461 else
00462 {
00463 if ( plsc->difilt )
00464 {
00465 for ( i = 0; i < npts; i++ )
00466 {
00467 xscl[i] = x[i];
00468 yscl[i] = y[i];
00469 }
00470 difilt( xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma );
00471 plP_plfclp( xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma,
00472 grfill );
00473 }
00474 else
00475 {
00476 grfill( x, y, npts );
00477 }
00478 }
00479 }
00480
00481
00482
00483
00484
00485
00486 void
00487 plP_gradient( short *x, short *y, PLINT npts )
00488 {
00489 PLINT i, clpxmi, clpxma, clpymi, clpyma;
00490
00491 plsc->page_status = DRAWING;
00492
00493 if ( plsc->plbuf_write )
00494 {
00495 plsc->dev_npts = npts;
00496 plsc->dev_x = x;
00497 plsc->dev_y = y;
00498 plbuf_esc( plsc, PLESC_GRADIENT, NULL );
00499 }
00500
00501
00502 if ( plsc->difilt )
00503 {
00504 for ( i = 0; i < npts; i++ )
00505 {
00506 xscl[i] = x[i];
00507 yscl[i] = y[i];
00508 }
00509 difilt( xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma );
00510 plP_plfclp( xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma,
00511 grgradient );
00512 }
00513 else
00514 {
00515 grgradient( x, y, npts );
00516 }
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 int text2num( const char *text, char end, PLUNICODE *num )
00538 {
00539 char *endptr;
00540 char msgbuf[BUFFER_SIZE];
00541
00542 *num = strtoul( text, &endptr, 0 );
00543
00544 if ( end != endptr[0] )
00545 {
00546 snprintf( msgbuf, BUFFER_SIZE, "text2num: invalid control string detected - %c expected", end );
00547 plwarn( msgbuf );
00548 }
00549
00550 return (int) ( endptr - text );
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 int text2fci( const char *text, unsigned char *hexdigit, unsigned char *hexpower )
00572 {
00573 typedef struct
00574 {
00575 char *ptext;
00576 unsigned char hexdigit;
00577 unsigned char hexpower;
00578 }
00579 TextLookupTable;
00580
00581
00582
00583 #define N_TextLookupTable 10
00584 const TextLookupTable lookup[N_TextLookupTable] = {
00585 { "<sans-serif/>", PL_FCI_SANS, PL_FCI_FAMILY },
00586 { "<serif/>", PL_FCI_SERIF, PL_FCI_FAMILY },
00587 { "<monospace/>", PL_FCI_MONO, PL_FCI_FAMILY },
00588 { "<script/>", PL_FCI_SCRIPT, PL_FCI_FAMILY },
00589 { "<symbol/>", PL_FCI_SYMBOL, PL_FCI_FAMILY },
00590 { "<upright/>", PL_FCI_UPRIGHT, PL_FCI_STYLE },
00591 { "<italic/>", PL_FCI_ITALIC, PL_FCI_STYLE },
00592 { "<oblique/>", PL_FCI_OBLIQUE, PL_FCI_STYLE },
00593 { "<medium/>", PL_FCI_MEDIUM, PL_FCI_WEIGHT },
00594 { "<bold/>", PL_FCI_BOLD, PL_FCI_WEIGHT }
00595 };
00596 int i, length;
00597 for ( i = 0; i < N_TextLookupTable; i++ )
00598 {
00599 length = strlen( lookup[i].ptext );
00600 if ( !strncmp( text, lookup[i].ptext, length ) )
00601 {
00602 *hexdigit = lookup[i].hexdigit;
00603 *hexpower = lookup[i].hexpower;
00604 return ( length );
00605 }
00606 }
00607 *hexdigit = 0;
00608 *hexpower = PL_FCI_HEXPOWER_IMPOSSIBLE;
00609 return ( 0 );
00610 }
00611
00612 static PLUNICODE unicode_buffer[1024];
00613
00614 void
00615 plP_text( PLINT base, PLFLT just, PLFLT *xform, PLINT x, PLINT y,
00616 PLINT refx, PLINT refy, const char *string )
00617 {
00618 if ( plsc->dev_text )
00619 {
00620 EscText args;
00621 short len = 0;
00622 char skip;
00623 unsigned short i, j;
00624 PLUNICODE code;
00625 char esc;
00626 int idx;
00627
00628 args.base = base;
00629 args.just = just;
00630 args.xform = xform;
00631 args.x = x;
00632 args.y = y;
00633 args.refx = refx;
00634 args.refy = refy;
00635 args.string = string;
00636
00637 if ( plsc->dev_unicode )
00638 {
00639 PLINT ig;
00640 PLUNICODE fci;
00641 PLUNICODE orig_fci;
00642 unsigned char hexdigit, hexpower;
00643
00644
00645
00646 if ( string != NULL )
00647
00648
00649
00650 {
00651 len = strlen( string );
00652
00653
00654 plgesc( &esc );
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 plgfci( &fci );
00667 orig_fci = fci;
00668
00669
00670
00671 for ( j = i = 0; i < len; i++ )
00672 {
00673 skip = 0;
00674
00675 if ( string[i] == esc )
00676 {
00677 switch ( string[i + 1] )
00678 {
00679 case '(':
00680 i += 2 + text2num( &string[i + 2], ')', &code );
00681 idx = plhershey2unicode( code );
00682 unicode_buffer[j++] = \
00683 (PLUNICODE) hershey_to_unicode_lookup_table[idx].Unicode;
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 if ( unicode_buffer[j - 1] == esc )
00694 unicode_buffer[j++] = esc;
00695 j--;
00696 skip = 1;
00697 break;
00698
00699 case '[':
00700 i += 2 + text2num( &string[i + 2], ']', &code );
00701 unicode_buffer[j++] = code;
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 if ( unicode_buffer[j - 1] == esc )
00712 unicode_buffer[j++] = esc;
00713 j--;
00714 skip = 1;
00715 break;
00716
00717 case '<':
00718 if ( '0' <= string[i + 2] && string[i + 2] <= '9' )
00719 {
00720 i += 2 + text2num( &string[i + 2], '>', &code );
00721 if ( code & PL_FCI_MARK )
00722 {
00723
00724
00725
00726 fci = code;
00727 unicode_buffer[j] = fci;
00728 skip = 1;
00729 }
00730 else
00731 {
00732
00733
00734
00735
00736
00737 hexdigit = ( code >> 4 ) & PL_FCI_HEXDIGIT_MASK;
00738 hexpower = code & PL_FCI_HEXPOWER_MASK;
00739 plP_hex2fci( hexdigit, hexpower, &fci );
00740 unicode_buffer[j] = fci;
00741 skip = 1;
00742 }
00743 }
00744 else
00745 {
00746 i += text2fci( &string[i + 1], &hexdigit, &hexpower );
00747 if ( hexpower < 7 )
00748 {
00749 plP_hex2fci( hexdigit, hexpower, &fci );
00750 unicode_buffer[j] = fci;
00751 skip = 1;
00752 }
00753 }
00754 break;
00755
00756 case 'f':
00757 case 'F':
00758
00759
00760
00761
00762
00763
00764 fci = PL_FCI_MARK;
00765 if ( string[i + 2] == 'n' )
00766 {
00767
00768 plP_hex2fci( PL_FCI_SANS, PL_FCI_FAMILY, &fci );
00769 }
00770 else if ( string[i + 2] == 'r' )
00771 {
00772
00773 plP_hex2fci( PL_FCI_SERIF, PL_FCI_FAMILY, &fci );
00774 }
00775 else if ( string[i + 2] == 'i' )
00776 {
00777
00778 plP_hex2fci( PL_FCI_ITALIC, PL_FCI_STYLE, &fci );
00779 plP_hex2fci( PL_FCI_SERIF, PL_FCI_FAMILY, &fci );
00780 }
00781 else if ( string[i + 2] == 's' )
00782 {
00783
00784 plP_hex2fci( PL_FCI_SCRIPT, PL_FCI_FAMILY, &fci );
00785 }
00786 else
00787 fci = PL_FCI_IMPOSSIBLE;
00788
00789 if ( fci != PL_FCI_IMPOSSIBLE )
00790 {
00791 i += 2;
00792 unicode_buffer[j] = fci;
00793 skip = 1;
00794 }
00795 break;
00796
00797 case 'g':
00798 case 'G':
00799
00800
00801
00802
00803
00804 ig = plP_strpos( plP_greek_mnemonic, string[i + 2] );
00805 if ( ig >= 0 )
00806 {
00807 if ( ig >= 24 )
00808 ig = ig + 100 - 24;
00809 ig = ig + 527;
00810
00811
00812
00813
00814 if ( ig == 631 )
00815 ig = 684;
00816 else if ( ig == 634 )
00817 ig = 685;
00818 else if ( ig == 647 )
00819 ig = 686;
00820 idx = plhershey2unicode( ig );
00821 unicode_buffer[j++] = \
00822 (PLUNICODE) hershey_to_unicode_lookup_table[idx].Unicode;
00823 i += 2;
00824 skip = 1;
00825
00826 }
00827 else
00828 {
00829
00830
00831 unicode_buffer[j++] = (PLUNICODE) 0x00;
00832 i += 2;
00833 skip = 1;
00834
00835 }
00836 j--;
00837 break;
00838 }
00839 }
00840
00841 if ( skip == 0 )
00842 {
00843 PLUNICODE unichar = 0;
00844 #ifdef HAVE_LIBUNICODE
00845 char * ptr = unicode_get_utf8( string + i, &unichar );
00846 #else
00847 char * ptr = utf8_to_ucs4( string + i, &unichar );
00848 #endif
00849 if ( ptr == NULL )
00850 {
00851 char buf[BUFFER_SIZE];
00852 char tmpstring[31];
00853 strncpy( tmpstring, string, 30 );
00854 tmpstring[30] = '\0';
00855 snprintf( buf, BUFFER_SIZE, "UTF-8 string is malformed: %s%s",
00856 tmpstring, strlen( string ) > 30 ? "[...]" : "" );
00857 plabort( buf );
00858 return;
00859 }
00860 unicode_buffer [j] = unichar;
00861 i += ptr - ( string + i ) - 1;
00862
00863
00864
00865
00866 if ( unicode_buffer[j] == esc && string[i + 1] == esc )
00867 {
00868 i++;
00869 unicode_buffer[++j] = esc;
00870 }
00871 }
00872 j++;
00873 }
00874 if ( j > 0 )
00875 {
00876 args.unicode_array_len = j;
00877
00878 args.unicode_array = &unicode_buffer[0];
00879
00880
00881
00882 }
00883
00884
00885
00886
00887 if ( plsc->alt_unicode )
00888 {
00889 args.n_fci = orig_fci;
00890 plP_esc( PLESC_BEGIN_TEXT, &args );
00891
00892 for ( i = 0; i < len; i++ )
00893 {
00894 skip = 0;
00895
00896 if ( string[i] == esc )
00897 {
00898 switch ( string[i + 1] )
00899 {
00900 case '(':
00901 i += 2 + text2num( &string[i + 2], ')', &code );
00902 idx = plhershey2unicode( code );
00903 args.n_char = \
00904 (PLUNICODE) hershey_to_unicode_lookup_table[idx].Unicode;
00905 plP_esc( PLESC_TEXT_CHAR, &args );
00906
00907 skip = 1;
00908 break;
00909
00910 case '[':
00911 i += 2 + text2num( &string[i + 2], ']', &code );
00912 args.n_char = code;
00913 plP_esc( PLESC_TEXT_CHAR, &args );
00914 skip = 1;
00915 break;
00916
00917 case '<':
00918 if ( '0' <= string[i + 2] && string[i + 2] <= '9' )
00919 {
00920 i += 2 + text2num( &string[i + 2], '>', &code );
00921 if ( code & PL_FCI_MARK )
00922 {
00923
00924
00925
00926 fci = code;
00927 skip = 1;
00928
00929 args.n_fci = fci;
00930 args.n_ctrl_char = PLTEXT_FONTCHANGE;
00931 plP_esc( PLESC_CONTROL_CHAR, &args );
00932 }
00933 else
00934 {
00935
00936
00937
00938
00939
00940 hexdigit = ( code >> 4 ) & PL_FCI_HEXDIGIT_MASK;
00941 hexpower = code & PL_FCI_HEXPOWER_MASK;
00942 plP_hex2fci( hexdigit, hexpower, &fci );
00943 skip = 1;
00944
00945 args.n_fci = fci;
00946 args.n_ctrl_char = PLTEXT_FONTCHANGE;
00947 plP_esc( PLESC_CONTROL_CHAR, &args );
00948 }
00949 }
00950 else
00951 {
00952 i += text2fci( &string[i + 1], &hexdigit, &hexpower );
00953 if ( hexpower < 7 )
00954 {
00955 plP_hex2fci( hexdigit, hexpower, &fci );
00956 skip = 1;
00957
00958 args.n_fci = fci;
00959 args.n_ctrl_char = PLTEXT_FONTCHANGE;
00960 plP_esc( PLESC_CONTROL_CHAR, &args );
00961 }
00962 }
00963 break;
00964
00965 case 'f':
00966 case 'F':
00967
00968
00969
00970
00971
00972
00973 fci = PL_FCI_MARK;
00974 if ( string[i + 2] == 'n' )
00975 {
00976
00977 plP_hex2fci( PL_FCI_SANS, PL_FCI_FAMILY, &fci );
00978 }
00979 else if ( string[i + 2] == 'r' )
00980 {
00981
00982 plP_hex2fci( PL_FCI_SERIF, PL_FCI_FAMILY, &fci );
00983 }
00984 else if ( string[i + 2] == 'i' )
00985 {
00986
00987 plP_hex2fci( PL_FCI_ITALIC, PL_FCI_STYLE, &fci );
00988 plP_hex2fci( PL_FCI_SERIF, PL_FCI_FAMILY, &fci );
00989 }
00990 else if ( string[i + 2] == 's' )
00991 {
00992
00993 plP_hex2fci( PL_FCI_SCRIPT, PL_FCI_FAMILY, &fci );
00994 }
00995 else
00996 fci = PL_FCI_IMPOSSIBLE;
00997
00998 if ( fci != PL_FCI_IMPOSSIBLE )
00999 {
01000 i += 2;
01001 skip = 1;
01002
01003 args.n_fci = fci;
01004 args.n_ctrl_char = PLTEXT_FONTCHANGE;
01005 plP_esc( PLESC_CONTROL_CHAR, &args );
01006 }
01007 break;
01008
01009 case 'g':
01010 case 'G':
01011
01012
01013
01014
01015 ig = plP_strpos( plP_greek_mnemonic, string[i + 2] );
01016 if ( ig >= 0 )
01017 {
01018 if ( ig >= 24 )
01019 ig = ig + 100 - 24;
01020 ig = ig + 527;
01021
01022
01023
01024
01025 if ( ig == 631 )
01026 ig = 684;
01027 else if ( ig == 634 )
01028 ig = 685;
01029 else if ( ig == 647 )
01030 ig = 686;
01031 idx = plhershey2unicode( ig );
01032 i += 2;
01033 skip = 1;
01034
01035
01036 args.n_char = \
01037 (PLUNICODE) hershey_to_unicode_lookup_table[idx].Unicode;
01038 plP_esc( PLESC_TEXT_CHAR, &args );
01039 }
01040 else
01041 {
01042
01043
01044 i += 2;
01045 skip = 1;
01046
01047
01048 args.n_char = \
01049 (PLUNICODE) hershey_to_unicode_lookup_table[idx].Unicode;
01050 plP_esc( PLESC_TEXT_CHAR, &args );
01051 }
01052 break;
01053
01054 case 'u':
01055 args.n_ctrl_char = PLTEXT_SUPERSCRIPT;
01056 plP_esc( PLESC_CONTROL_CHAR, &args );
01057 i += 1;
01058 skip = 1;
01059 break;
01060
01061 case 'd':
01062 args.n_ctrl_char = PLTEXT_SUBSCRIPT;
01063 plP_esc( PLESC_CONTROL_CHAR, &args );
01064 i += 1;
01065 skip = 1;
01066 break;
01067 }
01068 }
01069
01070 if ( skip == 0 )
01071 {
01072 PLUNICODE unichar = 0;
01073 #ifdef HAVE_LIBUNICODE
01074 char * ptr = unicode_get_utf8( string + i, &unichar );
01075 #else
01076 char * ptr = utf8_to_ucs4( string + i, &unichar );
01077 #endif
01078 if ( ptr == NULL )
01079 {
01080 char buf[BUFFER_SIZE];
01081 char tmpstring[31];
01082 strncpy( tmpstring, string, 30 );
01083 tmpstring[30] = '\0';
01084 snprintf( buf, BUFFER_SIZE, "UTF-8 string is malformed: %s%s",
01085 tmpstring, strlen( string ) > 30 ? "[...]" : "" );
01086 plabort( buf );
01087 return;
01088 }
01089 i += ptr - ( string + i ) - 1;
01090
01091
01092
01093
01094 if ( string[i] == esc && string[i + 1] == esc )
01095 {
01096 i++;
01097 args.n_char = esc;
01098 }
01099 else
01100 {
01101 args.n_char = unichar;
01102 }
01103 plP_esc( PLESC_TEXT_CHAR, &args );
01104 }
01105 }
01106 plP_esc( PLESC_END_TEXT, &args );
01107 }
01108
01109
01110
01111 if ( j == 0 )
01112 return;
01113 }
01114 }
01115
01116 if ( plsc->dev_unicode )
01117 {
01118 args.string = NULL;
01119 }
01120 else
01121 {
01122 args.string = string;
01123 }
01124
01125 plP_esc( PLESC_HAS_TEXT, &args );
01126
01127 #ifndef DEBUG_TEXT
01128 }
01129 else
01130 {
01131 #endif
01132 plstr( base, xform, refx, refy, string );
01133 }
01134 }
01135
01136
01137 static char *
01138 utf8_to_ucs4( const char *ptr, PLUNICODE *unichar )
01139 {
01140 char tmp;
01141 int isFirst = 1;
01142 int cnt = 0;
01143
01144 do
01145 {
01146
01147 tmp = *ptr++;
01148 if ( isFirst )
01149 {
01150 isFirst = 0;
01151
01152 if ( (unsigned char) ( tmp & 0x80 ) == 0x00 )
01153 {
01154 *unichar = (unsigned int) tmp & 0x7F;
01155 cnt = 0;
01156 }
01157 else if ( (unsigned char) ( tmp & 0xE0 ) == 0xC0 )
01158 {
01159 *unichar = (unsigned int) tmp & 0x1F;
01160 cnt = 1;
01161 }
01162 else if ( (unsigned char) ( tmp & 0xF0 ) == 0xE0 )
01163 {
01164 *unichar = (unsigned char) tmp & 0x0F;
01165 cnt = 2;
01166 }
01167 else if ( (unsigned char) ( tmp & 0xF8 ) == 0xF0 )
01168 {
01169 *unichar = (unsigned char) tmp & 0x07;
01170 cnt = 3;
01171 }
01172 else if ( (unsigned char) ( tmp & 0xFC ) == 0xF8 )
01173 {
01174 *unichar = (unsigned char) tmp & 0x03;
01175 cnt = 4;
01176 }
01177 else if ( (unsigned char) ( tmp & 0xFE ) == 0xFC )
01178 {
01179 *unichar = (unsigned char) tmp & 0x01;
01180 cnt = 5;
01181 }
01182 else
01183 {
01184 ptr = NULL;
01185 cnt = 0;
01186 }
01187 }
01188 else
01189 {
01190 if ( (unsigned char) ( tmp & 0xC0 ) == 0x80 )
01191 {
01192 *unichar = ( *unichar << 6 ) | ( (unsigned int) tmp & 0x3F );
01193 cnt--;
01194 }
01195 else
01196 {
01197 ptr = NULL;
01198 cnt = 0;
01199 }
01200 }
01201 } while ( cnt > 0 );
01202 return (char *) ptr;
01203 }
01204
01205
01206 int
01207 ucs4_to_utf8( PLUNICODE unichar, char *ptr )
01208 {
01209 unsigned char *tmp;
01210 int len;
01211
01212 tmp = (unsigned char *) ptr;
01213
01214 if ( ( unichar & 0xffff80 ) == 0 )
01215 {
01216 *tmp = (unsigned char) unichar;
01217 tmp++;
01218 len = 1;
01219 }
01220 else if ( ( unichar & 0xfff800 ) == 0 )
01221 {
01222 *tmp = (unsigned char) 0xc0 | ( unichar >> 6 );
01223 tmp++;
01224 *tmp = (unsigned char) 0x80 | ( unichar & 0x3f );
01225 tmp++;
01226 len = 2;
01227 }
01228 else if ( ( unichar & 0xff0000 ) == 0 )
01229 {
01230 *tmp = (unsigned char) 0xe0 | ( unichar >> 12 );
01231 tmp++;
01232 *tmp = (unsigned char) 0x80 | ( ( unichar >> 6 ) & 0x3f );
01233 tmp++;
01234 *tmp = (unsigned char) 0x80 | ( unichar & 0x3f );
01235 tmp++;
01236 len = 3;
01237 }
01238 else if ( ( unichar & 0xe0000 ) == 0 )
01239 {
01240 *tmp = (unsigned char) 0xf0 | ( unichar >> 18 );
01241 tmp++;
01242 *tmp = (unsigned char) 0x80 | ( ( unichar >> 12 ) & 0x3f );
01243 tmp++;
01244 *tmp = (unsigned char) 0x80 | ( ( unichar >> 6 ) & 0x3f );
01245 tmp++;
01246 *tmp = (unsigned char) 0x80 | ( unichar & 0x3f );
01247 tmp++;
01248 len = 4;
01249 }
01250 else
01251 {
01252 len = 0;
01253 }
01254 *tmp = '\0';
01255
01256 return len;
01257 }
01258
01259 static void
01260 grline( short *x, short *y, PLINT npts )
01261 {
01262 char *save_locale = plsave_set_locale();
01263 if ( !plsc->stream_closed )
01264 {
01265 ( *plsc->dispatch_table->pl_line )( (struct PLStream_struct *) plsc,
01266 x[0], y[0], x[1], y[1] );
01267 }
01268 plrestore_locale( save_locale );
01269 }
01270
01271 static void
01272 grpolyline( short *x, short *y, PLINT npts )
01273 {
01274 char *save_locale = plsave_set_locale();
01275 if ( !plsc->stream_closed )
01276 {
01277 ( *plsc->dispatch_table->pl_polyline )( (struct PLStream_struct *) plsc,
01278 x, y, npts );
01279 }
01280 plrestore_locale( save_locale );
01281 }
01282
01283 static void
01284 grfill( short *x, short *y, PLINT npts )
01285 {
01286 char * save_locale;
01287 plsc->dev_npts = npts;
01288 plsc->dev_x = x;
01289 plsc->dev_y = y;
01290
01291 save_locale = plsave_set_locale();
01292 if ( !plsc->stream_closed )
01293 {
01294 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
01295 PLESC_FILL, NULL );
01296 }
01297 plrestore_locale( save_locale );
01298 }
01299
01300 static void
01301 grgradient( short *x, short *y, PLINT npts )
01302 {
01303 char * save_locale;
01304 plsc->dev_npts = npts;
01305 plsc->dev_x = x;
01306 plsc->dev_y = y;
01307
01308 save_locale = plsave_set_locale();
01309 if ( !plsc->stream_closed )
01310 {
01311 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
01312 PLESC_GRADIENT, NULL );
01313 }
01314 plrestore_locale( save_locale );
01315 }
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 void
01338 difilt( PLINT *xscl, PLINT *yscl, PLINT npts,
01339 PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma )
01340 {
01341 PLINT i, x, y;
01342
01343
01344
01345 if ( plsc->difilt & PLDI_MAP )
01346 {
01347 for ( i = 0; i < npts; i++ )
01348 {
01349 xscl[i] = (PLINT) ( plsc->dimxax * xscl[i] + plsc->dimxb );
01350 yscl[i] = (PLINT) ( plsc->dimyay * yscl[i] + plsc->dimyb );
01351 }
01352 }
01353
01354
01355
01356 if ( plsc->difilt & PLDI_ORI )
01357 {
01358 for ( i = 0; i < npts; i++ )
01359 {
01360 x = (PLINT) ( plsc->dioxax * xscl[i] + plsc->dioxay * yscl[i] + plsc->dioxb );
01361 y = (PLINT) ( plsc->dioyax * xscl[i] + plsc->dioyay * yscl[i] + plsc->dioyb );
01362 xscl[i] = x;
01363 yscl[i] = y;
01364 }
01365 }
01366
01367
01368
01369 if ( plsc->difilt & PLDI_PLT )
01370 {
01371 for ( i = 0; i < npts; i++ )
01372 {
01373 xscl[i] = (PLINT) ( plsc->dipxax * xscl[i] + plsc->dipxb );
01374 yscl[i] = (PLINT) ( plsc->dipyay * yscl[i] + plsc->dipyb );
01375 }
01376 }
01377
01378
01379
01380
01381 if ( plsc->difilt & PLDI_DEV )
01382 {
01383 for ( i = 0; i < npts; i++ )
01384 {
01385 xscl[i] = (PLINT) ( plsc->didxax * xscl[i] + plsc->didxb );
01386 yscl[i] = (PLINT) ( plsc->didyay * yscl[i] + plsc->didyb );
01387 }
01388 *clpxmi = plsc->diclpxmi;
01389 *clpxma = plsc->diclpxma;
01390 *clpymi = plsc->diclpymi;
01391 *clpyma = plsc->diclpyma;
01392 }
01393 else
01394 {
01395 *clpxmi = plsc->phyxmi;
01396 *clpxma = plsc->phyxma;
01397 *clpymi = plsc->phyymi;
01398 *clpyma = plsc->phyyma;
01399 }
01400 }
01401
01402 void
01403 sdifilt( short *xscl, short *yscl, PLINT npts,
01404 PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma )
01405 {
01406 int i;
01407 short x, y;
01408
01409
01410
01411 if ( plsc->difilt & PLDI_MAP )
01412 {
01413 for ( i = 0; i < npts; i++ )
01414 {
01415 xscl[i] = (PLINT) ( plsc->dimxax * xscl[i] + plsc->dimxb );
01416 yscl[i] = (PLINT) ( plsc->dimyay * yscl[i] + plsc->dimyb );
01417 }
01418 }
01419
01420
01421
01422 if ( plsc->difilt & PLDI_ORI )
01423 {
01424 for ( i = 0; i < npts; i++ )
01425 {
01426 x = (PLINT) ( plsc->dioxax * xscl[i] + plsc->dioxay * yscl[i] + plsc->dioxb );
01427 y = (PLINT) ( plsc->dioyax * xscl[i] + plsc->dioyay * yscl[i] + plsc->dioyb );
01428 xscl[i] = x;
01429 yscl[i] = y;
01430 }
01431 }
01432
01433
01434
01435 if ( plsc->difilt & PLDI_PLT )
01436 {
01437 for ( i = 0; i < npts; i++ )
01438 {
01439 xscl[i] = (PLINT) ( plsc->dipxax * xscl[i] + plsc->dipxb );
01440 yscl[i] = (PLINT) ( plsc->dipyay * yscl[i] + plsc->dipyb );
01441 }
01442 }
01443
01444
01445
01446
01447 if ( plsc->difilt & PLDI_DEV )
01448 {
01449 for ( i = 0; i < npts; i++ )
01450 {
01451 xscl[i] = (PLINT) ( plsc->didxax * xscl[i] + plsc->didxb );
01452 yscl[i] = (PLINT) ( plsc->didyay * yscl[i] + plsc->didyb );
01453 }
01454 *clpxmi = (PLINT) ( plsc->diclpxmi );
01455 *clpxma = (PLINT) ( plsc->diclpxma );
01456 *clpymi = (PLINT) ( plsc->diclpymi );
01457 *clpyma = (PLINT) ( plsc->diclpyma );
01458 }
01459 else
01460 {
01461 *clpxmi = plsc->phyxmi;
01462 *clpxma = plsc->phyxma;
01463 *clpymi = plsc->phyymi;
01464 *clpyma = plsc->phyyma;
01465 }
01466 }
01467
01468
01469
01470
01471
01472
01473
01474
01475 void
01476 difilt_clip( PLINT *x_coords, PLINT *y_coords )
01477 {
01478 PLINT x1c, x2c, y1c, y2c;
01479
01480 x1c = plsc->clpxmi;
01481 y1c = plsc->clpymi;
01482 x2c = plsc->clpxma;
01483 y2c = plsc->clpyma;
01484 x_coords[0] = x1c;
01485 x_coords[1] = x1c;
01486 x_coords[2] = x2c;
01487 x_coords[3] = x2c;
01488 y_coords[0] = y1c;
01489 y_coords[1] = y2c;
01490 y_coords[2] = y2c;
01491 y_coords[3] = y1c;
01492 difilt( x_coords, y_coords, 4, &x1c, &x2c, &y1c, &y2c );
01493 }
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503 static void
01504 setdef_diplt()
01505 {
01506 plsc->dipxmin = 0.0;
01507 plsc->dipxmax = 1.0;
01508 plsc->dipymin = 0.0;
01509 plsc->dipymax = 1.0;
01510 }
01511
01512 static void
01513 setdef_didev()
01514 {
01515 plsc->mar = 0.0;
01516 plsc->aspect = 0.0;
01517 plsc->jx = 0.0;
01518 plsc->jy = 0.0;
01519 }
01520
01521 static void
01522 setdef_diori()
01523 {
01524 plsc->diorot = 0.;
01525 }
01526
01527 static void
01528 pldi_ini( void )
01529 {
01530 if ( plsc->level >= 1 )
01531 {
01532 if ( plsc->difilt & PLDI_MAP )
01533 calc_dimap();
01534
01535 if ( plsc->difilt & PLDI_ORI )
01536 calc_diori();
01537 else
01538 setdef_diori();
01539
01540 if ( plsc->difilt & PLDI_PLT )
01541 calc_diplt();
01542 else
01543 setdef_diplt();
01544
01545 if ( plsc->difilt & PLDI_DEV )
01546 calc_didev();
01547 else
01548 setdef_didev();
01549 }
01550 }
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 void
01562 pldid2pc( PLFLT *xmin, PLFLT *ymin, PLFLT *xmax, PLFLT *ymax )
01563 {
01564 PLFLT pxmin, pymin, pxmax, pymax;
01565 PLFLT sxmin, symin, sxmax, symax;
01566 PLFLT rxmin, rymin, rxmax, rymax;
01567
01568 if ( plsc->difilt & PLDI_DEV )
01569 {
01570 pldebug( "pldid2pc",
01571 "Relative device coordinates (in): %f, %f, %f, %f\n",
01572 *xmin, *ymin, *xmax, *ymax );
01573
01574 pxmin = plP_dcpcx( *xmin );
01575 pymin = plP_dcpcy( *ymin );
01576 pxmax = plP_dcpcx( *xmax );
01577 pymax = plP_dcpcy( *ymax );
01578
01579 sxmin = ( pxmin - plsc->didxb ) / plsc->didxax;
01580 symin = ( pymin - plsc->didyb ) / plsc->didyay;
01581 sxmax = ( pxmax - plsc->didxb ) / plsc->didxax;
01582 symax = ( pymax - plsc->didyb ) / plsc->didyay;
01583
01584 rxmin = plP_pcdcx( (PLINT) sxmin );
01585 rymin = plP_pcdcy( (PLINT) symin );
01586 rxmax = plP_pcdcx( (PLINT) sxmax );
01587 rymax = plP_pcdcy( (PLINT) symax );
01588
01589 *xmin = ( rxmin < 0 ) ? 0 : rxmin;
01590 *xmax = ( rxmax > 1 ) ? 1 : rxmax;
01591 *ymin = ( rymin < 0 ) ? 0 : rymin;
01592 *ymax = ( rymax > 1 ) ? 1 : rymax;
01593
01594 pldebug( "pldid2pc",
01595 "Relative plot coordinates (out): %f, %f, %f, %f\n",
01596 rxmin, rymin, rxmax, rymax );
01597 }
01598 }
01599
01600
01601
01602
01603
01604
01605
01606
01607 void
01608 pldip2dc( PLFLT *xmin, PLFLT *ymin, PLFLT *xmax, PLFLT *ymax )
01609 {
01610 PLFLT pxmin, pymin, pxmax, pymax;
01611 PLFLT sxmin, symin, sxmax, symax;
01612 PLFLT rxmin, rymin, rxmax, rymax;
01613
01614 if ( plsc->difilt & PLDI_DEV )
01615 {
01616 pldebug( "pldip2pc",
01617 "Relative plot coordinates (in): %f, %f, %f, %f\n",
01618 *xmin, *ymin, *xmax, *ymax );
01619
01620 pxmin = plP_dcpcx( *xmin );
01621 pymin = plP_dcpcy( *ymin );
01622 pxmax = plP_dcpcx( *xmax );
01623 pymax = plP_dcpcy( *ymax );
01624
01625 sxmin = pxmin * plsc->didxax + plsc->didxb;
01626 symin = pymin * plsc->didyay + plsc->didyb;
01627 sxmax = pxmax * plsc->didxax + plsc->didxb;
01628 symax = pymax * plsc->didyay + plsc->didyb;
01629
01630 rxmin = plP_pcdcx( (PLINT) sxmin );
01631 rymin = plP_pcdcy( (PLINT) symin );
01632 rxmax = plP_pcdcx( (PLINT) sxmax );
01633 rymax = plP_pcdcy( (PLINT) symax );
01634
01635 *xmin = ( rxmin < 0 ) ? 0 : rxmin;
01636 *xmax = ( rxmax > 1 ) ? 1 : rxmax;
01637 *ymin = ( rymin < 0 ) ? 0 : rymin;
01638 *ymax = ( rymax > 1 ) ? 1 : rymax;
01639
01640 pldebug( "pldip2pc",
01641 "Relative device coordinates (out): %f, %f, %f, %f\n",
01642 rxmin, rymin, rxmax, rymax );
01643 }
01644 }
01645
01646
01647
01648
01649
01650
01651
01652 void
01653 c_plsdiplt( PLFLT xmin, PLFLT ymin, PLFLT xmax, PLFLT ymax )
01654 {
01655 plsc->dipxmin = ( xmin < xmax ) ? xmin : xmax;
01656 plsc->dipxmax = ( xmin < xmax ) ? xmax : xmin;
01657 plsc->dipymin = ( ymin < ymax ) ? ymin : ymax;
01658 plsc->dipymax = ( ymin < ymax ) ? ymax : ymin;
01659
01660 if ( xmin == 0. && xmax == 1. && ymin == 0. && ymax == 1. )
01661 {
01662 plsc->difilt &= ~PLDI_PLT;
01663 return;
01664 }
01665
01666 plsc->difilt |= PLDI_PLT;
01667 pldi_ini();
01668 }
01669
01670
01671
01672
01673
01674
01675
01676 void
01677 c_plsdiplz( PLFLT xmin, PLFLT ymin, PLFLT xmax, PLFLT ymax )
01678 {
01679 if ( plsc->difilt & PLDI_PLT )
01680 {
01681 xmin = plsc->dipxmin + ( plsc->dipxmax - plsc->dipxmin ) * xmin;
01682 ymin = plsc->dipymin + ( plsc->dipymax - plsc->dipymin ) * ymin;
01683 xmax = plsc->dipxmin + ( plsc->dipxmax - plsc->dipxmin ) * xmax;
01684 ymax = plsc->dipymin + ( plsc->dipymax - plsc->dipymin ) * ymax;
01685 }
01686
01687 plsdiplt( xmin, ymin, xmax, ymax );
01688 }
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701 static void
01702 calc_diplt( void )
01703 {
01704 PLINT pxmin, pxmax, pymin, pymax, pxlen, pylen;
01705
01706 if ( plsc->dev_di )
01707 {
01708 char *save_locale = plsave_set_locale();
01709 if ( !plsc->stream_closed )
01710 {
01711 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
01712 PLESC_DI, NULL );
01713 }
01714 plrestore_locale( save_locale );
01715 }
01716
01717 if ( !( plsc->difilt & PLDI_PLT ) )
01718 return;
01719
01720 pxmin = plP_dcpcx( plsc->dipxmin );
01721 pxmax = plP_dcpcx( plsc->dipxmax );
01722 pymin = plP_dcpcy( plsc->dipymin );
01723 pymax = plP_dcpcy( plsc->dipymax );
01724
01725 pxlen = pxmax - pxmin;
01726 pylen = pymax - pymin;
01727 pxlen = MAX( 1, pxlen );
01728 pylen = MAX( 1, pylen );
01729
01730 plsc->dipxax = plsc->phyxlen / (double) pxlen;
01731 plsc->dipyay = plsc->phyylen / (double) pylen;
01732 plsc->dipxb = plsc->phyxmi - plsc->dipxax * pxmin;
01733 plsc->dipyb = plsc->phyymi - plsc->dipyay * pymin;
01734 }
01735
01736
01737
01738
01739
01740
01741
01742 void
01743 c_plgdiplt( PLFLT *p_xmin, PLFLT *p_ymin, PLFLT *p_xmax, PLFLT *p_ymax )
01744 {
01745 *p_xmin = plsc->dipxmin;
01746 *p_xmax = plsc->dipxmax;
01747 *p_ymin = plsc->dipymin;
01748 *p_ymax = plsc->dipymax;
01749 }
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762 void
01763 c_plsdidev( PLFLT mar, PLFLT aspect, PLFLT jx, PLFLT jy )
01764 {
01765 plsetvar( plsc->mar, mar );
01766 plsetvar( plsc->aspect, aspect );
01767 plsetvar( plsc->jx, jx );
01768 plsetvar( plsc->jy, jy );
01769
01770 if ( mar == 0. && aspect == 0. && jx == 0. && jy == 0. &&
01771 !( plsc->difilt & PLDI_ORI ) )
01772 {
01773 plsc->difilt &= ~PLDI_DEV;
01774 return;
01775 }
01776
01777 plsc->difilt |= PLDI_DEV;
01778 pldi_ini();
01779 }
01780
01781
01782
01783
01784
01785
01786
01787
01788 static void
01789 calc_didev( void )
01790 {
01791 PLFLT lx, ly, aspect, aspdev;
01792 PLFLT xmin, xmax, xlen, ymin, ymax, ylen;
01793 PLINT pxmin, pxmax, pymin, pymax, pxlen, pylen;
01794
01795 if ( plsc->dev_di )
01796 {
01797 char *save_locale = plsave_set_locale();
01798 if ( !plsc->stream_closed )
01799 {
01800 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
01801 PLESC_DI, NULL );
01802 }
01803 plrestore_locale( save_locale );
01804 }
01805
01806 if ( !( plsc->difilt & PLDI_DEV ) )
01807 return;
01808
01809
01810
01811 lx = plsc->phyxlen / plsc->xpmm;
01812 ly = plsc->phyylen / plsc->ypmm;
01813 aspdev = lx / ly;
01814
01815 if ( plsc->difilt & PLDI_ORI )
01816 aspect = plsc->aspori;
01817 else
01818 aspect = plsc->aspect;
01819
01820 if ( aspect <= 0. )
01821 aspect = plsc->aspdev;
01822
01823
01824
01825 plsc->mar = ( plsc->mar > 0.5 ) ? 0.5 : plsc->mar;
01826 plsc->mar = ( plsc->mar < 0.0 ) ? 0.0 : plsc->mar;
01827 plsc->jx = ( plsc->jx > 0.5 ) ? 0.5 : plsc->jx;
01828 plsc->jx = ( plsc->jx < -0.5 ) ? -0.5 : plsc->jx;
01829 plsc->jy = ( plsc->jy > 0.5 ) ? 0.5 : plsc->jy;
01830 plsc->jy = ( plsc->jy < -0.5 ) ? -0.5 : plsc->jy;
01831
01832
01833
01834 xlen = ( aspect < aspdev ) ? ( aspect / aspdev ) : 1.0;
01835 ylen = ( aspect < aspdev ) ? 1.0 : ( aspdev / aspect );
01836
01837 xlen *= ( 1.0 - 2. * plsc->mar );
01838 ylen *= ( 1.0 - 2. * plsc->mar );
01839
01840 xmin = ( 1. - xlen ) * ( 0.5 + plsc->jx );
01841 xmax = xmin + xlen;
01842
01843 ymin = ( 1. - ylen ) * ( 0.5 + plsc->jy );
01844 ymax = ymin + ylen;
01845
01846
01847
01848 pxmin = plP_dcpcx( xmin );
01849 pxmax = plP_dcpcx( xmax );
01850 pymin = plP_dcpcy( ymin );
01851 pymax = plP_dcpcy( ymax );
01852
01853 pxlen = pxmax - pxmin;
01854 pylen = pymax - pymin;
01855 pxlen = MAX( 1, pxlen );
01856 pylen = MAX( 1, pylen );
01857
01858 plsc->didxax = pxlen / (double) plsc->phyxlen;
01859 plsc->didyay = pylen / (double) plsc->phyylen;
01860 plsc->didxb = pxmin - plsc->didxax * plsc->phyxmi;
01861 plsc->didyb = pymin - plsc->didyay * plsc->phyymi;
01862
01863
01864
01865 plsc->diclpxmi = (PLINT) ( plsc->didxax * plsc->phyxmi + plsc->didxb );
01866 plsc->diclpxma = (PLINT) ( plsc->didxax * plsc->phyxma + plsc->didxb );
01867 plsc->diclpymi = (PLINT) ( plsc->didyay * plsc->phyymi + plsc->didyb );
01868 plsc->diclpyma = (PLINT) ( plsc->didyay * plsc->phyyma + plsc->didyb );
01869 }
01870
01871
01872
01873
01874
01875
01876
01877 void
01878 c_plgdidev( PLFLT *p_mar, PLFLT *p_aspect, PLFLT *p_jx, PLFLT *p_jy )
01879 {
01880 *p_mar = plsc->mar;
01881 *p_aspect = plsc->aspect;
01882 *p_jx = plsc->jx;
01883 *p_jy = plsc->jy;
01884 }
01885
01886
01887
01888
01889
01890
01891
01892 void
01893 c_plsdiori( PLFLT rot )
01894 {
01895 plsc->diorot = rot;
01896 if ( rot == 0. )
01897 {
01898 plsc->difilt &= ~PLDI_ORI;
01899 pldi_ini();
01900 return;
01901 }
01902
01903 plsc->difilt |= PLDI_ORI;
01904 pldi_ini();
01905 }
01906
01907
01908
01909
01910
01911
01912
01913
01914 static void
01915 calc_diori( void )
01916 {
01917 PLFLT r11, r21, r12, r22, cost, sint;
01918 PLFLT x0, y0, lx, ly, aspect;
01919 PLFLT affine_result[NAFFINE], affine_left[NAFFINE];
01920
01921 if ( plsc->dev_di )
01922 {
01923 char *save_locale = plsave_set_locale();
01924 if ( !plsc->stream_closed )
01925 {
01926 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
01927 PLESC_DI, NULL );
01928 }
01929 plrestore_locale( save_locale );
01930 }
01931
01932 if ( !( plsc->difilt & PLDI_ORI ) )
01933 return;
01934
01935
01936
01937 x0 = ( plsc->phyxma + plsc->phyxmi ) / 2.;
01938 y0 = ( plsc->phyyma + plsc->phyymi ) / 2.;
01939
01940
01941
01942 r11 = cos( plsc->diorot * PI / 2. );
01943 r21 = sin( plsc->diorot * PI / 2. );
01944 r12 = -r21;
01945 r22 = r11;
01946
01947 cost = ABS( r11 );
01948 sint = ABS( r21 );
01949
01950
01951
01952 aspect = plsc->aspect;
01953 if ( aspect == 0. )
01954 aspect = plsc->aspdev;
01955
01956 if ( plsc->freeaspect )
01957 plsc->aspori = aspect;
01958 else
01959 plsc->aspori = ( aspect * cost + sint ) / ( aspect * sint + cost );
01960
01961 if ( !( plsc->difilt & PLDI_DEV ) )
01962 {
01963 plsc->difilt |= PLDI_DEV;
01964 setdef_didev();
01965 }
01966 calc_didev();
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979 lx = plsc->phyxlen;
01980 ly = plsc->phyylen;
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997 plP_affine_translate( affine_result, x0, y0 );
01998 plP_affine_scale( affine_left, lx, ly );
01999 plP_affine_multiply( affine_result, affine_left, affine_result );
02000 plP_affine_rotate( affine_left, plsc->diorot * 90. );
02001 plP_affine_multiply( affine_result, affine_left, affine_result );
02002 plP_affine_scale( affine_left, 1. / lx, 1. / ly );
02003 plP_affine_multiply( affine_result, affine_left, affine_result );
02004 plP_affine_translate( affine_left, -x0, -y0 );
02005 plP_affine_multiply( affine_result, affine_left, affine_result );
02006 plsc->dioxax = affine_result[0];
02007 plsc->dioxay = affine_result[2];
02008 plsc->dioxb = affine_result[4];
02009 plsc->dioyax = affine_result[1];
02010 plsc->dioyay = affine_result[3];
02011 plsc->dioyb = affine_result[5];
02012 }
02013
02014
02015
02016
02017
02018
02019
02020 void
02021 c_plgdiori( PLFLT *p_rot )
02022 {
02023 *p_rot = plsc->diorot;
02024 }
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035 void
02036 c_plsdimap( PLINT dimxmin, PLINT dimxmax, PLINT dimymin, PLINT dimymax,
02037 PLFLT dimxpmm, PLFLT dimypmm )
02038 {
02039 plsetvar( plsc->dimxmin, dimxmin );
02040 plsetvar( plsc->dimxmax, dimxmax );
02041 plsetvar( plsc->dimymin, dimymin );
02042 plsetvar( plsc->dimymax, dimymax );
02043 plsetvar( plsc->dimxpmm, dimxpmm );
02044 plsetvar( plsc->dimypmm, dimypmm );
02045
02046 plsc->difilt |= PLDI_MAP;
02047 pldi_ini();
02048 }
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059 static void
02060 calc_dimap()
02061 {
02062 PLFLT lx, ly;
02063 PLINT pxmin, pxmax, pymin, pymax;
02064 PLFLT dimxlen, dimylen, pxlen, pylen;
02065
02066 if ( ( plsc->dimxmin == plsc->phyxmi ) && ( plsc->dimxmax == plsc->phyxma ) &&
02067 ( plsc->dimymin == plsc->phyymi ) && ( plsc->dimymax == plsc->phyyma ) &&
02068 ( plsc->dimxpmm == plsc->xpmm ) && ( plsc->dimypmm == plsc->ypmm ) )
02069 {
02070 plsc->difilt &= ~PLDI_MAP;
02071 return;
02072 }
02073
02074
02075
02076 lx = ( plsc->dimxmax - plsc->dimxmin + 1 ) / plsc->dimxpmm;
02077 ly = ( plsc->dimymax - plsc->dimymin + 1 ) / plsc->dimypmm;
02078
02079 plsc->aspdev = lx / ly;
02080
02081
02082
02083 dimxlen = plsc->dimxmax - plsc->dimxmin;
02084 dimylen = plsc->dimymax - plsc->dimymin;
02085
02086 pxmin = plsc->phyxmi;
02087 pxmax = plsc->phyxma;
02088 pymin = plsc->phyymi;
02089 pymax = plsc->phyyma;
02090 pxlen = pxmax - pxmin;
02091 pylen = pymax - pymin;
02092
02093 plsc->dimxax = pxlen / dimxlen;
02094 plsc->dimyay = pylen / dimylen;
02095 plsc->dimxb = pxmin - pxlen * plsc->dimxmin / dimxlen;
02096 plsc->dimyb = pymin - pylen * plsc->dimymin / dimylen;
02097 }
02098
02099
02100
02101
02102
02103
02104
02105 void
02106 c_plflush( void )
02107 {
02108 if ( plsc->dev_flush )
02109 {
02110 char *save_locale = plsave_set_locale();
02111 if ( !plsc->stream_closed )
02112 {
02113 ( *plsc->dispatch_table->pl_esc )( (struct PLStream_struct *) plsc,
02114 PLESC_FLUSH, NULL );
02115 }
02116 plrestore_locale( save_locale );
02117 }
02118 else
02119 {
02120 if ( plsc->OutFile != NULL )
02121 fflush( plsc->OutFile );
02122 }
02123 }
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137 void
02138 pllib_init()
02139 {
02140 if ( lib_initialized )
02141 return;
02142 lib_initialized = 1;
02143
02144 #ifdef ENABLE_DYNDRIVERS
02145
02146 lt_dlinit();
02147 #endif
02148
02149
02150
02151
02152 plInitDispatchTable();
02153 }
02154
02155
02156
02157
02158
02159
02160
02161 void
02162 c_plstar( PLINT nx, PLINT ny )
02163 {
02164 pllib_init();
02165
02166 if ( plsc->level != 0 )
02167 plend1();
02168
02169 plssub( nx, ny );
02170
02171 c_plinit();
02172 }
02173
02174
02175
02176
02177
02178
02179
02180 void
02181 c_plstart( const char *devname, PLINT nx, PLINT ny )
02182 {
02183 pllib_init();
02184
02185 if ( plsc->level != 0 )
02186 plend1();
02187
02188 plssub( nx, ny );
02189 plsdev( devname );
02190
02191 c_plinit();
02192 }
02193
02194
02195
02196
02197
02198
02199
02200 void
02201 c_plinit( void )
02202 {
02203 PLFLT def_arrow_x[6] = { -0.5, 0.5, 0.3, 0.5, 0.3, 0.5 };
02204 PLFLT def_arrow_y[6] = { 0.0, 0.0, 0.2, 0.0, -0.2, 0.0 };
02205 PLFLT lx, ly, xpmm_loc, ypmm_loc, aspect_old, aspect_new;
02206 PLINT inc = 0, del = 2000;
02207
02208 pllib_init();
02209
02210 if ( plsc->level != 0 )
02211 plend1();
02212
02213
02214
02215 plsc->ipls = ipls;
02216
02217
02218
02219 pllib_devinit();
02220
02221
02222
02223 plstrm_init();
02224
02225
02226 if ( plsc->plwindow == NULL )
02227 {
02228 if ( plsc->program )
02229 {
02230 if ( ( plsc->plwindow = (char *) malloc( (size_t) ( 1 + strlen( plsc->program ) ) * sizeof ( char ) ) ) == NULL )
02231 {
02232 plexit( "plinit: Insufficient memory" );
02233 }
02234 strcpy( plsc->plwindow, plsc->program );
02235 }
02236 else
02237 {
02238 if ( ( plsc->plwindow = (char *) malloc( (size_t) 7 * sizeof ( char ) ) ) == NULL )
02239 {
02240 plexit( "plinit: Insufficient memory" );
02241 }
02242 strcpy( plsc->plwindow, "PLplot" );
02243 }
02244 }
02245
02246
02247
02248 plP_init();
02249 plP_bop();
02250 plsc->level = 1;
02251
02252
02253
02254
02255
02256
02257
02258
02259 plP_FreeDrvOpts();
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269 if ( plsc->aspect > 0. )
02270 {
02271 lx = plsc->phyxlen / plsc->xpmm;
02272 ly = plsc->phyylen / plsc->ypmm;
02273 aspect_old = lx / ly;
02274 aspect_new = plsc->aspect;
02275 plsc->caspfactor = sqrt( aspect_old / aspect_new );
02276 }
02277
02278
02279 else if ( plsc->freeaspect && ABS( cos( plsc->diorot * PI / 2. ) ) <= 1.e-5 )
02280 {
02281 lx = plsc->phyxlen / plsc->xpmm;
02282 ly = plsc->phyylen / plsc->ypmm;
02283 aspect_old = lx / ly;
02284 aspect_new = ly / lx;
02285 plsc->caspfactor = sqrt( aspect_old / aspect_new );
02286 }
02287
02288 else
02289 plsc->caspfactor = 1.;
02290
02291
02292
02293 plsc->cfont = 1;
02294 plfntld( initfont );
02295
02296
02297
02298 plP_subpInit();
02299
02300
02301
02302
02303 if ( plsc->xdigmax == 0 )
02304 plsc->xdigmax = 4;
02305
02306 if ( plsc->ydigmax == 0 )
02307 plsc->ydigmax = 4;
02308
02309 if ( plsc->zdigmax == 0 )
02310 plsc->zdigmax = 3;
02311
02312 if ( plsc->timefmt == NULL )
02313 c_pltimefmt( "%c" );
02314
02315
02316
02317
02318 if ( plsc->qsasconfig == NULL )
02319 c_plconfigtime( 0., 0., 0., 0x0, 0, 0, 0, 0, 0, 0, 0. );
02320
02321
02322
02323 plgra();
02324 plcol0( 1 );
02325
02326 pllsty( 1 );
02327 plpat( 1, &inc, &del );
02328
02329 plsvect( def_arrow_x, def_arrow_y, 6, 0 );
02330
02331
02332
02333 plsc->clpxmi = plsc->phyxmi;
02334 plsc->clpxma = plsc->phyxma;
02335 plsc->clpymi = plsc->phyymi;
02336 plsc->clpyma = plsc->phyyma;
02337
02338
02339
02340 lx = plsc->phyxlen / plsc->xpmm;
02341 ly = plsc->phyylen / plsc->ypmm;
02342 plsc->aspdev = lx / ly;
02343
02344
02345
02346 pldi_ini();
02347
02348
02349
02350
02351
02352
02353
02354 plP_gpixmm( &xpmm_loc, &ypmm_loc );
02355 plP_setpxl( xpmm_loc * plsc->caspfactor, ypmm_loc / plsc->caspfactor );
02356 }
02357
02358
02359
02360
02361
02362
02363
02364 void
02365 c_plend( void )
02366 {
02367 PLINT i;
02368
02369 if ( lib_initialized == 0 )
02370 return;
02371
02372 for ( i = PL_NSTREAMS - 1; i >= 0; i-- )
02373 {
02374 if ( pls[i] != NULL )
02375 {
02376 plsstrm( i );
02377 c_plend1();
02378 }
02379 }
02380 plfontrel();
02381 #ifdef ENABLE_DYNDRIVERS
02382
02383 lt_dlexit();
02384
02385 for ( i = 0; i < npldynamicdevices; i++ )
02386 {
02387 free_mem( loadable_device_list[i].devnam );
02388 free_mem( loadable_device_list[i].description );
02389 free_mem( loadable_device_list[i].drvnam );
02390 free_mem( loadable_device_list[i].tag );
02391 }
02392 free_mem( loadable_device_list );
02393 for ( i = 0; i < nloadabledrivers; i++ )
02394 {
02395 free_mem( loadable_driver_list[i].drvnam );
02396 }
02397 free_mem( loadable_driver_list );
02398 for ( i = nplstaticdevices; i < npldrivers; i++ )
02399 {
02400 free_mem( dispatch_table[i]->pl_MenuStr );
02401 free_mem( dispatch_table[i]->pl_DevName );
02402 free_mem( dispatch_table[i] );
02403 }
02404 #endif
02405 for ( i = 0; i < nplstaticdevices; i++ )
02406 {
02407 free_mem( dispatch_table[i] );
02408 }
02409 free_mem( dispatch_table );
02410
02411 lib_initialized = 0;
02412 }
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422 void
02423 c_plend1( void )
02424 {
02425 if ( plsc->level > 0 )
02426 {
02427 plP_eop();
02428 plP_tidy();
02429 plsc->level = 0;
02430 }
02431
02432 if ( plsc->FileName )
02433 free_mem( plsc->FileName );
02434
02435
02436
02437 free_mem( plsc->cmap0 );
02438 free_mem( plsc->cmap1 );
02439 free_mem( plsc->plwindow );
02440 free_mem( plsc->geometry );
02441 free_mem( plsc->dev );
02442 free_mem( plsc->BaseName );
02443 #ifndef BUFFERED_FILE
02444 free_mem( plsc->plbuf_buffer );
02445 #endif
02446 if ( plsc->program )
02447 free_mem( plsc->program );
02448 if ( plsc->server_name )
02449 free_mem( plsc->server_name );
02450 if ( plsc->server_host )
02451 free_mem( plsc->server_host );
02452 if ( plsc->server_port )
02453 free_mem( plsc->server_port );
02454 if ( plsc->user )
02455 free_mem( plsc->user );
02456 if ( plsc->plserver )
02457 free_mem( plsc->plserver );
02458 if ( plsc->auto_path )
02459 free_mem( plsc->auto_path );
02460
02461 if ( plsc->arrow_x )
02462 free_mem( plsc->arrow_x );
02463 if ( plsc->arrow_y )
02464 free_mem( plsc->arrow_y );
02465
02466 if ( plsc->timefmt )
02467 free_mem( plsc->timefmt );
02468
02469
02470
02471
02472 closeqsas( &( plsc->qsasconfig ) );
02473
02474
02475
02476 if ( ipls > 0 )
02477 {
02478 free_mem( plsc );
02479 pls[ipls] = NULL;
02480 plsstrm( 0 );
02481 }
02482 else
02483 {
02484 memset( (char *) pls[ipls], 0, sizeof ( PLStream ) );
02485 }
02486 }
02487
02488
02489
02490
02491
02492
02493
02494
02495 void
02496 c_plsstrm( PLINT strm )
02497 {
02498 if ( strm < 0 || strm >= PL_NSTREAMS )
02499 {
02500 fprintf( stderr,
02501 "plsstrm: Illegal stream number %d, must be in [0, %d]\n",
02502 (int) strm, PL_NSTREAMS );
02503 }
02504 else
02505 {
02506 ipls = strm;
02507 if ( pls[ipls] == NULL )
02508 {
02509 pls[ipls] = (PLStream *) malloc( (size_t) sizeof ( PLStream ) );
02510 if ( pls[ipls] == NULL )
02511 plexit( "plsstrm: Out of memory." );
02512
02513 memset( (char *) pls[ipls], 0, sizeof ( PLStream ) );
02514 }
02515 plsc = pls[ipls];
02516 plsc->ipls = ipls;
02517 }
02518 }
02519
02520
02521
02522
02523
02524
02525
02526 void
02527 c_plgstrm( PLINT *p_strm )
02528 {
02529 *p_strm = ipls;
02530 }
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545 void
02546 c_plmkstrm( PLINT *p_strm )
02547 {
02548 int i;
02549
02550 for ( i = 1; i < PL_NSTREAMS; i++ )
02551 {
02552 if ( pls[i] == NULL )
02553 break;
02554 }
02555
02556 if ( i == PL_NSTREAMS )
02557 {
02558 fprintf( stderr, "plmkstrm: Cannot create new stream\n" );
02559 *p_strm = -1;
02560 }
02561 else
02562 {
02563 *p_strm = i;
02564 plsstrm( i );
02565 }
02566 plstrm_init();
02567 }
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585 void
02586 plstrm_init( void )
02587 {
02588 if ( !plsc->initialized )
02589 {
02590 plsc->initialized = 1;
02591
02592 if ( plsc->cmap0 == NULL )
02593 plspal0( "" );
02594
02595 if ( plsc->cmap1 == NULL )
02596 plspal1( "", TRUE );
02597
02598
02599 plsc->cmap1_min = 0.0;
02600 plsc->cmap1_max = 1.0;
02601 }
02602
02603 plsc->psdoc = NULL;
02604 }
02605
02606
02607
02608
02609
02610
02611
02612 void
02613 pl_cpcolor( PLColor *to, PLColor *from )
02614 {
02615 to->r = from->r;
02616 to->g = from->g;
02617 to->b = from->b;
02618 to->a = from->a;
02619 }
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635 void
02636 c_plcpstrm( PLINT iplsr, PLINT flags )
02637 {
02638 int i;
02639 PLStream *plsr;
02640
02641 plsr = pls[iplsr];
02642 if ( plsr == NULL )
02643 {
02644 fprintf( stderr, "plcpstrm: stream %d not in use\n", (int) iplsr );
02645 return;
02646 }
02647
02648
02649
02650 plsc->debug = plsr->debug;
02651
02652
02653
02654
02655 #ifdef BUFFERED_FILE
02656 plsc->plbufFile = plsr->plbufFile;
02657 #else
02658 plsc->plbuf_buffer_grow = plsr->plbuf_buffer_grow;
02659 plsc->plbuf_buffer_size = plsr->plbuf_buffer_size;
02660 plsc->plbuf_top = plsr->plbuf_top;
02661 plsc->plbuf_readpos = plsr->plbuf_readpos;
02662 if ( ( plsc->plbuf_buffer = malloc( plsc->plbuf_buffer_size ) ) == NULL )
02663 plexit( "plcpstrm: Error allocating plot buffer." );
02664 memcpy( plsc->plbuf_buffer, plsr->plbuf_buffer, plsr->plbuf_top );
02665 #endif
02666
02667
02668
02669
02670 if ( plsr->difilt & PLDI_PLT )
02671 plsdiplt( plsr->dipxmin, plsr->dipymin, plsr->dipxmax, plsr->dipymax );
02672
02673 if ( plsr->difilt & PLDI_DEV )
02674 plsdidev( plsr->mar, plsr->aspect, plsr->jx, plsr->jy );
02675
02676 if ( plsr->difilt & PLDI_ORI )
02677 plsdiori( plsr->diorot );
02678
02679
02680
02681 if ( !( flags & 0x01 ) )
02682 {
02683 pldebug( "plcpstrm", "mapping parameters: %d %d %d %d %f %f\n",
02684 plsr->phyxmi, plsr->phyxma, plsr->phyymi, plsr->phyyma,
02685 plsr->xpmm, plsr->ypmm );
02686 plsdimap( plsr->phyxmi, plsr->phyxma, plsr->phyymi, plsr->phyyma,
02687 plsr->xpmm, plsr->ypmm );
02688 }
02689
02690
02691
02692 pl_cpcolor( &plsc->curcolor, &plsr->curcolor );
02693
02694
02695
02696 plsc->icol0 = plsr->icol0;
02697 plsc->ncol0 = plsr->ncol0;
02698 if ( plsc->cmap0 != NULL )
02699 free( (void *) plsc->cmap0 );
02700
02701 if ( ( plsc->cmap0 = (PLColor *) calloc( 1, plsc->ncol0 * sizeof ( PLColor ) ) ) == NULL )
02702 {
02703 plexit( "c_plcpstrm: Insufficient memory" );
02704 }
02705
02706 for ( i = 0; i < plsc->ncol0; i++ )
02707 pl_cpcolor( &plsc->cmap0[i], &plsr->cmap0[i] );
02708
02709
02710
02711 plsc->icol1 = plsr->icol1;
02712 plsc->ncol1 = plsr->ncol1;
02713 plsc->cmap1_min = plsr->cmap1_min;
02714 plsc->cmap1_max = plsr->cmap1_max;
02715 if ( plsc->cmap1 != NULL )
02716 free( (void *) plsc->cmap1 );
02717
02718 if ( ( plsc->cmap1 = (PLColor *) calloc( 1, plsc->ncol1 * sizeof ( PLColor ) ) ) == NULL )
02719 {
02720 plexit( "c_plcpstrm: Insufficient memory" );
02721 }
02722
02723 for ( i = 0; i < plsc->ncol1; i++ )
02724 pl_cpcolor( &plsc->cmap1[i], &plsr->cmap1[i] );
02725
02726
02727
02728 if ( plsc->level == 0 )
02729 plinit();
02730 }
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753 void
02754 pllib_devinit()
02755 {
02756 if ( plsc->dev_initialized )
02757 return;
02758 plsc->dev_initialized = 1;
02759
02760 plSelectDev();
02761
02762 plLoadDriver();
02763
02764
02765 plsc->dispatch_table = dispatch_table[plsc->device - 1];
02766 }
02767
02768 PLDLLIMPEXP int plInBuildTree()
02769 {
02770 static int inited = 0;
02771 static int inBuildTree = 0;
02772
02773 if ( inited == 0 )
02774 {
02775 char currdir[PLPLOT_MAX_PATH];
02776 char builddir[PLPLOT_MAX_PATH];
02777
02778 if ( getcwd( currdir, PLPLOT_MAX_PATH ) == NULL )
02779 {
02780 pldebug( "plInBuildTree():", "Not enough buffer space" );
02781 }
02782 else
02783 {
02784
02785
02786
02787 if ( chdir( BUILD_DIR ) == 0 )
02788 {
02789 if ( getcwd( builddir, PLPLOT_MAX_PATH ) == NULL )
02790 {
02791 pldebug( "plInBuildTree():", "Not enough buffer space" );
02792 }
02793 else
02794 {
02795
02796 if ( strncmp( builddir + 1, currdir + 1, strlen( builddir + 1 ) ) == 0 &&
02797 tolower( builddir[0] ) == tolower( currdir[0] ) )
02798 {
02799 inBuildTree = 1;
02800 }
02801 }
02802 if ( chdir( currdir ) != 0 )
02803 pldebug( "plInBuildTree():", "Unable to chdir to current directory" );
02804 }
02805 }
02806 inited = 1;
02807 }
02808 return inBuildTree;
02809 }
02810
02811 #ifdef ENABLE_DYNDRIVERS
02812
02813 char*
02814 plGetDrvDir()
02815 {
02816 char* drvdir;
02817
02818
02819
02820
02821
02822 if ( plInBuildTree() == 1 )
02823 {
02824 drvdir = BUILD_DIR "/drivers";
02825 pldebug( "plGetDrvDir", "Using %s as the driver directory.\n", drvdir );
02826 }
02827 else
02828 {
02829 pldebug( "plGetDrvDir", "Trying to read env var PLPLOT_DRV_DIR\n" );
02830 drvdir = getenv( "PLPLOT_DRV_DIR" );
02831
02832 if ( drvdir == NULL )
02833 {
02834 pldebug( "plGetDrvDir",
02835 "Will use drivers dir: " DRV_DIR "\n" );
02836 drvdir = DRV_DIR;
02837 }
02838 }
02839
02840 return drvdir;
02841 }
02842
02843 #endif
02844
02845
02846
02847
02848
02849
02850
02851
02852 static int plDispatchSequencer( const void *p1, const void *p2 )
02853 {
02854 const PLDispatchTable* t1 = *(PLDispatchTable **) p1;
02855 const PLDispatchTable* t2 = *(PLDispatchTable **) p2;
02856
02857
02858
02859
02860 return t1->pl_seq - t2->pl_seq;
02861 }
02862
02863 static void
02864 plInitDispatchTable()
02865 {
02866 int n;
02867
02868 #ifdef ENABLE_DYNDRIVERS
02869 char buf[BUFFER2_SIZE];
02870 char * drvdir;
02871 char *devnam, *devdesc, *devtype, *driver, *tag, *seqstr;
02872 int seq;
02873 int i, j, driver_found, done = 0;
02874 FILE *fp_drvdb = NULL;
02875 DIR * dp_drvdir = NULL;
02876 struct dirent* entry;
02877
02878
02879
02880 npldynamicdevices = 0;
02881 nloadabledrivers = 0;
02882
02883
02884
02885 fp_drvdb = pl_create_tempfile( NULL );
02886 if ( fp_drvdb == NULL )
02887 {
02888 plabort( "plInitDispatchTable: Could not open temporary file" );
02889 return;
02890 }
02891
02892
02893 drvdir = plGetDrvDir();
02894 dp_drvdir = opendir( drvdir );
02895 if ( dp_drvdir == NULL )
02896 {
02897 fclose( fp_drvdb );
02898 plabort( "plInitDispatchTable: Could not open drivers directory" );
02899 return;
02900 }
02901
02902
02903
02904 pldebug( "plInitDispatchTable", "Scanning dyndrivers dir\n" );
02905 while ( ( entry = readdir( dp_drvdir ) ) != NULL )
02906 {
02907 char* name = entry->d_name;
02908
02909 int len = strlen( name ) - 12;
02910
02911 pldebug( "plInitDispatchTable",
02912 "Consider file %s\n", name );
02913
02914
02915 if ( ( len > 0 ) && ( strcmp( name + len, ".driver_info" ) == 0 ) )
02916 {
02917 char path[PLPLOT_MAX_PATH];
02918 FILE * fd;
02919
02920
02921 snprintf( path, PLPLOT_MAX_PATH, "%s/%s", drvdir, name );
02922 fd = fopen( path, "r" );
02923 if ( fd == NULL )
02924 {
02925 closedir( dp_drvdir );
02926 fclose( fp_drvdb );
02927 snprintf( buf, BUFFER2_SIZE,
02928 "plInitDispatchTable: Could not open driver info file %s\n",
02929 name );
02930 plabort( buf );
02931 return;
02932 }
02933
02934
02935
02936
02937
02938 pldebug( "plInitDispatchTable",
02939 "Opened driver info file %s\n", name );
02940 while ( fgets( buf, BUFFER2_SIZE, fd ) != NULL )
02941 {
02942 fprintf( fp_drvdb, "%s", buf );
02943 if ( buf [strlen( buf ) - 1] != '\n' )
02944 fprintf( fp_drvdb, "\n" );
02945 npldynamicdevices++;
02946 }
02947 fclose( fd );
02948 }
02949 }
02950
02951
02952
02953 fflush( fp_drvdb );
02954 closedir( dp_drvdir );
02955
02956 #endif
02957
02958
02959 if ( ( dispatch_table = (PLDispatchTable **)
02960 malloc( ( nplstaticdevices + npldynamicdevices ) * sizeof ( PLDispatchTable * ) ) ) == NULL )
02961 {
02962 #ifdef ENABLE_DYNDRIVERS
02963 fclose( fp_drvdb );
02964 #endif
02965 plexit( "plInitDispatchTable: Insufficient memory" );
02966 }
02967
02968
02969
02970
02971
02972
02973 for ( n = 0; n < nplstaticdevices; n++ )
02974 {
02975 if ( ( dispatch_table[n] = (PLDispatchTable *) malloc( sizeof ( PLDispatchTable ) ) ) == NULL )
02976 {
02977 #ifdef ENABLE_DYNDRIVERS
02978 fclose( fp_drvdb );
02979 #endif
02980 plexit( "plInitDispatchTable: Insufficient memory" );
02981 }
02982
02983 ( *static_device_initializers[n] )( dispatch_table[n] );
02984 }
02985 npldrivers = nplstaticdevices;
02986
02987 #ifdef ENABLE_DYNDRIVERS
02988
02989
02990
02991
02992 if ( ( ( loadable_device_list = malloc( npldynamicdevices * sizeof ( PLLoadableDevice ) ) ) == NULL ) ||
02993 ( ( loadable_driver_list = malloc( npldynamicdevices * sizeof ( PLLoadableDriver ) ) ) == NULL ) )
02994 {
02995 fclose( fp_drvdb );
02996 plexit( "plInitDispatchTable: Insufficient memory" );
02997 }
02998
02999 rewind( fp_drvdb );
03000
03001 i = 0;
03002 done = !( i < npldynamicdevices );
03003 while ( !done )
03004 {
03005 char *p = fgets( buf, BUFFER2_SIZE, fp_drvdb );
03006
03007 if ( p == 0 )
03008 {
03009 done = 1;
03010 continue;
03011 }
03012
03013 devnam = strtok( buf, ":" );
03014 devdesc = strtok( 0, ":" );
03015 devtype = strtok( 0, ":" );
03016 driver = strtok( 0, ":" );
03017 seqstr = strtok( 0, ":" );
03018 tag = strtok( 0, "\n" );
03019
03020 if ( devnam == NULL || devdesc == NULL || devtype == NULL || driver == NULL ||
03021 seqstr == NULL || tag == NULL )
03022 {
03023 continue;
03024 }
03025
03026 seq = atoi( seqstr );
03027
03028 n = npldrivers++;
03029
03030 if ( ( dispatch_table[n] = malloc( sizeof ( PLDispatchTable ) ) ) == NULL )
03031 {
03032 fclose( fp_drvdb );
03033 plexit( "plInitDispatchTable: Insufficient memory" );
03034 }
03035
03036
03037 dispatch_table[n]->pl_MenuStr = plstrdup( devdesc );
03038 dispatch_table[n]->pl_DevName = plstrdup( devnam );
03039 dispatch_table[n]->pl_type = atoi( devtype );
03040 dispatch_table[n]->pl_seq = seq;
03041 dispatch_table[n]->pl_init = 0;
03042 dispatch_table[n]->pl_line = 0;
03043 dispatch_table[n]->pl_polyline = 0;
03044 dispatch_table[n]->pl_eop = 0;
03045 dispatch_table[n]->pl_bop = 0;
03046 dispatch_table[n]->pl_tidy = 0;
03047 dispatch_table[n]->pl_state = 0;
03048 dispatch_table[n]->pl_esc = 0;
03049
03050
03051 loadable_device_list[i].devnam = plstrdup( devnam );
03052 loadable_device_list[i].description = plstrdup( devdesc );
03053 loadable_device_list[i].drvnam = plstrdup( driver );
03054 loadable_device_list[i].tag = plstrdup( tag );
03055
03056
03057
03058 driver_found = 0;
03059 for ( j = 0; j < nloadabledrivers; j++ )
03060 if ( strcmp( driver, loadable_driver_list[j].drvnam ) == 0 )
03061 {
03062 driver_found = 1;
03063 break;
03064 }
03065
03066 if ( !driver_found )
03067 {
03068 loadable_driver_list[nloadabledrivers].drvnam = plstrdup( driver );
03069 loadable_driver_list[nloadabledrivers].dlhand = 0;
03070 nloadabledrivers++;
03071 }
03072
03073 loadable_device_list[i].drvidx = j;
03074
03075
03076 i++;
03077 }
03078
03079
03080 fclose( fp_drvdb );
03081
03082 #endif
03083
03084 if ( npldrivers == 0 )
03085 {
03086 npldynamicdevices = 0;
03087 plexit( "No device drivers found - please check the environment variable PLPLOT_DRV_DIR" );
03088 }
03089
03090
03091
03092
03093 qsort( dispatch_table, npldrivers, sizeof ( PLDispatchTable* ),
03094 plDispatchSequencer );
03095 }
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108 static void
03109 plSelectDev()
03110 {
03111 int dev, i, count, length;
03112 char response[80];
03113 char * devname_env;
03114
03115
03116
03117 if ( plsc->DevName[0] == '\0' )
03118 {
03119 devname_env = getenv( "PLPLOT_DEV" );
03120 if ( devname_env )
03121 {
03122 strncpy( plsc->DevName, devname_env, sizeof ( plsc->DevName ) - 1 );
03123 plsc->DevName[sizeof ( plsc->DevName ) - 1] = '\0';
03124 }
03125 }
03126
03127
03128
03129 if ( *( plsc->DevName ) != '\0' && *( plsc->DevName ) != '?' )
03130 {
03131 length = strlen( plsc->DevName );
03132 for ( i = 0; i < npldrivers; i++ )
03133 {
03134 if ( ( *plsc->DevName == *dispatch_table[i]->pl_DevName ) &&
03135 ( strncmp( plsc->DevName,
03136 dispatch_table[i]->pl_DevName, length ) == 0 ) )
03137 break;
03138 }
03139 if ( i < npldrivers )
03140 {
03141 plsc->device = i + 1;
03142 return;
03143 }
03144 else
03145 {
03146 fprintf( stderr, "Requested device %s not available\n",
03147 plsc->DevName );
03148 }
03149 }
03150
03151 dev = 0;
03152 count = 0;
03153
03154 if ( npldrivers == 1 )
03155 dev = 1;
03156
03157
03158
03159 while ( dev < 1 || dev > npldrivers )
03160 {
03161 fprintf( stdout, "\nPlotting Options:\n" );
03162 for ( i = 0; i < npldrivers; i++ )
03163 {
03164 fprintf( stdout, " <%2d> %-10s %s\n", i + 1,
03165 dispatch_table[i]->pl_DevName,
03166 dispatch_table[i]->pl_MenuStr );
03167 }
03168 if ( ipls == 0 )
03169 fprintf( stdout, "\nEnter device number or keyword: " );
03170 else
03171 fprintf( stdout, "\nEnter device number or keyword (stream %d): ",
03172 (int) ipls );
03173
03174 plio_fgets( response, sizeof ( response ), stdin );
03175
03176
03177
03178
03179 length = strlen( response );
03180 if ( *( response - 1 + length ) == '\n' )
03181 length--;
03182
03183 for ( i = 0; i < npldrivers; i++ )
03184 {
03185 if ( !strncmp( response, dispatch_table[i]->pl_DevName,
03186 (unsigned int) length ) )
03187 break;
03188 }
03189 if ( i < npldrivers )
03190 {
03191 dev = i + 1;
03192 }
03193 else
03194 {
03195 if ( ( dev = atoi( response ) ) < 1 )
03196 {
03197 fprintf( stdout, "\nInvalid device: %s", response );
03198 dev = 0;
03199 }
03200 }
03201 if ( count++ > 10 )
03202 plexit( "plSelectDev: Too many tries." );
03203 }
03204 plsc->device = dev;
03205 strcpy( plsc->DevName, dispatch_table[dev - 1]->pl_DevName );
03206 }
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216 static void
03217 plLoadDriver( void )
03218 {
03219 #ifdef ENABLE_DYNDRIVERS
03220 int i, drvidx;
03221 char sym[BUFFER_SIZE];
03222 char *tag;
03223
03224 int n = plsc->device - 1;
03225 PLDispatchTable *dev = dispatch_table[n];
03226 PLLoadableDriver *driver = 0;
03227
03228
03229
03230
03231 if ( dev->pl_init )
03232 return;
03233
03234 pldebug( "plLoadDriver", "Device not loaded!\n" );
03235
03236
03237
03238 for ( i = 0; i < npldynamicdevices; i++ )
03239 if ( strcmp( dev->pl_DevName, loadable_device_list[i].devnam ) == 0 )
03240 break;
03241
03242
03243
03244
03245 if ( i == npldynamicdevices )
03246 {
03247 fprintf( stderr, "No such device: %s.\n", dev->pl_DevName );
03248 plexit( "plLoadDriver detected device logic screwup" );
03249 }
03250
03251
03252
03253
03254 tag = loadable_device_list[i].tag;
03255 drvidx = loadable_device_list[i].drvidx;
03256
03257 pldebug( "plLoadDriver", "tag=%s, drvidx=%d\n", tag, drvidx );
03258
03259 driver = &loadable_driver_list[drvidx];
03260
03261
03262 if ( !driver->dlhand )
03263 {
03264 char drvspec[ DRVSPEC_SIZE ];
03265 #if defined ( LTDL_WIN32 ) || defined ( __CYGWIN__ )
03266 snprintf( drvspec, DRVSPEC_SIZE, "%s", driver->drvnam );
03267 #else
03268 snprintf( drvspec, DRVSPEC_SIZE, "%s/%s", plGetDrvDir(), driver->drvnam );
03269 #endif // LTDL_WIN32
03270
03271 pldebug( "plLoadDriver", "Trying to load %s on %s\n",
03272 driver->drvnam, drvspec );
03273
03274 driver->dlhand = lt_dlopenext( drvspec );
03275
03276
03277
03278
03279
03280
03281
03282
03283 if ( !( strcmp( driver->drvnam, "mem" ) == 0 ||
03284 strcmp( driver->drvnam, "null" ) == 0 ||
03285 strcmp( driver->drvnam, "plmeta" ) == 0 ||
03286 strcmp( driver->drvnam, "ps" ) == 0 ||
03287 strcmp( driver->drvnam, "svg" ) == 0 ||
03288 strcmp( driver->drvnam, "xfig" ) == 0 ) )
03289 lt_dlmakeresident( driver->dlhand );
03290 }
03291
03292
03293 if ( !driver->dlhand )
03294 {
03295 pldebug( "plLoadDriver", "lt_dlopenext failed because of "
03296 "the following reason:\n%s\n", lt_dlerror() );
03297 fprintf( stderr, "Unable to load driver: %s.\n", driver->drvnam );
03298 plexit( "Unable to load driver" );
03299 }
03300
03301
03302
03303
03304 snprintf( sym, BUFFER_SIZE, "plD_dispatch_init_%s", tag );
03305 {
03306 PLDispatchInit dispatch_init = (PLDispatchInit) lt_dlsym( driver->dlhand, sym );
03307 if ( !dispatch_init )
03308 {
03309 fprintf( stderr,
03310 "Unable to locate dispatch table initialization function for driver: %s.\n",
03311 driver->drvnam );
03312 return;
03313 }
03314
03315 ( *dispatch_init )( dev );
03316 }
03317 #endif
03318 }
03319
03320
03321
03322
03323
03324
03325
03326 void
03327 c_plfontld( PLINT ifont )
03328 {
03329 if ( ifont != 0 )
03330 ifont = 1;
03331
03332 if ( plsc->level > 0 )
03333 plfntld( ifont );
03334 else
03335 initfont = ifont;
03336 }
03337
03338
03339
03340
03341
03342
03343
03344 void
03345 c_plreplot( void )
03346 {
03347 #ifdef BUFFERED_FILE
03348 if ( plsc->plbufFile != NULL )
03349 {
03350 #else
03351 if ( plsc->plbuf_buffer != NULL )
03352 {
03353 #endif
03354 plRemakePlot( plsc );
03355 }
03356 else
03357 {
03358 plwarn( "plreplot: plot buffer not available" );
03359 }
03360 }
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373 void
03374 plgFileDevs( const char ***p_menustr, const char ***p_devname, int *p_ndev )
03375 {
03376 plgdevlst( *p_menustr, *p_devname, p_ndev, 0 );
03377 }
03378
03379
03380
03381
03382
03383
03384
03385 void
03386 plgDevs( const char ***p_menustr, const char ***p_devname, int *p_ndev )
03387 {
03388 plgdevlst( *p_menustr, *p_devname, p_ndev, -1 );
03389 }
03390
03391 static void
03392 plgdevlst( const char **p_menustr, const char **p_devname, int *p_ndev, int type )
03393 {
03394 int i, j;
03395
03396 pllib_init();
03397
03398 for ( i = j = 0; i < npldrivers; i++ )
03399 {
03400 if ( type < 0 || dispatch_table[i]->pl_type == type )
03401 {
03402 p_menustr[j] = dispatch_table[i]->pl_MenuStr;
03403 p_devname[j] = dispatch_table[i]->pl_DevName;
03404 if ( ++j + 1 >= *p_ndev )
03405 {
03406 plwarn( "plgdevlst: too many devices" );
03407 break;
03408 }
03409 }
03410 }
03411 p_menustr[j] = NULL;
03412 p_devname[j] = NULL;
03413 *p_ndev = j;
03414 }
03415
03416
03417
03418
03419
03420
03421
03422 void
03423 c_plgpage( PLFLT *p_xp, PLFLT *p_yp,
03424 PLINT *p_xleng, PLINT *p_yleng, PLINT *p_xoff, PLINT *p_yoff )
03425 {
03426 *p_xp = plsc->xdpi;
03427 *p_yp = plsc->ydpi;
03428 *p_xleng = plsc->xlength;
03429 *p_yleng = plsc->ylength;
03430 *p_xoff = plsc->xoffset;
03431 *p_yoff = plsc->yoffset;
03432 }
03433
03434
03435
03436 void
03437 c_plspage( PLFLT xp, PLFLT yp, PLINT xleng, PLINT yleng, PLINT xoff, PLINT yoff )
03438 {
03439 if ( plsc->level > 0 )
03440 plwarn( "calling plspage() after plinit() may give unpredictable results" );
03441
03442 if ( xp )
03443 plsc->xdpi = xp;
03444 if ( yp )
03445 plsc->ydpi = yp;
03446
03447 if ( xleng )
03448 plsc->xlength = xleng;
03449 if ( yleng )
03450 plsc->ylength = yleng;
03451
03452 if ( xoff )
03453 plsc->xoffset = xoff;
03454 if ( yoff )
03455 plsc->yoffset = yoff;
03456
03457 plsc->pageset = 1;
03458 }
03459
03460
03461
03462 void
03463 c_plssub( PLINT nx, PLINT ny )
03464 {
03465 if ( nx > 0 )
03466 plsc->nsubx = nx;
03467 if ( ny > 0 )
03468 plsc->nsuby = ny;
03469
03470
03471
03472 if ( plsc->level > 0 )
03473 {
03474 plP_subpInit();
03475
03476
03477 }
03478 }
03479
03480
03481
03482 void
03483 c_plsdev( const char *devname )
03484 {
03485 if ( plsc->level > 0 )
03486 {
03487 plwarn( "plsdev: Must be called before plinit." );
03488 return;
03489 }
03490 if ( devname != NULL )
03491 {
03492 strncpy( plsc->DevName, devname, sizeof ( plsc->DevName ) - 1 );
03493 plsc->DevName[sizeof ( plsc->DevName ) - 1] = '\0';
03494 }
03495 }
03496
03497
03498
03499
03500 void
03501 c_plgdev( char *p_dev )
03502 {
03503 strcpy( p_dev, plsc->DevName );
03504 }
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515 void
03516 c_plsmem( PLINT maxx, PLINT maxy, void *plotmem )
03517 {
03518 plsc->dev = plotmem;
03519 plsc->dev_mem_alpha = 0;
03520 plP_setphy( 0, maxx, 0, maxy );
03521 }
03522
03523
03524
03525 void
03526 c_plsmema( PLINT maxx, PLINT maxy, void *plotmem )
03527 {
03528 plsc->dev = plotmem;
03529 plsc->dev_mem_alpha = 1;
03530 plP_setphy( 0, maxx, 0, maxy );
03531 }
03532
03533
03534
03535 void
03536 plgpls( PLStream **p_pls )
03537 {
03538 *p_pls = plsc;
03539 }
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549 void
03550 c_plglevel( PLINT *p_level )
03551 {
03552 *p_level = plsc->level;
03553 }
03554
03555
03556
03557 void
03558 plsKeyEH( void ( *KeyEH )( PLGraphicsIn *, void *, int * ),
03559 void *KeyEH_data )
03560 {
03561 plsc->KeyEH = KeyEH;
03562 plsc->KeyEH_data = KeyEH_data;
03563 }
03564
03565
03566
03567 void
03568 plsButtonEH( void ( *ButtonEH )( PLGraphicsIn *, void *, int * ),
03569 void *ButtonEH_data )
03570 {
03571 plsc->ButtonEH = ButtonEH;
03572 plsc->ButtonEH_data = ButtonEH_data;
03573 }
03574
03575
03576
03577 void
03578 plsbopH( void ( *handler )( void *, int * ), void *handler_data )
03579 {
03580 plsc->bop_handler = handler;
03581 plsc->bop_data = handler_data;
03582 }
03583
03584
03585
03586 void
03587 plseopH( void ( *handler )( void *, int * ), void *handler_data )
03588 {
03589 plsc->eop_handler = handler;
03590 plsc->eop_data = handler_data;
03591 }
03592
03593
03594
03595 void
03596 plsError( PLINT *errcode, char *errmsg )
03597 {
03598 if ( errcode != NULL )
03599 plsc->errcode = errcode;
03600
03601 if ( errmsg != NULL )
03602 plsc->errmsg = errmsg;
03603 }
03604
03605
03606
03607 void
03608 c_plsori( PLINT ori )
03609 {
03610 plsdiori( (PLFLT) ori );
03611 }
03612
03613
03614
03615
03616
03617
03618
03619 void
03620 c_plwid( PLINT width )
03621 {
03622 if ( width != plsc->width && width >= 0 )
03623 {
03624 plsc->width = width;
03625
03626 if ( plsc->level > 0 )
03627 {
03628 if ( !plsc->widthlock )
03629 plP_state( PLSTATE_WIDTH );
03630 }
03631 }
03632 }
03633
03634
03635
03636 void
03637 plgfile( FILE **p_file )
03638 {
03639 *p_file = plsc->OutFile;
03640 }
03641
03642
03643
03644 void
03645 plsfile( FILE *file )
03646 {
03647 plsc->OutFile = file;
03648 }
03649
03650
03651
03652
03653 void
03654 c_plgfnam( char *fnam )
03655 {
03656 if ( fnam == NULL )
03657 {
03658 plabort( "filename string must be preallocated to >=80 bytes" );
03659 return;
03660 }
03661
03662 *fnam = '\0';
03663 if ( plsc->FileName != NULL )
03664 {
03665 strncpy( fnam, plsc->FileName, 79 );
03666 fnam[79] = '\0';
03667 }
03668 }
03669
03670
03671
03672 void
03673 c_plsfnam( const char *fnam )
03674 {
03675 plP_sfnam( plsc, fnam );
03676 }
03677
03678
03679
03680 void
03681 c_plspause( PLINT pause )
03682 {
03683 plsc->nopause = !pause;
03684 }
03685
03686
03687
03688 void
03689 c_plprec( PLINT setp, PLINT prec )
03690 {
03691 plsc->setpre = setp;
03692 plsc->precis = prec;
03693 }
03694
03695
03696
03697 void
03698 plP_gprec( PLINT *p_setp, PLINT *p_prec )
03699 {
03700 *p_setp = plsc->setpre;
03701 *p_prec = plsc->precis;
03702 }
03703
03704 const char *
03705 plP_gtimefmt()
03706 {
03707 return (const char *) plsc->timefmt;
03708 }
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718 void
03719 c_plsesc( char esc )
03720 {
03721 switch ( esc )
03722 {
03723 case '!':
03724 case '#':
03725 case '$':
03726 case '%':
03727 case '&':
03728 case '*':
03729 case '@':
03730 case '^':
03731 case '~':
03732 plsc->esc = esc;
03733 break;
03734
03735 default:
03736 plwarn( "plsesc: Invalid escape character, ignoring." );
03737 }
03738 }
03739
03740
03741
03742 void
03743 plgesc( char *p_esc )
03744 {
03745 if ( plsc->esc == '\0' )
03746 plsc->esc = '#';
03747
03748 *p_esc = plsc->esc;
03749 }
03750
03751
03752
03753
03754 void
03755 c_plsfci( PLUNICODE fci )
03756 {
03757
03758 plsc->fci = fci | PL_FCI_MARK;
03759 }
03760
03761
03762
03763
03764 void
03765 c_plgfci( PLUNICODE *pfci )
03766 {
03767
03768 *pfci = plsc->fci | PL_FCI_MARK;
03769 }
03770
03771
03772
03773 void
03774 plP_hex2fci( unsigned char hexdigit, unsigned char hexpower, PLUNICODE *pfci )
03775 {
03776 PLUNICODE mask;
03777 hexpower = hexpower & PL_FCI_HEXPOWER_MASK;
03778 mask = ~( ( (PLUNICODE) PL_FCI_HEXDIGIT_MASK ) << ( (PLUNICODE) 4 * hexpower ) );
03779 *pfci = *pfci & mask;
03780 mask = ( ( (PLUNICODE) ( hexdigit & PL_FCI_HEXDIGIT_MASK ) ) << ( 4 * hexpower ) );
03781 *pfci = *pfci | mask;
03782 }
03783
03784
03785
03786 void
03787 plP_fci2hex( PLUNICODE fci, unsigned char *phexdigit, unsigned char hexpower )
03788 {
03789 PLUNICODE mask;
03790 hexpower = hexpower & PL_FCI_HEXPOWER_MASK;
03791 mask = ( ( (PLUNICODE) PL_FCI_HEXPOWER_MASK ) << ( (PLUNICODE) ( 4 * hexpower ) ) );
03792 *phexdigit = (unsigned char) ( ( fci & mask ) >>
03793 ( (PLUNICODE) ( 4 * hexpower ) ) );
03794 }
03795
03796
03797
03798 void
03799 c_plgver( char *p_ver )
03800 {
03801 strcpy( p_ver, VERSION );
03802 }
03803
03804
03805
03806 void
03807 plsxwin( PLINT window_id )
03808 {
03809 plsc->window_id = window_id;
03810 }
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823 void
03824 c_plgfam( PLINT *p_fam, PLINT *p_num, PLINT *p_bmax )
03825 {
03826 *p_fam = plsc->family;
03827 *p_num = plsc->member;
03828 *p_bmax = plsc->bytemax;
03829 }
03830
03831
03832
03833 void
03834 c_plsfam( PLINT fam, PLINT num, PLINT bmax )
03835 {
03836 if ( plsc->level > 0 )
03837 plwarn( "plsfam: Must be called before plinit." );
03838
03839 if ( fam >= 0 )
03840 plsc->family = fam;
03841 if ( num >= 0 )
03842 plsc->member = num;
03843 if ( bmax >= 0 )
03844 plsc->bytemax = bmax;
03845 }
03846
03847
03848
03849 void
03850 c_plfamadv( void )
03851 {
03852 plsc->famadv = 1;
03853 }
03854
03855
03856
03857
03858
03859
03860
03861
03862 void
03863 c_plgxax( PLINT *p_digmax, PLINT *p_digits )
03864 {
03865 *p_digmax = plsc->xdigmax;
03866 *p_digits = plsc->xdigits;
03867 }
03868
03869
03870
03871 void
03872 c_plsxax( PLINT digmax, PLINT digits )
03873 {
03874 plsc->xdigmax = digmax;
03875 plsc->xdigits = digits;
03876 }
03877
03878
03879
03880 void
03881 c_plgyax( PLINT *p_digmax, PLINT *p_digits )
03882 {
03883 *p_digmax = plsc->ydigmax;
03884 *p_digits = plsc->ydigits;
03885 }
03886
03887
03888
03889 void
03890 c_plsyax( PLINT digmax, PLINT digits )
03891 {
03892 plsc->ydigmax = digmax;
03893 plsc->ydigits = digits;
03894 }
03895
03896
03897
03898 void
03899 c_plgzax( PLINT *p_digmax, PLINT *p_digits )
03900 {
03901 *p_digmax = plsc->zdigmax;
03902 *p_digits = plsc->zdigits;
03903 }
03904
03905
03906
03907 void
03908 c_plszax( PLINT digmax, PLINT digits )
03909 {
03910 plsc->zdigmax = digmax;
03911 plsc->zdigits = digits;
03912 }
03913
03914
03915
03916 void
03917 c_plgchr( PLFLT *p_def, PLFLT *p_ht )
03918 {
03919 *p_def = plsc->chrdef;
03920 *p_ht = plsc->chrht;
03921 }
03922
03923
03924
03925 void
03926 c_plgvpd( PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax )
03927 {
03928 *p_xmin = plsc->vpdxmi;
03929 *p_xmax = plsc->vpdxma;
03930 *p_ymin = plsc->vpdymi;
03931 *p_ymax = plsc->vpdyma;
03932 }
03933
03934
03935
03936 void
03937 c_plgvpw( PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax )
03938 {
03939 *p_xmin = plsc->vpwxmi;
03940 *p_xmax = plsc->vpwxma;
03941 *p_ymin = plsc->vpwymi;
03942 *p_ymax = plsc->vpwyma;
03943 }
03944
03945
03946 void
03947 plP_xgvpw( PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax )
03948 {
03949 PLFLT dx, dy;
03950
03951 dx = ( plsc->vpwxma - plsc->vpwxmi ) * 1.0e-5;
03952 dy = ( plsc->vpwyma - plsc->vpwymi ) * 1.0e-5;
03953
03954
03955
03956
03957 *p_xmin = plsc->vpwxmi - dx;
03958 *p_xmax = plsc->vpwxma + dx;
03959 *p_ymin = plsc->vpwymi - dy;
03960 *p_ymax = plsc->vpwyma + dy;
03961 }
03962
03963
03964
03965
03966
03967
03968
03969 void
03970 plP_gdom( PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax )
03971 {
03972 *p_xmin = plsc->domxmi;
03973 *p_xmax = plsc->domxma;
03974 *p_ymin = plsc->domymi;
03975 *p_ymax = plsc->domyma;
03976 }
03977
03978
03979
03980 void
03981 plP_grange( PLFLT *p_zscl, PLFLT *p_zmin, PLFLT *p_zmax )
03982 {
03983 *p_zscl = plsc->zzscl;
03984 *p_zmin = plsc->ranmi;
03985 *p_zmax = plsc->ranma;
03986 }
03987
03988
03989
03990 void
03991 plP_gw3wc( PLFLT *p_dxx, PLFLT *p_dxy, PLFLT *p_dyx, PLFLT *p_dyy, PLFLT *p_dyz )
03992 {
03993 *p_dxx = plsc->cxx;
03994 *p_dxy = plsc->cxy;
03995 *p_dyx = plsc->cyx;
03996 *p_dyy = plsc->cyy;
03997 *p_dyz = plsc->cyz;
03998 }
03999
04000
04001
04002 void
04003 plP_gclp( PLINT *p_ixmin, PLINT *p_ixmax, PLINT *p_iymin, PLINT *p_iymax )
04004 {
04005 *p_ixmin = plsc->clpxmi;
04006 *p_ixmax = plsc->clpxma;
04007 *p_iymin = plsc->clpymi;
04008 *p_iymax = plsc->clpyma;
04009 }
04010
04011
04012
04013 void
04014 plP_sclp( PLINT ixmin, PLINT ixmax, PLINT iymin, PLINT iymax )
04015 {
04016 plsc->clpxmi = ixmin;
04017 plsc->clpxma = ixmax;
04018 plsc->clpymi = iymin;
04019 plsc->clpyma = iymax;
04020 }
04021
04022
04023
04024 void
04025 plP_gphy( PLINT *p_ixmin, PLINT *p_ixmax, PLINT *p_iymin, PLINT *p_iymax )
04026 {
04027 *p_ixmin = plsc->phyxmi;
04028 *p_ixmax = plsc->phyxma;
04029 *p_iymin = plsc->phyymi;
04030 *p_iymax = plsc->phyyma;
04031 }
04032
04033
04034
04035 void
04036 plP_gsub( PLINT *p_nx, PLINT *p_ny, PLINT *p_cs )
04037 {
04038 *p_nx = plsc->nsubx;
04039 *p_ny = plsc->nsuby;
04040 *p_cs = plsc->cursub;
04041 }
04042
04043
04044
04045 void
04046 plP_ssub( PLINT nx, PLINT ny, PLINT cs )
04047 {
04048 plsc->nsubx = nx;
04049 plsc->nsuby = ny;
04050 plsc->cursub = cs;
04051 }
04052
04053
04054
04055 void
04056 plP_gpixmm( PLFLT *p_x, PLFLT *p_y )
04057 {
04058 *p_x = plsc->xpmm;
04059 *p_y = plsc->ypmm;
04060 }
04061
04062
04063
04064 void
04065 plP_setpxl( PLFLT xpmm, PLFLT ypmm )
04066 {
04067 plsc->xpmm = xpmm;
04068 plsc->ypmm = ypmm;
04069 plsc->umx = (PLINT) ( 1000.0 / plsc->xpmm );
04070 plsc->umy = (PLINT) ( 1000.0 / plsc->ypmm );
04071 }
04072
04073
04074
04075 void
04076 plP_setphy( PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax )
04077 {
04078 if ( xmin > xmax || ymin > ymax )
04079 plexit( "plP_setphy: device minima must not exceed maxima" );
04080
04081 plsc->phyxmi = xmin;
04082 plsc->phyxma = xmax;
04083 plsc->phyymi = ymin;
04084 plsc->phyyma = ymax;
04085 plsc->phyxlen = xmax - xmin;
04086 plsc->phyylen = ymax - ymin;
04087 }
04088
04089
04090
04091
04092
04093
04094
04095
04096 void
04097 c_plscompression( PLINT compression )
04098 {
04099 if ( plsc->level <= 0 )
04100 {
04101 plsc->dev_compression = compression;
04102 }
04103 }
04104
04105
04106
04107
04108
04109
04110
04111 void
04112 c_plgcompression( PLINT *compression )
04113 {
04114 *compression = plsc->dev_compression;
04115 }
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128 void
04129 plP_getinitdriverlist( char *names )
04130 {
04131 int i;
04132
04133 for ( i = 0; i < PL_NSTREAMS; ++i )
04134 {
04135 if ( pls[i] != NULL )
04136 {
04137 if ( i == 0 )
04138 strcpy( names, pls[i]->DevName );
04139 else
04140 {
04141 strcat( names, " " );
04142 strcat( names, pls[i]->DevName );
04143 }
04144 }
04145 else
04146 break;
04147 }
04148 }
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159 PLINT plP_checkdriverinit( char *names )
04160 {
04161 char *buff;
04162 char *tok = NULL;
04163 PLINT ret = 0;
04164
04165 buff = (char *) malloc( (size_t) PL_NSTREAMS * 8 );
04166
04167
04168 if ( buff != NULL )
04169 {
04170 memset( buff, 0, PL_NSTREAMS * 8 );
04171 plP_getinitdriverlist( buff );
04172
04173 for ( tok = strtok( buff, " ," );
04174 tok; tok = strtok( 0, " ," ) )
04175 {
04176 if ( strstr( names, tok ) != NULL )
04177 {
04178 ret++;
04179 }
04180 }
04181 free( buff );
04182 }
04183 else
04184 ret = -1;
04185
04186 return ( ret );
04187 }
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
04201 void
04202 plP_image( PLFLT *z, PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy,
04203 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ), PLPointer pltr_data )
04204 {
04205 plsc->page_status = DRAWING;
04206
04207 plimageslow( z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data );
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218 #if 0 // BEGIN dev_fastimg COMMENT
04219 PLINT i, npts;
04220 short *xscl, *yscl;
04221 int plbuf_write;
04222
04223 plsc->page_status = DRAWING;
04224
04225 if ( plsc->dev_fastimg == 0 )
04226 {
04227 plimageslow( x, y, z, nx - 1, ny - 1,
04228 xmin, ymin, dx, dy, zmin, zmax );
04229 return;
04230 }
04231
04232 if ( plsc->plbuf_write )
04233 {
04234 IMG_DT img_dt;
04235
04236 img_dt.xmin = xmin;
04237 img_dt.ymin = ymin;
04238 img_dt.dx = dx;
04239 img_dt.dy = dy;
04240
04241 plsc->dev_ix = x;
04242 plsc->dev_iy = y;
04243 plsc->dev_z = z;
04244 plsc->dev_nptsX = nx;
04245 plsc->dev_nptsY = ny;
04246 plsc->dev_zmin = zmin;
04247 plsc->dev_zmax = zmax;
04248
04249 plbuf_esc( plsc, PLESC_IMAGE, &img_dt );
04250 }
04251
04252
04253 plbuf_write = plsc->plbuf_write;
04254 plsc->plbuf_write = 0;
04255
04256 npts = nx * ny;
04257 if ( plsc->difilt )
04258 {
04259 PLINT clpxmi, clpxma, clpymi, clpyma;
04260
04261 if ( ( ( xscl = (short *) malloc( nx * ny * sizeof ( short ) ) ) == NULL ) ||
04262 ( ( yscl = (short *) malloc( nx * ny * sizeof ( short ) ) ) == NULL ) )
04263 {
04264 plexit( "plP_image: Insufficient memory" );
04265 }
04266
04267 for ( i = 0; i < npts; i++ )
04268 {
04269 xscl[i] = x[i];
04270 yscl[i] = y[i];
04271 }
04272 sdifilt( xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma );
04273 plsc->imclxmin = clpxmi;
04274 plsc->imclymin = clpymi;
04275 plsc->imclxmax = clpxma;
04276 plsc->imclymax = clpyma;
04277 grimage( xscl, yscl, z, nx, ny );
04278 free( xscl );
04279 free( yscl );
04280 }
04281 else
04282 {
04283 plsc->imclxmin = plsc->phyxmi;
04284 plsc->imclymin = plsc->phyymi;
04285 plsc->imclxmax = plsc->phyxma;
04286 plsc->imclymax = plsc->phyyma;
04287 grimage( x, y, z, nx, ny );
04288 }
04289 plsc->plbuf_write = plbuf_write;
04290 #endif // END dev_fastimg COMMENT
04291 }
04292
04293
04294
04295
04296
04297
04298
04299 void
04300 c_plstransform( void ( *coordinate_transform )( PLFLT, PLFLT, PLFLT*, PLFLT*, PLPointer ), PLPointer coordinate_transform_data )
04301 {
04302 plsc->coordinate_transform = coordinate_transform;
04303 plsc->coordinate_transform_data = coordinate_transform_data;
04304 }