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