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 #define NEED_PLDEBUG
00028 #include "plplotP.h"
00029 #include "drivers.h"
00030 #include "metadefs.h"
00031
00032 #include <string.h>
00033
00034
00035 void * plbuf_save( PLStream *pls, void *state );
00036
00037 static int rd_command( PLStream *pls, U_CHAR *p_c );
00038 static void rd_data( PLStream *pls, void *buf, size_t buf_size );
00039 static void wr_command( PLStream *pls, U_CHAR c );
00040 static void wr_data( PLStream *pls, void *buf, size_t buf_size );
00041 static void plbuf_control( PLStream *pls, U_CHAR c );
00042
00043 static void rdbuf_init( PLStream *pls );
00044 static void rdbuf_line( PLStream *pls );
00045 static void rdbuf_polyline( PLStream *pls );
00046 static void rdbuf_eop( PLStream *pls );
00047 static void rdbuf_bop( PLStream *pls );
00048 static void rdbuf_state( PLStream *pls );
00049 static void rdbuf_esc( PLStream *pls );
00050
00051 static void plbuf_fill( PLStream *pls );
00052 static void rdbuf_fill( PLStream *pls );
00053 static void plbuf_swin( PLStream *pls, PLWindow *plwin );
00054 static void rdbuf_swin( PLStream *pls );
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void
00065 plbuf_init( PLStream *pls )
00066 {
00067 dbug_enter( "plbuf_init" );
00068
00069 pls->plbuf_read = FALSE;
00070 #ifdef BUFFERED_FILE
00071 if ( pls->plbufFile != NULL )
00072 pls->plbuf_write = FALSE;
00073 #else
00074 if ( pls->plbuf_buffer != NULL )
00075 pls->plbuf_write = FALSE;
00076 #endif
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 void
00086 plbuf_line( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
00087 {
00088 short xpl[2], ypl[2];
00089
00090 dbug_enter( "plbuf_line" );
00091
00092 wr_command( pls, (U_CHAR) LINE );
00093
00094 xpl[0] = x1a;
00095 xpl[1] = x2a;
00096 ypl[0] = y1a;
00097 ypl[1] = y2a;
00098
00099 wr_data( pls, xpl, sizeof ( short ) * 2 );
00100 wr_data( pls, ypl, sizeof ( short ) * 2 );
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 void
00110 plbuf_polyline( PLStream *pls, short *xa, short *ya, PLINT npts )
00111 {
00112 dbug_enter( "plbuf_polyline" );
00113
00114 wr_command( pls, (U_CHAR) POLYLINE );
00115
00116 wr_data( pls, &npts, sizeof ( PLINT ) );
00117
00118 wr_data( pls, xa, sizeof ( short ) * npts );
00119 wr_data( pls, ya, sizeof ( short ) * npts );
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 void
00129 plbuf_eop( PLStream *pls )
00130 {
00131 dbug_enter( "plbuf_eop" );
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 void
00146 plbuf_bop( PLStream *pls )
00147 {
00148 dbug_enter( "plbuf_bop" );
00149
00150 plbuf_tidy( pls );
00151
00152 #ifdef BUFFERED_FILE
00153 pls->plbufFile = pl_create_tempfile( NULL );
00154 if ( pls->plbufFile == NULL )
00155 plexit( "plbuf_bop: Error opening plot data storage file." );
00156 #else
00157
00158 pls->plbuf_buffer_grow = 128 * 1024;
00159
00160 if ( pls->plbuf_buffer == NULL )
00161 {
00162
00163 if ( ( pls->plbuf_buffer = malloc( pls->plbuf_buffer_grow ) ) == NULL )
00164 plexit( "plbuf_bop: Error allocating plot buffer." );
00165
00166 pls->plbuf_buffer_size = pls->plbuf_buffer_grow;
00167 pls->plbuf_top = 0;
00168 pls->plbuf_readpos = 0;
00169 }
00170 else
00171 {
00172
00173 pls->plbuf_top = 0;
00174 }
00175 #endif
00176
00177 wr_command( pls, (U_CHAR) BOP );
00178 plbuf_state( pls, PLSTATE_COLOR0 );
00179 plbuf_state( pls, PLSTATE_WIDTH );
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 void
00189 plbuf_tidy( PLStream *pls )
00190 {
00191 dbug_enter( "plbuf_tidy" );
00192
00193 #ifdef BUFFERED_FILE
00194 if ( pls->plbufFile == NULL )
00195 return;
00196
00197 fclose( pls->plbufFile )
00198 pls->plbufFile = NULL;
00199 #endif
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 void
00209 plbuf_state( PLStream *pls, PLINT op )
00210 {
00211 dbug_enter( "plbuf_state" );
00212
00213 wr_command( pls, (U_CHAR) CHANGE_STATE );
00214 wr_command( pls, (U_CHAR) op );
00215
00216 switch ( op )
00217 {
00218 case PLSTATE_WIDTH:
00219 wr_data( pls, &( pls->width ), sizeof ( pls->width ) );
00220 break;
00221
00222 case PLSTATE_COLOR0:
00223 wr_data( pls, &( pls->icol0 ), sizeof ( pls->icol0 ) );
00224 if ( pls->icol0 == PL_RGB_COLOR )
00225 {
00226 wr_data( pls, &( pls->curcolor.r ), sizeof ( pls->curcolor.r ) );
00227 wr_data( pls, &( pls->curcolor.g ), sizeof ( pls->curcolor.g ) );
00228 wr_data( pls, &( pls->curcolor.b ), sizeof ( pls->curcolor.b ) );
00229 }
00230 break;
00231
00232 case PLSTATE_COLOR1:
00233 wr_data( pls, &( pls->icol1 ), sizeof ( pls->icol1 ) );
00234 break;
00235
00236 case PLSTATE_FILL:
00237 wr_data( pls, &( pls->patt ), sizeof ( pls->patt ) );
00238 break;
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static void
00251 plbuf_image( PLStream *pls, IMG_DT *img_dt )
00252 {
00253 PLINT npts = pls->dev_nptsX * pls->dev_nptsY;
00254
00255 dbug_enter( "plbuf_image" );
00256
00257 wr_data( pls, &pls->dev_nptsX, sizeof ( PLINT ) );
00258 wr_data( pls, &pls->dev_nptsY, sizeof ( PLINT ) );
00259
00260 wr_data( pls, &img_dt->xmin, sizeof ( PLFLT ) );
00261 wr_data( pls, &img_dt->ymin, sizeof ( PLFLT ) );
00262 wr_data( pls, &img_dt->dx, sizeof ( PLFLT ) );
00263 wr_data( pls, &img_dt->dy, sizeof ( PLFLT ) );
00264
00265 wr_data( pls, &pls->dev_zmin, sizeof ( short ) );
00266 wr_data( pls, &pls->dev_zmax, sizeof ( short ) );
00267
00268 wr_data( pls, pls->dev_ix, sizeof ( short ) * npts );
00269 wr_data( pls, pls->dev_iy, sizeof ( short ) * npts );
00270 wr_data( pls, pls->dev_z, sizeof ( unsigned short ) * ( pls->dev_nptsX - 1 ) * ( pls->dev_nptsY - 1 ) );
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 static void
00280 plbuf_text( PLStream *pls, EscText *text )
00281 {
00282 PLUNICODE fci;
00283
00284 dbug_enter( "plbuf_text" );
00285
00286
00287 plgfci( &fci );
00288
00289
00290
00291 wr_data( pls, &fci, sizeof ( PLUNICODE ) );
00292
00293 wr_data( pls, &pls->chrht, sizeof ( PLFLT ) );
00294 wr_data( pls, &pls->diorot, sizeof ( PLFLT ) );
00295 wr_data( pls, &pls->clpxmi, sizeof ( PLFLT ) );
00296 wr_data( pls, &pls->clpxma, sizeof ( PLFLT ) );
00297 wr_data( pls, &pls->clpymi, sizeof ( PLFLT ) );
00298 wr_data( pls, &pls->clpyma, sizeof ( PLFLT ) );
00299
00300 wr_data( pls, &text->base, sizeof ( PLINT ) );
00301 wr_data( pls, &text->just, sizeof ( PLFLT ) );
00302 wr_data( pls, text->xform, sizeof ( PLFLT ) * 4 );
00303 wr_data( pls, &text->x, sizeof ( PLINT ) );
00304 wr_data( pls, &text->y, sizeof ( PLINT ) );
00305 wr_data( pls, &text->refx, sizeof ( PLINT ) );
00306 wr_data( pls, &text->refy, sizeof ( PLINT ) );
00307
00308 wr_data( pls, &text->unicode_array_len, sizeof ( PLINT ) );
00309 if ( text->unicode_array_len )
00310 wr_data( pls, text->unicode_array, sizeof ( PLUNICODE ) * text->unicode_array_len );
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 static void
00320 plbuf_text_unicode( PLStream *pls, EscText *text )
00321 {
00322 PLUNICODE fci;
00323
00324 dbug_enter( "plbuf_text" );
00325
00326
00327 plgfci( &fci );
00328
00329
00330
00331 wr_data( pls, &fci, sizeof ( PLUNICODE ) );
00332
00333 wr_data( pls, &pls->chrht, sizeof ( PLFLT ) );
00334 wr_data( pls, &pls->diorot, sizeof ( PLFLT ) );
00335 wr_data( pls, &pls->clpxmi, sizeof ( PLFLT ) );
00336 wr_data( pls, &pls->clpxma, sizeof ( PLFLT ) );
00337 wr_data( pls, &pls->clpymi, sizeof ( PLFLT ) );
00338 wr_data( pls, &pls->clpyma, sizeof ( PLFLT ) );
00339
00340 wr_data( pls, &text->base, sizeof ( PLINT ) );
00341 wr_data( pls, &text->just, sizeof ( PLFLT ) );
00342 wr_data( pls, text->xform, sizeof ( PLFLT ) * 4 );
00343 wr_data( pls, &text->x, sizeof ( PLINT ) );
00344 wr_data( pls, &text->y, sizeof ( PLINT ) );
00345 wr_data( pls, &text->refx, sizeof ( PLINT ) );
00346 wr_data( pls, &text->refy, sizeof ( PLINT ) );
00347
00348 wr_data( pls, &text->n_fci, sizeof ( PLUNICODE ) );
00349 wr_data( pls, &text->n_char, sizeof ( PLUNICODE ) );
00350 wr_data( pls, &text->n_ctrl_char, sizeof ( PLINT ) );
00351
00352 wr_data( pls, &text->unicode_array_len, sizeof ( PLINT ) );
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 void
00374 plbuf_esc( PLStream *pls, PLINT op, void *ptr )
00375 {
00376 dbug_enter( "plbuf_esc" );
00377
00378 wr_command( pls, (U_CHAR) ESCAPE );
00379 wr_command( pls, (U_CHAR) op );
00380
00381 switch ( op )
00382 {
00383 case PLESC_FILL:
00384 plbuf_fill( pls );
00385 break;
00386 case PLESC_SWIN:
00387 plbuf_swin( pls, (PLWindow *) ptr );
00388 break;
00389 case PLESC_IMAGE:
00390 plbuf_image( pls, (IMG_DT *) ptr );
00391 break;
00392 case PLESC_HAS_TEXT:
00393 if ( ptr != NULL )
00394 plbuf_text( pls, (EscText *) ptr );
00395 break;
00396 case PLESC_BEGIN_TEXT:
00397 case PLESC_TEXT_CHAR:
00398 case PLESC_CONTROL_CHAR:
00399 case PLESC_END_TEXT:
00400 plbuf_text_unicode( pls, (EscText *) ptr );
00401 break;
00402 #if 0
00403
00404 case PLESC_CLEAR:
00405 case PLESC_START_RASTERIZE:
00406 case PLESC_END_RASTERIZE:
00407 break;
00408 #endif
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417
00418 static void
00419 plbuf_fill( PLStream *pls )
00420 {
00421 dbug_enter( "plbuf_fill" );
00422
00423 wr_data( pls, &pls->dev_npts, sizeof ( PLINT ) );
00424 wr_data( pls, pls->dev_x, sizeof ( short ) * pls->dev_npts );
00425 wr_data( pls, pls->dev_y, sizeof ( short ) * pls->dev_npts );
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 static void
00435 plbuf_swin( PLStream *pls, PLWindow *plwin )
00436 {
00437 wr_data( pls, &plwin->dxmi, sizeof ( PLFLT ) );
00438 wr_data( pls, &plwin->dxma, sizeof ( PLFLT ) );
00439 wr_data( pls, &plwin->dymi, sizeof ( PLFLT ) );
00440 wr_data( pls, &plwin->dyma, sizeof ( PLFLT ) );
00441
00442 wr_data( pls, &plwin->wxmi, sizeof ( PLFLT ) );
00443 wr_data( pls, &plwin->wxma, sizeof ( PLFLT ) );
00444 wr_data( pls, &plwin->wymi, sizeof ( PLFLT ) );
00445 wr_data( pls, &plwin->wyma, sizeof ( PLFLT ) );
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 static void
00459 rdbuf_init( PLStream *pls )
00460 {
00461 dbug_enter( "rdbuf_init" );
00462 }
00463
00464
00465
00466
00467
00468
00469
00470 static void
00471 rdbuf_line( PLStream *pls )
00472 {
00473 short xpl[2], ypl[2];
00474 PLINT npts = 2;
00475
00476 dbug_enter( "rdbuf_line" );
00477
00478 rd_data( pls, xpl, sizeof ( short ) * npts );
00479 rd_data( pls, ypl, sizeof ( short ) * npts );
00480
00481 plP_line( xpl, ypl );
00482 }
00483
00484
00485
00486
00487
00488
00489
00490 static void
00491 rdbuf_polyline( PLStream *pls )
00492 {
00493 short _xpl[PL_MAXPOLY], _ypl[PL_MAXPOLY];
00494 short *xpl, *ypl;
00495 PLINT npts;
00496
00497 dbug_enter( "rdbuf_polyline" );
00498
00499 rd_data( pls, &npts, sizeof ( PLINT ) );
00500
00501 if ( npts > PL_MAXPOLY )
00502 {
00503 xpl = (short *) malloc( ( npts + 1 ) * sizeof ( PLINT ) );
00504 ypl = (short *) malloc( ( npts + 1 ) * sizeof ( PLINT ) );
00505
00506 if ( ( xpl == NULL ) || ( ypl == NULL ) )
00507 {
00508 plexit( "rdbuf_polyline: Insufficient memory for large polyline" );
00509 }
00510 }
00511 else
00512 {
00513 xpl = _xpl;
00514 ypl = _ypl;
00515 }
00516
00517
00518 rd_data( pls, xpl, sizeof ( short ) * npts );
00519 rd_data( pls, ypl, sizeof ( short ) * npts );
00520
00521 plP_polyline( xpl, ypl, npts );
00522
00523 if ( npts > PL_MAXPOLY )
00524 {
00525 free( xpl );
00526 free( ypl );
00527 }
00528 }
00529
00530
00531
00532
00533
00534
00535
00536 static void
00537 rdbuf_eop( PLStream *pls )
00538 {
00539 dbug_enter( "rdbuf_eop" );
00540 }
00541
00542
00543
00544
00545
00546
00547
00548 static void
00549 rdbuf_bop( PLStream *pls )
00550 {
00551 dbug_enter( "rdbuf_bop" );
00552
00553 pls->nplwin = 0;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562 static void
00563 rdbuf_state( PLStream *pls )
00564 {
00565 U_CHAR op;
00566
00567 dbug_enter( "rdbuf_state" );
00568
00569 rd_data( pls, &op, sizeof ( U_CHAR ) );
00570
00571 switch ( op )
00572 {
00573 case PLSTATE_WIDTH: {
00574 U_CHAR width;
00575
00576 rd_data( pls, &width, sizeof ( U_CHAR ) );
00577 pls->width = width;
00578 plP_state( PLSTATE_WIDTH );
00579
00580 break;
00581 }
00582
00583 case PLSTATE_COLOR0: {
00584 short icol0;
00585 U_CHAR r, g, b;
00586 PLFLT a;
00587
00588 rd_data( pls, &icol0, sizeof ( short ) );
00589 if ( icol0 == PL_RGB_COLOR )
00590 {
00591 rd_data( pls, &r, sizeof ( U_CHAR ) );
00592 rd_data( pls, &g, sizeof ( U_CHAR ) );
00593 rd_data( pls, &b, sizeof ( U_CHAR ) );
00594 a = 1.0;
00595 }
00596 else
00597 {
00598 if ( (int) icol0 >= pls->ncol0 )
00599 {
00600 char buffer[256];
00601 snprintf( buffer, 256, "rdbuf_state: Invalid color map entry: %d", (int) icol0 );
00602 plabort( buffer );
00603 return;
00604 }
00605 r = pls->cmap0[icol0].r;
00606 g = pls->cmap0[icol0].g;
00607 b = pls->cmap0[icol0].b;
00608 a = pls->cmap0[icol0].a;
00609 }
00610 pls->icol0 = icol0;
00611 pls->curcolor.r = r;
00612 pls->curcolor.g = g;
00613 pls->curcolor.b = b;
00614 pls->curcolor.a = a;
00615
00616 plP_state( PLSTATE_COLOR0 );
00617 break;
00618 }
00619
00620 case PLSTATE_COLOR1: {
00621 short icol1;
00622
00623 rd_data( pls, &icol1, sizeof ( short ) );
00624
00625 pls->icol1 = icol1;
00626 pls->curcolor.r = pls->cmap1[icol1].r;
00627 pls->curcolor.g = pls->cmap1[icol1].g;
00628 pls->curcolor.b = pls->cmap1[icol1].b;
00629 pls->curcolor.a = pls->cmap1[icol1].a;
00630
00631 plP_state( PLSTATE_COLOR1 );
00632 break;
00633 }
00634
00635 case PLSTATE_FILL: {
00636 signed char patt;
00637
00638 rd_data( pls, &patt, sizeof ( signed char ) );
00639
00640 pls->patt = patt;
00641 plP_state( PLSTATE_FILL );
00642 break;
00643 }
00644 }
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 static void
00671 rdbuf_image( PLStream *pls );
00672
00673 static void
00674 rdbuf_text( PLStream *pls );
00675
00676 static void
00677 rdbuf_text_unicode( PLINT op, PLStream *pls );
00678
00679 static void
00680 rdbuf_esc( PLStream *pls )
00681 {
00682 U_CHAR op;
00683
00684 dbug_enter( "rdbuf_esc" );
00685
00686 rd_data( pls, &op, sizeof ( U_CHAR ) );
00687
00688 switch ( op )
00689 {
00690 case PLESC_FILL:
00691 rdbuf_fill( pls );
00692 break;
00693 case PLESC_SWIN:
00694 rdbuf_swin( pls );
00695 break;
00696 case PLESC_IMAGE:
00697 rdbuf_image( pls );
00698 break;
00699 case PLESC_HAS_TEXT:
00700 rdbuf_text( pls );
00701 break;
00702 case PLESC_BEGIN_TEXT:
00703 case PLESC_TEXT_CHAR:
00704 case PLESC_CONTROL_CHAR:
00705 case PLESC_END_TEXT:
00706 rdbuf_text_unicode( op, pls );
00707 break;
00708 case PLESC_CLEAR:
00709 plP_esc( PLESC_CLEAR, NULL );
00710 break;
00711 case PLESC_START_RASTERIZE:
00712 plP_esc( PLESC_START_RASTERIZE, NULL );
00713 break;
00714 case PLESC_END_RASTERIZE:
00715 plP_esc( PLESC_END_RASTERIZE, NULL );
00716 break;
00717 }
00718 }
00719
00720
00721
00722
00723
00724
00725
00726 static void
00727 rdbuf_fill( PLStream *pls )
00728 {
00729 short _xpl[PL_MAXPOLY], _ypl[PL_MAXPOLY];
00730 short *xpl, *ypl;
00731 PLINT npts;
00732
00733 dbug_enter( "rdbuf_fill" );
00734
00735 rd_data( pls, &npts, sizeof ( PLINT ) );
00736
00737 if ( npts > PL_MAXPOLY )
00738 {
00739 xpl = (short *) malloc( ( npts + 1 ) * sizeof ( PLINT ) );
00740 ypl = (short *) malloc( ( npts + 1 ) * sizeof ( PLINT ) );
00741
00742 if ( ( xpl == NULL ) || ( ypl == NULL ) )
00743 {
00744 plexit( "rdbuf_polyline: Insufficient memory for large polyline" );
00745 }
00746 }
00747 else
00748 {
00749 xpl = _xpl;
00750 ypl = _ypl;
00751 }
00752
00753 rd_data( pls, xpl, sizeof ( short ) * npts );
00754 rd_data( pls, ypl, sizeof ( short ) * npts );
00755
00756 plP_fill( xpl, ypl, npts );
00757
00758 if ( npts > PL_MAXPOLY )
00759 {
00760 free( xpl );
00761 free( ypl );
00762 }
00763 }
00764
00765
00766
00767
00768
00769
00770
00771 static void
00772 rdbuf_image( PLStream *pls )
00773 {
00774 short *dev_ix, *dev_iy;
00775 unsigned short *dev_z, dev_zmin, dev_zmax;
00776 PLINT nptsX, nptsY, npts;
00777 PLFLT xmin, ymin, dx, dy;
00778
00779 dbug_enter( "rdbuf_image" );
00780
00781 rd_data( pls, &nptsX, sizeof ( PLINT ) );
00782 rd_data( pls, &nptsY, sizeof ( PLINT ) );
00783 npts = nptsX * nptsY;
00784
00785 rd_data( pls, &xmin, sizeof ( PLFLT ) );
00786 rd_data( pls, &ymin, sizeof ( PLFLT ) );
00787 rd_data( pls, &dx, sizeof ( PLFLT ) );
00788 rd_data( pls, &dy, sizeof ( PLFLT ) );
00789
00790 rd_data( pls, &dev_zmin, sizeof ( short ) );
00791 rd_data( pls, &dev_zmax, sizeof ( short ) );
00792
00793
00794
00795
00796
00797 if ( ( ( dev_ix = (short *) malloc( npts * sizeof ( short ) ) ) == NULL ) ||
00798 ( ( dev_iy = (short *) malloc( npts * sizeof ( short ) ) ) == NULL ) ||
00799 ( ( dev_z = (unsigned short *) malloc( ( nptsX - 1 ) * ( nptsY - 1 ) * sizeof ( unsigned short ) ) ) == NULL ) )
00800 plexit( "rdbuf_image: Insufficient memory" );
00801
00802 rd_data( pls, dev_ix, sizeof ( short ) * npts );
00803 rd_data( pls, dev_iy, sizeof ( short ) * npts );
00804 rd_data( pls, dev_z, sizeof ( unsigned short ) * ( nptsX - 1 ) * ( nptsY - 1 ) );
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 free( dev_ix );
00816 free( dev_iy );
00817 free( dev_z );
00818 }
00819
00820
00821
00822
00823
00824
00825
00826 static void
00827 rdbuf_swin( PLStream *pls )
00828 {
00829 PLWindow plwin;
00830
00831 rd_data( pls, &plwin.dxmi, sizeof ( PLFLT ) );
00832 rd_data( pls, &plwin.dxma, sizeof ( PLFLT ) );
00833 rd_data( pls, &plwin.dymi, sizeof ( PLFLT ) );
00834 rd_data( pls, &plwin.dyma, sizeof ( PLFLT ) );
00835
00836 rd_data( pls, &plwin.wxmi, sizeof ( PLFLT ) );
00837 rd_data( pls, &plwin.wxma, sizeof ( PLFLT ) );
00838 rd_data( pls, &plwin.wymi, sizeof ( PLFLT ) );
00839 rd_data( pls, &plwin.wyma, sizeof ( PLFLT ) );
00840
00841 plP_swin( &plwin );
00842 }
00843
00844
00845
00846
00847
00848
00849
00850 static void
00851 rdbuf_text( PLStream *pls )
00852 {
00853 PLUNICODE( fci );
00854 EscText text;
00855 PLFLT xform[4];
00856 PLUNICODE* unicode;
00857
00858 text.xform = xform;
00859
00860
00861
00862
00863 rd_data( pls, &fci, sizeof ( PLUNICODE ) );
00864
00865 rd_data( pls, &pls->chrht, sizeof ( PLFLT ) );
00866 rd_data( pls, &pls->diorot, sizeof ( PLFLT ) );
00867 rd_data( pls, &pls->clpxmi, sizeof ( PLFLT ) );
00868 rd_data( pls, &pls->clpxma, sizeof ( PLFLT ) );
00869 rd_data( pls, &pls->clpymi, sizeof ( PLFLT ) );
00870 rd_data( pls, &pls->clpyma, sizeof ( PLFLT ) );
00871
00872 rd_data( pls, &text.base, sizeof ( PLINT ) );
00873 rd_data( pls, &text.just, sizeof ( PLFLT ) );
00874 rd_data( pls, text.xform, sizeof ( PLFLT ) * 4 );
00875 rd_data( pls, &text.x, sizeof ( PLINT ) );
00876 rd_data( pls, &text.y, sizeof ( PLINT ) );
00877 rd_data( pls, &text.refx, sizeof ( PLINT ) );
00878 rd_data( pls, &text.refy, sizeof ( PLINT ) );
00879
00880 rd_data( pls, &text.unicode_array_len, sizeof ( PLINT ) );
00881 if ( text.unicode_array_len )
00882 {
00883 if ( ( unicode = (PLUNICODE *) malloc( text.unicode_array_len * sizeof ( PLUNICODE ) ) )
00884 == NULL )
00885 plexit( "rdbuf_text: Insufficient memory" );
00886
00887 rd_data( pls, unicode, sizeof ( PLUNICODE ) * text.unicode_array_len );
00888 text.unicode_array = unicode;
00889 }
00890 else
00891 text.unicode_array = NULL;
00892
00893
00894 if ( pls->dev_unicode )
00895 {
00896 plsfci( fci );
00897 plP_esc( PLESC_HAS_TEXT, &text );
00898 }
00899 }
00900
00901
00902
00903
00904
00905
00906
00907 static void
00908 rdbuf_text_unicode( PLINT op, PLStream *pls )
00909 {
00910 PLUNICODE( fci );
00911 EscText text;
00912 PLFLT xform[4];
00913
00914 text.xform = xform;
00915
00916
00917
00918
00919 rd_data( pls, &fci, sizeof ( PLUNICODE ) );
00920
00921 rd_data( pls, &pls->chrht, sizeof ( PLFLT ) );
00922 rd_data( pls, &pls->diorot, sizeof ( PLFLT ) );
00923 rd_data( pls, &pls->clpxmi, sizeof ( PLFLT ) );
00924 rd_data( pls, &pls->clpxma, sizeof ( PLFLT ) );
00925 rd_data( pls, &pls->clpymi, sizeof ( PLFLT ) );
00926 rd_data( pls, &pls->clpyma, sizeof ( PLFLT ) );
00927
00928 rd_data( pls, &text.base, sizeof ( PLINT ) );
00929 rd_data( pls, &text.just, sizeof ( PLFLT ) );
00930 rd_data( pls, text.xform, sizeof ( PLFLT ) * 4 );
00931 rd_data( pls, &text.x, sizeof ( PLINT ) );
00932 rd_data( pls, &text.y, sizeof ( PLINT ) );
00933 rd_data( pls, &text.refx, sizeof ( PLINT ) );
00934 rd_data( pls, &text.refy, sizeof ( PLINT ) );
00935
00936 rd_data( pls, &text.n_fci, sizeof ( PLUNICODE ) );
00937 rd_data( pls, &text.n_char, sizeof ( PLUNICODE ) );
00938 rd_data( pls, &text.n_ctrl_char, sizeof ( PLINT ) );
00939
00940 rd_data( pls, &text.unicode_array_len, sizeof ( PLINT ) );
00941
00942 if ( pls->dev_unicode )
00943 {
00944 plsfci( fci );
00945 plP_esc( op, &text );
00946 }
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956 void
00957 plRemakePlot( PLStream *pls )
00958 {
00959 U_CHAR c;
00960 int plbuf_status;
00961 PLStream *save_pls;
00962
00963 dbug_enter( "plRemakePlot" );
00964
00965
00966
00967
00968
00969
00970
00971 plbuf_status = pls->plbuf_write;
00972 pls->plbuf_write = FALSE;
00973 pls->plbuf_read = TRUE;
00974
00975 #ifdef BUFFERED_FILE
00976 if ( pls->plbufFile )
00977 {
00978 rewind( pls->plbufFile );
00979 #else
00980 if ( pls->plbuf_buffer )
00981 {
00982 pls->plbuf_readpos = 0;
00983 #endif
00984
00985
00986
00987
00988 save_pls = plsc;
00989 plsc = pls;
00990
00991 while ( rd_command( pls, &c ) )
00992 {
00993 plbuf_control( pls, c );
00994 }
00995
00996 plsc = save_pls;
00997 }
00998
00999 pls->plbuf_read = FALSE;
01000 pls->plbuf_write = plbuf_status;
01001 }
01002
01003
01004
01005
01006
01007
01008
01009 static void
01010 plbuf_control( PLStream *pls, U_CHAR c )
01011 {
01012 static U_CHAR c_old = 0;
01013
01014 dbug_enter( "plbuf_control" );
01015
01016 switch ( (int) c )
01017 {
01018 case INITIALIZE:
01019 rdbuf_init( pls );
01020 break;
01021
01022 case EOP:
01023 rdbuf_eop( pls );
01024 break;
01025
01026 case BOP:
01027 rdbuf_bop( pls );
01028 break;
01029
01030 case CHANGE_STATE:
01031 rdbuf_state( pls );
01032 break;
01033
01034 case LINE:
01035 rdbuf_line( pls );
01036 break;
01037
01038 case POLYLINE:
01039 rdbuf_polyline( pls );
01040 break;
01041
01042 case ESCAPE:
01043 rdbuf_esc( pls );
01044 break;
01045
01046 default:
01047 pldebug( "plbuf_control", "Unrecognized command %d, previous %d\n", c, c_old );
01048 }
01049 c_old = c;
01050 }
01051
01052
01053
01054
01055
01056
01057
01058 static int
01059 rd_command( PLStream *pls, U_CHAR *p_c )
01060 {
01061 int count;
01062
01063 #ifdef BUFFERED_FILE
01064 count = fread( p_c, sizeof ( U_CHAR ), 1, pls->plbufFile );
01065 #else
01066 if ( pls->plbuf_readpos < pls->plbuf_top )
01067 {
01068 *p_c = *(U_CHAR *) ( (U_CHAR *) pls->plbuf_buffer + pls->plbuf_readpos );
01069 pls->plbuf_readpos += sizeof ( U_CHAR );
01070 count = sizeof ( U_CHAR );
01071 }
01072 else
01073 {
01074 count = 0;
01075 }
01076 #endif
01077 return ( count );
01078 }
01079
01080
01081
01082
01083
01084
01085
01086 static void
01087 rd_data( PLStream *pls, void *buf, size_t buf_size )
01088 {
01089 #ifdef BUFFERED_FILE
01090 plio_fread( buf, buf_size, 1, pls->plbufFile );
01091 #else
01092
01093
01094
01095
01096 memcpy( buf, (U_CHAR *) pls->plbuf_buffer + pls->plbuf_readpos, buf_size );
01097 pls->plbuf_readpos += buf_size;
01098 #endif
01099 }
01100
01101
01102
01103
01104
01105
01106
01107 static void
01108 wr_command( PLStream *pls, U_CHAR c )
01109 {
01110 #ifdef BUFFERED_FILE
01111 plio_fwrite( &c1, sizeof ( U_CHAR ), 1, pls->plbufFile );
01112 #else
01113 if ( ( pls->plbuf_top + sizeof ( U_CHAR ) ) >= pls->plbuf_buffer_size )
01114 {
01115
01116 pls->plbuf_buffer_size += pls->plbuf_buffer_grow;
01117
01118 if ( pls->verbose )
01119 printf( "Growing buffer to %d KB\n", (int) ( pls->plbuf_buffer_size / 1024 ) );
01120 if ( ( pls->plbuf_buffer = realloc( pls->plbuf_buffer, pls->plbuf_buffer_size ) ) == NULL )
01121 plexit( "plbuf wr_data: Plot buffer grow failed" );
01122 }
01123
01124 *(U_CHAR *) ( (U_CHAR *) pls->plbuf_buffer + pls->plbuf_top ) = c;
01125 pls->plbuf_top += sizeof ( U_CHAR );
01126 #endif
01127 }
01128
01129
01130
01131
01132
01133
01134
01135 static void
01136 wr_data( PLStream *pls, void *buf, size_t buf_size )
01137 {
01138 #ifdef BUFFERED_FILE
01139 plio_fwrite( buf, buf_size, 1, pls->plbufFile );
01140 #else
01141 if ( ( pls->plbuf_top + buf_size ) >= pls->plbuf_buffer_size )
01142 {
01143
01144
01145 pls->plbuf_buffer_size += pls->plbuf_buffer_grow *
01146 ( ( pls->plbuf_top + buf_size - pls->plbuf_buffer_size ) /
01147 pls->plbuf_buffer_grow + 1 );
01148 while ( pls->plbuf_top + buf_size >= pls->plbuf_buffer_size )
01149 ;
01150
01151 if ( ( pls->plbuf_buffer = realloc( pls->plbuf_buffer, pls->plbuf_buffer_size ) ) == NULL )
01152 plexit( "plbuf wr_data: Plot buffer grow failed" );
01153 }
01154
01155
01156
01157
01158
01159 memcpy( (U_CHAR *) pls->plbuf_buffer + pls->plbuf_top, buf, buf_size );
01160 pls->plbuf_top += buf_size;
01161 #endif
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 struct _color_map
01181 {
01182 PLColor *cmap;
01183 PLINT icol;
01184 PLINT ncol;
01185 };
01186
01187 struct _state
01188 {
01189 size_t size;
01190 int valid;
01191 #ifdef BUFFERED_FILE
01192 FILE *plbufFile;
01193 #else
01194 void *plbuf_buffer;
01195 size_t plbuf_buffer_size;
01196 size_t plbuf_top;
01197 size_t plbuf_readpos;
01198 #endif
01199 struct _color_map *color_map;
01200 };
01201
01202 void * plbuf_save( PLStream *pls, void *state )
01203 {
01204 size_t save_size;
01205 struct _state *plot_state = (struct _state *) state;
01206 PLINT i;
01207 U_CHAR *buf;
01208
01209 if ( pls->plbuf_write )
01210 {
01211 pls->plbuf_write = FALSE;
01212 pls->plbuf_read = TRUE;
01213
01214
01215
01216
01217
01218 save_size = sizeof ( struct _state )
01219 + 2 * sizeof ( struct _color_map )
01220 + pls->ncol0 * sizeof ( PLColor )
01221 + pls->ncol1 * sizeof ( PLColor );
01222
01223 #ifndef BUFFERED_FILE
01224
01225 save_size += pls->plbuf_top;
01226 #endif
01227
01228
01229 if ( state != NULL )
01230 {
01231
01232 if ( plot_state->size < save_size )
01233 {
01234
01235 if ( ( plot_state = (struct _state *) realloc( state, save_size ) ) == NULL )
01236 {
01237
01238
01239
01240
01241 plwarn( "plbuf: Unable to reallocate sufficient memory to save state" );
01242 plot_state->valid = 0;
01243
01244 return state;
01245 }
01246 plot_state->size = save_size;
01247 }
01248 }
01249 else
01250 {
01251
01252 if ( ( plot_state = (struct _state *) malloc( save_size ) ) == NULL )
01253 {
01254 plwarn( "plbuf: Unable to allocate sufficient memory to save state" );
01255
01256 return NULL;
01257 }
01258 plot_state->size = save_size;
01259
01260 #ifdef BUFFERED_FILE
01261
01262 plot_state->plbufFile = NULL;
01263 #endif
01264 }
01265
01266
01267
01268
01269
01270
01271
01272 plot_state->valid = 0;
01273
01274
01275 buf = (U_CHAR *) ( plot_state + 1 );
01276
01277 #ifdef BUFFERED_FILE
01278
01279 if ( plot_state->plbufFile != NULL )
01280 {
01281 fclose( plot_state->plbufFile );
01282 }
01283
01284
01285 if ( ( plot_state->plbufFile = pl_create_tempfile( NULL ) ) == NULL )
01286 {
01287
01288
01289
01290 plwarn( "plbuf: Unable to open temporary file to save state" );
01291 return (void *) plot_state;
01292 }
01293 else
01294 {
01295 U_CHAR tmp;
01296
01297 rewind( pls->plbufFile );
01298 while ( count = fread( &tmp, sizeof ( U_CHAR ), 1, pls->plbufFile ) )
01299 {
01300 if ( fwrite( &tmp, sizeof ( U_CHAR ), 1, plot_state->plbufFile ) != count )
01301 {
01302
01303
01304
01305 plwarn( "plbuf: Unable to write to temporary file" );
01306 fclose( plot_state->plbufFile );
01307 plot_state->plbufFile = NULL;
01308 return (void *) plot_state;
01309 }
01310 }
01311 }
01312 #else
01313
01314 plot_state->plbuf_buffer_size = pls->plbuf_top;
01315 plot_state->plbuf_top = pls->plbuf_top;
01316 plot_state->plbuf_readpos = 0;
01317
01318
01319 plot_state->plbuf_buffer = (void *) buf;
01320 buf += pls->plbuf_top;
01321
01322
01323
01324
01325 if ( memcpy( plot_state->plbuf_buffer, pls->plbuf_buffer, pls->plbuf_top ) == NULL )
01326 {
01327
01328 plwarn( "plbuf: Got a NULL in memcpy!" );
01329 return (void *) plot_state;
01330 }
01331 #endif
01332
01333 pls->plbuf_write = TRUE;
01334 pls->plbuf_read = FALSE;
01335
01336
01337
01338 plot_state->color_map = (struct _color_map *) buf;
01339 buf += sizeof ( struct _color_map ) * 2;
01340
01341
01342 plot_state->color_map[0].cmap = (PLColor *) buf;
01343 buf += sizeof ( PLColor ) * pls->ncol0;
01344 plot_state->color_map[1].cmap = (PLColor *) buf;
01345 buf += sizeof ( PLColor ) * pls->ncol1;
01346
01347
01348 plot_state->color_map[0].icol = pls->icol0;
01349 plot_state->color_map[0].ncol = pls->ncol0;
01350 for ( i = 0; i < pls->ncol0; i++ )
01351 {
01352 pl_cpcolor( &( plot_state->color_map[0].cmap[i] ), &pls->cmap0[i] );
01353 }
01354
01355
01356 plot_state->color_map[1].icol = pls->icol1;
01357 plot_state->color_map[1].ncol = pls->ncol1;
01358 for ( i = 0; i < pls->ncol1; i++ )
01359 {
01360 pl_cpcolor( &( plot_state->color_map[1].cmap[i] ), &pls->cmap1[i] );
01361 }
01362
01363 plot_state->valid = 1;
01364 return (void *) plot_state;
01365 }
01366
01367 return NULL;
01368 }
01369
01370
01371
01372
01373
01374 void plbuf_restore( PLStream *pls, void *state )
01375 {
01376 struct _state *new_state = (struct _state *) state;
01377
01378 #ifdef BUFFERED_FILE
01379 pls->plbufFile = new_state->save_file;
01380 #else
01381 pls->plbuf_buffer = new_state->plbuf_buffer;
01382 pls->plbuf_buffer_size = new_state->plbuf_buffer_size;
01383 pls->plbuf_top = new_state->plbuf_top;
01384 pls->plbuf_readpos = new_state->plbuf_readpos;
01385 #endif
01386
01387 pls->cmap0 = new_state->color_map[0].cmap;
01388 pls->icol0 = new_state->color_map[0].icol;
01389 pls->ncol0 = new_state->color_map[0].ncol;
01390
01391 pls->cmap1 = new_state->color_map[1].cmap;
01392 pls->icol1 = new_state->color_map[1].icol;
01393 pls->ncol1 = new_state->color_map[1].ncol;
01394 }
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408 void * plbuf_switch( PLStream *pls, void *state )
01409 {
01410 struct _state *new_state = (struct _state *) state;
01411 struct _state *prev_state;
01412 size_t save_size;
01413
01414
01415
01416
01417 if ( state == NULL )
01418 return NULL;
01419
01420 if ( !new_state->valid )
01421 {
01422 plwarn( "plbuf: Attempting to switch to an invalid saved state" );
01423 return NULL;
01424 }
01425
01426 save_size = sizeof ( struct _state )
01427 + 2 * sizeof ( struct _color_map );
01428
01429 if ( ( prev_state = (struct _state *) malloc( save_size ) ) == NULL )
01430 {
01431 plwarn( "plbuf: Unable to allocate memory to save state" );
01432 return NULL;
01433 }
01434
01435
01436 prev_state->size = save_size;
01437 prev_state->valid = 1;
01438
01439
01440 #ifdef BUFFERED_FILE
01441 prev_state->plbufFile = pls->plbufFile;
01442 #else
01443 prev_state->plbuf_buffer = pls->plbuf_buffer;
01444 prev_state->plbuf_buffer_size = pls->plbuf_buffer_size;
01445 prev_state->plbuf_top = pls->plbuf_top;
01446 prev_state->plbuf_readpos = pls->plbuf_readpos;
01447 #endif
01448
01449 prev_state->color_map[0].cmap = pls->cmap0;
01450 prev_state->color_map[0].icol = pls->icol0;
01451 prev_state->color_map[0].ncol = pls->ncol0;
01452
01453 prev_state->color_map[1].cmap = pls->cmap1;
01454 prev_state->color_map[1].icol = pls->icol1;
01455 prev_state->color_map[1].ncol = pls->ncol1;
01456
01457 plbuf_restore( pls, new_state );
01458
01459 return (void *) prev_state;
01460 }
01461
01462