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 #include "plDevs.h"
00028
00029
00030
00031 #ifdef PLD_plmeta
00032
00033 #define NEED_PLDEBUG
00034 #include "plplotP.h"
00035 #include "drivers.h"
00036 #include "metadefs.h"
00037 #include <string.h>
00038
00039
00040 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_plmeta = "plmeta:PLplot Native Meta-File:0:plmeta:26:plm\n";
00041
00042
00043 void plD_dispatch_init_plm( PLDispatchTable *pdt );
00044
00045 void plD_init_plm( PLStream * );
00046 void plD_line_plm( PLStream *, short, short, short, short );
00047 void plD_polyline_plm( PLStream *, short *, short *, PLINT );
00048 void plD_eop_plm( PLStream * );
00049 void plD_bop_plm( PLStream * );
00050 void plD_tidy_plm( PLStream * );
00051 void plD_state_plm( PLStream *, PLINT );
00052 void plD_esc_plm( PLStream *, PLINT, void * );
00053
00054
00055
00056 typedef struct
00057 {
00058 PLFLT pxlx, pxly;
00059 PLINT xold, yold;
00060
00061 PLINT xmin, xmax, xlen;
00062 PLINT ymin, ymax, ylen;
00063
00064 FPOS_T lp_offset, index_offset;
00065
00066 int notfirst;
00067 } PLmDev;
00068
00069
00070
00071 #define BUFFER_LEN 256
00072 static char buffer[BUFFER_LEN];
00073
00074
00075
00076 static void WriteFileHeader( PLStream *pls );
00077 static void UpdatePrevPagehdr( PLStream *pls );
00078 static void WritePageInfo( PLStream *pls, FPOS_T pp_offset );
00079 static void UpdateIndex( PLStream *pls, FPOS_T cp_offset );
00080 static void plm_fill( PLStream *pls );
00081 static void plm_swin( PLStream *pls );
00082
00083
00084
00085 #ifdef DEBUG
00086 #define DEBUG_PRINT_LOCATION( a ) PrintLocation( pls, a )
00087
00088 static void PrintLocation( PLStream *pls, char *tag )
00089 {
00090 int isfile = ( pls->output_type == 0 );
00091 if ( isfile )
00092 {
00093 FILE *file = pls->OutFile;
00094 FPOS_T current_offset;
00095
00096 if ( pl_fgetpos( file, ¤t_offset ) )
00097 plexit( "PrintLocation (plmeta.c): fgetpos call failed" );
00098
00099 pldebug( tag, "at offset %d in file %s\n",
00100 (int) current_offset, pls->FileName );
00101 }
00102 }
00103 #else
00104 #define DEBUG_PRINT_LOCATION( a )
00105 #endif
00106
00107 void plD_dispatch_init_plm( PLDispatchTable *pdt )
00108 {
00109 #ifndef ENABLE_DYNDRIVERS
00110 pdt->pl_MenuStr = "PLplot Native Meta-File";
00111 pdt->pl_DevName = "plmeta";
00112 #endif
00113 pdt->pl_type = plDevType_FileOriented;
00114 pdt->pl_seq = 26;
00115 pdt->pl_init = (plD_init_fp) plD_init_plm;
00116 pdt->pl_line = (plD_line_fp) plD_line_plm;
00117 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_plm;
00118 pdt->pl_eop = (plD_eop_fp) plD_eop_plm;
00119 pdt->pl_bop = (plD_bop_fp) plD_bop_plm;
00120 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_plm;
00121 pdt->pl_state = (plD_state_fp) plD_state_plm;
00122 pdt->pl_esc = (plD_esc_fp) plD_esc_plm;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131 void
00132 plD_init_plm( PLStream *pls )
00133 {
00134 PLmDev *dev;
00135 U_CHAR c = (U_CHAR) INITIALIZE;
00136
00137 dbug_enter( "plD_init_plm" );
00138
00139 pls->color = 1;
00140 pls->dev_fill0 = 1;
00141 pls->dev_fill1 = 1;
00142
00143
00144
00145 plFamInit( pls );
00146
00147
00148
00149 plOpenFile( pls );
00150 pls->pdfs = pdf_finit( pls->OutFile );
00151
00152
00153
00154 pls->dev = calloc( 1, (size_t) sizeof ( PLmDev ) );
00155 if ( pls->dev == NULL )
00156 plexit( "plD_init_plm: Out of memory." );
00157
00158 dev = (PLmDev *) pls->dev;
00159
00160 dev->xold = PL_UNDEFINED;
00161 dev->yold = PL_UNDEFINED;
00162
00163 dev->xmin = 0;
00164 dev->xmax = PIXELS_X - 1;
00165 dev->ymin = 0;
00166 dev->ymax = PIXELS_Y - 1;
00167
00168 dev->pxlx = (double) PIXELS_X / (double) LPAGE_X;
00169 dev->pxly = (double) PIXELS_Y / (double) LPAGE_Y;
00170
00171 plP_setpxl( dev->pxlx, dev->pxly );
00172 plP_setphy( dev->xmin, dev->xmax, dev->ymin, dev->ymax );
00173
00174
00175
00176 WriteFileHeader( pls );
00177
00178
00179
00180 plD_state_plm( pls, PLSTATE_CMAP0 );
00181 plD_state_plm( pls, PLSTATE_CMAP1 );
00182
00183
00184
00185 DEBUG_PRINT_LOCATION( "before init" );
00186 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 void
00196 plD_line_plm( PLStream *pls, short x1, short y1, short x2, short y2 )
00197 {
00198 PLmDev *dev = (PLmDev *) pls->dev;
00199 U_CHAR c;
00200 U_SHORT xy[4];
00201
00202
00203
00204
00205
00206 #ifdef DEBUG
00207 if ( x1 < dev->xmin || x1 > dev->xmax ||
00208 x2 < dev->xmin || x2 > dev->xmax ||
00209 y1 < dev->ymin || y1 > dev->ymax ||
00210 y2 < dev->ymin || y2 > dev->ymax )
00211 {
00212 pldebug( "plD_line_plm",
00213 "coordinates out of bounds -- \nActual: (%i,%i), (%i,%i) Bounds: (%i,%i,%i,%i)\n",
00214 x1, y1, x2, y2, dev->xmin, dev->xmax, dev->ymin, dev->ymax );
00215 }
00216 #endif
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 if ( x1 == dev->xold && y1 == dev->yold )
00229 {
00230 c = (U_CHAR) LINETO;
00231 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00232
00233 xy[0] = x2;
00234 xy[1] = y2;
00235 plm_wr( pdf_wr_2nbytes( pls->pdfs, xy, 2 ) );
00236 }
00237 else
00238 {
00239 c = (U_CHAR) LINE;
00240 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00241
00242 xy[0] = x1;
00243 xy[1] = y1;
00244 xy[2] = x2;
00245 xy[3] = y2;
00246 plm_wr( pdf_wr_2nbytes( pls->pdfs, xy, 4 ) );
00247 }
00248 dev->xold = x2;
00249 dev->yold = y2;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 void
00259 plD_polyline_plm( PLStream *pls, short *xa, short *ya, PLINT npts )
00260 {
00261 PLmDev *dev = (PLmDev *) pls->dev;
00262 U_CHAR c = (U_CHAR) POLYLINE;
00263
00264 dbug_enter( "plD_polyline_plm" );
00265
00266 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00267
00268 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) npts ) );
00269
00270 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) xa, npts ) );
00271 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) ya, npts ) );
00272
00273 dev->xold = xa[npts - 1];
00274 dev->yold = ya[npts - 1];
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 void
00284 plD_eop_plm( PLStream *pls )
00285 {
00286 U_CHAR c = (U_CHAR) EOP;
00287
00288 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 void
00308 plD_bop_plm( PLStream *pls )
00309 {
00310 PLmDev *dev = (PLmDev *) pls->dev;
00311 int isfile = ( pls->output_type == 0 );
00312 FPOS_T pp_offset = dev->lp_offset;;
00313
00314 dbug_enter( "plD_bop_plm" );
00315
00316 dev->xold = PL_UNDEFINED;
00317 dev->yold = PL_UNDEFINED;
00318
00319
00320
00321 if ( isfile )
00322 UpdatePrevPagehdr( pls );
00323
00324
00325
00326 pls->bytecnt = pls->pdfs->bp;
00327 plGetFam( pls );
00328
00329
00330
00331 pls->page++;
00332
00333
00334
00335 WritePageInfo( pls, pp_offset );
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 static void
00345 WritePageInfo( PLStream *pls, FPOS_T pp_offset )
00346 {
00347 PLmDev *dev = (PLmDev *) pls->dev;
00348 FILE *file = pls->OutFile;
00349 int isfile = ( pls->output_type == 0 );
00350 U_CHAR c;
00351 FPOS_T cp_offset = 0;
00352
00353
00354
00355 if ( isfile )
00356 {
00357 if ( pl_fgetpos( file, &cp_offset ) )
00358 plexit( "WritePageInfo (plmeta.c): fgetpos call failed" );
00359
00360 UpdateIndex( pls, cp_offset );
00361 }
00362
00363
00364
00365 if ( dev->notfirst )
00366 c = BOP;
00367 else
00368 {
00369 c = BOP0;
00370 dev->notfirst = 1;
00371 }
00372 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00373 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->page ) );
00374 plm_wr( pdf_wr_4bytes( pls->pdfs, (U_LONG) pp_offset ) );
00375 plm_wr( pdf_wr_4bytes( pls->pdfs, (U_LONG) 0 ) );
00376
00377
00378
00379 dev->lp_offset = cp_offset;
00380
00381
00382
00383
00384 plD_state_plm( pls, PLSTATE_COLOR0 );
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 static void
00394 UpdatePrevPagehdr( PLStream *pls )
00395 {
00396 PLmDev *dev = (PLmDev *) pls->dev;
00397 FILE *file = pls->OutFile;
00398 FPOS_T cp_offset = 0;
00399
00400 fflush( file );
00401
00402
00403
00404 if ( pl_fgetpos( file, &cp_offset ) )
00405 plexit( "plD_bop_plm: fgetpos call failed" );
00406
00407
00408
00409 if ( dev->lp_offset > 0 )
00410 {
00411 FPOS_T fwbyte_offset = 0;
00412
00413 pldebug( "UpdatePrevPagehdr 1 (plmeta.c)",
00414 "Location: %d, seeking to: %d\n",
00415 (int) cp_offset, (int) dev->lp_offset );
00416
00417
00418 fwbyte_offset = dev->lp_offset + 7;
00419 if ( pl_fsetpos( file, &fwbyte_offset ) )
00420 {
00421 snprintf( buffer, BUFFER_LEN, "UpdatePrevPagehdr (plmeta.c): fsetpos to fwbyte_offset (%d) failed",
00422 (int) fwbyte_offset );
00423 plexit( buffer );
00424 }
00425
00426
00427
00428 #ifdef DEBUG
00429 if ( pl_fgetpos( file, &fwbyte_offset ) )
00430 plexit( "UpdatePrevPagehdr (plmeta.c): fgetpos call failed" );
00431
00432 pldebug( "UpdatePrevPagehdr 2 (plmeta.c)",
00433 "Now at: %d, to write: %d\n",
00434 (int) fwbyte_offset, (int) cp_offset );
00435 #endif
00436
00437
00438
00439 plm_wr( pdf_wr_4bytes( pls->pdfs, (U_LONG) cp_offset ) );
00440 fflush( file );
00441
00442
00443
00444 #ifdef DEBUG
00445 if ( pl_fsetpos( file, &fwbyte_offset ) )
00446 {
00447 snprintf( buffer, BUFFER_LEN, "UpdatePrevPagehdr (plmeta.c): fsetpos to fwbyte_offset (%d) failed",
00448 (int) fwbyte_offset );
00449 plexit( buffer );
00450 }
00451 {
00452 U_LONG read_offset;
00453 plm_rd( pdf_rd_4bytes( pls->pdfs, &read_offset ) );
00454 pldebug( "UpdatePrevPagehdr 3 (plmeta.c)",
00455 "Value read as: %d\n", read_offset );
00456 }
00457 #endif
00458
00459
00460
00461 if ( pl_fsetpos( file, &cp_offset ) )
00462 {
00463 snprintf( buffer, BUFFER_LEN, "UpdatePrevPagehdr (plmeta.c): fsetpos to cp_offset (%d) failed",
00464 (int) cp_offset );
00465 plexit( buffer );
00466 }
00467 }
00468 }
00469
00470
00471
00472
00473
00474
00475
00476 static void
00477 UpdateIndex( PLStream *pls, FPOS_T cp_offset )
00478 {
00479 PLmDev *dev = (PLmDev *) pls->dev;
00480 FILE *file = pls->OutFile;
00481
00482
00483
00484
00485 if ( dev->index_offset > 0 )
00486 {
00487 pldebug( "UpdateIndex (plmeta.c)",
00488 "Location: %d, seeking to: %d\n",
00489 (int) cp_offset, (int) dev->lp_offset );
00490
00491 if ( pl_fsetpos( file, &dev->index_offset ) )
00492 {
00493 snprintf( buffer, BUFFER_LEN, "UpdateIndex (plmeta.c): fsetpos to index_offset (%d) failed",
00494 (int) dev->index_offset );
00495 plexit( buffer );
00496 }
00497 plm_wr( pdf_wr_header( pls->pdfs, "pages" ) );
00498 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->page ) );
00499
00500 pldebug( "UpdateIndex (plmeta.c)",
00501 "Location: %d, seeking to: %d\n",
00502 (int) dev->lp_offset, (int) cp_offset );
00503
00504 if ( pl_fsetpos( file, &cp_offset ) )
00505 {
00506 snprintf( buffer, BUFFER_LEN, "UpdateIndex (plmeta.c): fsetpos to cp_offset (%d) failed",
00507 (int) cp_offset );
00508 plexit( buffer );
00509 }
00510 }
00511 }
00512
00513
00514
00515
00516
00517
00518
00519 void
00520 plD_tidy_plm( PLStream *pls )
00521 {
00522 U_CHAR c = (U_CHAR) CLOSE;
00523
00524 dbug_enter( "plD_tidy_plm" );
00525
00526 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00527 pdf_close( pls->pdfs );
00528 free_mem( pls->dev );
00529 }
00530
00531
00532
00533
00534
00535
00536
00537 void
00538 plD_state_plm( PLStream *pls, PLINT op )
00539 {
00540 U_CHAR c = (U_CHAR) CHANGE_STATE;
00541 int i;
00542
00543 dbug_enter( "plD_state_plm" );
00544
00545 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00546 plm_wr( pdf_wr_1byte( pls->pdfs, op ) );
00547
00548 switch ( op )
00549 {
00550 case PLSTATE_WIDTH:
00551 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) ( pls->width ) ) );
00552 break;
00553
00554 case PLSTATE_COLOR0:
00555 plm_wr( pdf_wr_2bytes( pls->pdfs, (short) pls->icol0 ) );
00556
00557 if ( pls->icol0 == PL_RGB_COLOR )
00558 {
00559 plm_wr( pdf_wr_1byte( pls->pdfs, pls->curcolor.r ) );
00560 plm_wr( pdf_wr_1byte( pls->pdfs, pls->curcolor.g ) );
00561 plm_wr( pdf_wr_1byte( pls->pdfs, pls->curcolor.b ) );
00562 }
00563 break;
00564
00565 case PLSTATE_COLOR1:
00566 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->icol1 ) );
00567 break;
00568
00569 case PLSTATE_FILL:
00570 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) pls->patt ) );
00571 break;
00572
00573 case PLSTATE_CMAP0:
00574 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->ncol0 ) );
00575 for ( i = 0; i < pls->ncol0; i++ )
00576 {
00577 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap0[i].r ) );
00578 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap0[i].g ) );
00579 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap0[i].b ) );
00580 }
00581 break;
00582
00583 case PLSTATE_CMAP1:
00584 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->ncol1 ) );
00585 for ( i = 0; i < pls->ncol1; i++ )
00586 {
00587 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap1[i].r ) );
00588 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap1[i].g ) );
00589 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap1[i].b ) );
00590 }
00591 break;
00592 }
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 void
00609 plD_esc_plm( PLStream *pls, PLINT op, void *ptr )
00610 {
00611 U_CHAR c = (U_CHAR) ESCAPE;
00612
00613 dbug_enter( "plD_esc_plm" );
00614
00615 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
00616 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) op ) );
00617
00618 switch ( op )
00619 {
00620 case PLESC_FILL:
00621 plm_fill( pls );
00622 break;
00623
00624 case PLESC_SWIN:
00625 plm_swin( pls );
00626 break;
00627 }
00628 }
00629
00630
00631
00632
00633
00634
00635
00636 static void
00637 plm_fill( PLStream *pls )
00638 {
00639 PLmDev *dev = (PLmDev *) pls->dev;
00640
00641 dbug_enter( "plm_fill" );
00642
00643 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->dev_npts ) );
00644
00645 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) pls->dev_x, pls->dev_npts ) );
00646 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) pls->dev_y, pls->dev_npts ) );
00647
00648 dev->xold = PL_UNDEFINED;
00649 dev->yold = PL_UNDEFINED;
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 static void
00661 plm_swin( PLStream *pls )
00662 {
00663 dbug_enter( "plm_swin" );
00664 }
00665
00666
00667
00668
00669
00670
00671
00672 static void
00673 WriteFileHeader( PLStream *pls )
00674 {
00675 PLmDev *dev = (PLmDev *) pls->dev;
00676 FILE *file = pls->OutFile;
00677 int isfile = ( pls->output_type == 0 );
00678
00679 dbug_enter( "WriteFileHeader(PLStream *pls" );
00680
00681 plm_wr( pdf_wr_header( pls->pdfs, PLMETA_HEADER ) );
00682 plm_wr( pdf_wr_header( pls->pdfs, PLMETA_VERSION ) );
00683
00684
00685
00686
00687 if ( isfile )
00688 {
00689 if ( pl_fgetpos( file, &dev->index_offset ) )
00690 plexit( "WriteFileHeader: fgetpos call failed" );
00691 }
00692
00693 plm_wr( pdf_wr_header( pls->pdfs, "pages" ) );
00694 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) 0 ) );
00695
00696
00697
00698
00699 plm_wr( pdf_wr_header( pls->pdfs, "xmin" ) );
00700 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->xmin ) );
00701
00702 plm_wr( pdf_wr_header( pls->pdfs, "xmax" ) );
00703 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->xmax ) );
00704
00705 plm_wr( pdf_wr_header( pls->pdfs, "ymin" ) );
00706 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->ymin ) );
00707
00708 plm_wr( pdf_wr_header( pls->pdfs, "ymax" ) );
00709 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->ymax ) );
00710
00711 plm_wr( pdf_wr_header( pls->pdfs, "pxlx" ) );
00712 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) dev->pxlx ) );
00713
00714 plm_wr( pdf_wr_header( pls->pdfs, "pxly" ) );
00715 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) dev->pxly ) );
00716
00717
00718
00719
00720
00721 plm_wr( pdf_wr_header( pls->pdfs, "xdpi" ) );
00722 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->xdpi ) );
00723
00724 plm_wr( pdf_wr_header( pls->pdfs, "ydpi" ) );
00725 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->ydpi ) );
00726
00727 plm_wr( pdf_wr_header( pls->pdfs, "xlength" ) );
00728 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->xlength ) );
00729
00730 plm_wr( pdf_wr_header( pls->pdfs, "ylength" ) );
00731 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->ylength ) );
00732
00733 plm_wr( pdf_wr_header( pls->pdfs, "xoffset" ) );
00734 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->xoffset ) );
00735
00736 plm_wr( pdf_wr_header( pls->pdfs, "yoffset" ) );
00737 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->yoffset ) );
00738
00739 plm_wr( pdf_wr_header( pls->pdfs, "" ) );
00740 }
00741
00742 #else
00743 int
00744 pldummy_plmeta()
00745 {
00746 return 0;
00747 }
00748
00749 #endif // PLD_plmeta