PLplot: plmeta.c Source File

PLplot 5.15.0

plmeta.c
Go to the documentation of this file.
1 // Copyright (C) 1991, 1992, 1993, 1994, 1995 Geoffrey Furnish
2 // Copyright (C) 1991, 1992, 1993, 1994, 1995 Maurice LeBrun
3 //
4 // PLplot is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU Library General Public License as published
6 // by the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // PLplot is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Library General Public License for more details.
13 //
14 // You should have received a copy of the GNU Library General Public License
15 // along with PLplot; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 //
18 //--------------------------------------------------------------------------
19 //
20 // This is a metafile writer for PLplot.
21 //
22 //
23 #include "plDevs.h"
24
25 //#define DEBUG
26
27 #ifdef PLD_plmeta
28
29 #define NEED_PLDEBUG
30 #include "plplotP.h"
31 #include "drivers.h"
32 #include "metadefs.h"
33 #include <string.h>
34
35 // Device info
36 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_plmeta = "plmeta:PLplot Native Meta-File:0:plmeta:26:plm\n";
37
38
39 void plD_dispatch_init_plm( PLDispatchTable *pdt );
40
41 void plD_init_plm( PLStream * );
42 void plD_line_plm( PLStream *, short, short, short, short );
43 void plD_polyline_plm( PLStream *, short *, short *, PLINT );
44 void plD_eop_plm( PLStream * );
45 void plD_bop_plm( PLStream * );
46 void plD_tidy_plm( PLStream * );
47 void plD_state_plm( PLStream *, PLINT );
48 void plD_esc_plm( PLStream *, PLINT, void * );
49
50 // Struct to hold device-specific info.
51
52 // Used for constructing error messages
53
54 #define BUFFER_LEN 256
55
56 // Function prototypes
57
58 static void WriteFileHeader( PLStream *pls );
59 static void UpdatePrevPagehdr( PLStream *pls );
60 static void WritePageInfo( PLStream *pls, FPOS_T pp_offset );
61 static void UpdateIndex( PLStream *pls, FPOS_T cp_offset );
62 static void plm_fill( PLStream *pls );
63 static void plm_swin( PLStream *pls );
64 static void plm_text( PLStream *pls, EscText *args );
65
66 // A little function to help with debugging
67
68 #ifdef DEBUG
69 #define DEBUG_PRINT_LOCATION( a ) PrintLocation( pls, a )
70
71 static void PrintLocation( PLStream *pls, char *tag )
72 {
73 int isfile = ( pls->output_type == 0 );
74 if ( isfile )
75 {
76 FILE *file = pls->OutFile;
77 FPOS_T current_offset;
78
79 if ( pl_fgetpos( file, &current_offset ) )
80 plexit( "PrintLocation (plmeta.c): fgetpos call failed" );
81
82 pldebug( tag, "at offset %d in file %s\n",
83 (int) current_offset, pls->FileName );
84 }
85 }
86 #else
87 #define DEBUG_PRINT_LOCATION( a )
88 #endif
89
90 void plD_dispatch_init_plm( PLDispatchTable *pdt )
91 {
92 #ifndef ENABLE_DYNDRIVERS
93 pdt->pl_MenuStr = "PLplot Native Meta-File";
94 pdt->pl_DevName = "plmeta";
95 #endif
96 pdt->pl_type = plDevType_FileOriented;
97 pdt->pl_seq = 26;
98 pdt->pl_init = (plD_init_fp) plD_init_plm;
99 pdt->pl_line = (plD_line_fp) plD_line_plm;
100 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_plm;
101 pdt->pl_eop = (plD_eop_fp) plD_eop_plm;
102 pdt->pl_bop = (plD_bop_fp) plD_bop_plm;
103 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_plm;
104 pdt->pl_state = (plD_state_fp) plD_state_plm;
105 pdt->pl_esc = (plD_esc_fp) plD_esc_plm;
106 }
107
108 //--------------------------------------------------------------------------
109 // plD_init_plm()
110 //
111 // Initialize device.
112 //--------------------------------------------------------------------------
113
114 void
115 plD_init_plm( PLStream *pls )
116 {
117 PLmDev *dev;
118
119 dbug_enter( "plD_init_plm" );
120
121 pls->color = 1; // Is a color device
122 pls->dev_fill0 = 1; // Handle solid fills
123 pls->dev_fill1 = 1; // Driver handles pattern fills
124
125 if ( strncmp( PLMETA_VERSION, "2005", 4 ) == 0 )
126 {
127 pls->dev_text = 0; // Disable text handling by the driver
128 pls->dev_unicode = 0; // Disable unicode support
129 pls->dev_hrshsym = 0;
130 }
131 else
132 {
133 // NOTE: This breaks compatibility with the 2005 version of
134 // the plot metafile format
135 // Unicode support is not needed because the plmeta driver
136 // stores the unprocessed string data that was passed to PLplot.
137 // However, we turn it on to force unicode representation of the
138 // plot symbols in plsym.c rather than vectorization.
139 pls->dev_text = 1; // Enable text handling by the driver
140 pls->dev_unicode = 1; // Enable unicode support
141 pls->dev_hrshsym = 0; // Disable vectorizaton of Hershey symbols
142 }
143
144 // Initialize family file info
145
146 plFamInit( pls );
147
148 // Prompt for a file name if not already set
149
150 plOpenFile( pls );
151 pls->pdfs = pdf_finit( pls->OutFile );
152
153 // Allocate and initialize device-specific data
154
155 pls->dev = calloc( 1, (size_t) sizeof ( PLmDev ) );
156 if ( pls->dev == NULL )
157 plexit( "plD_init_plm: Out of memory." );
158
159 dev = (PLmDev *) pls->dev;
160
161 dev->xold = PL_UNDEFINED;
162 dev->yold = PL_UNDEFINED;
163
164 dev->xmin = 0;
165 dev->xmax = PIXELS_X - 1;
166 dev->ymin = 0;
167 dev->ymax = PIXELS_Y - 1;
168
169 dev->pxlx = (double) PIXELS_X / (double) LPAGE_X;
170 dev->pxly = (double) PIXELS_Y / (double) LPAGE_Y;
171
172 plP_setpxl( dev->pxlx, dev->pxly );
173 plP_setphy( dev->xmin, dev->xmax, dev->ymin, dev->ymax );
174
175 // Write Metafile header.
176
177 WriteFileHeader( pls );
178
179 // Write color map state info
180
181 plD_state_plm( pls, PLSTATE_CMAP0 );
182 plD_state_plm( pls, PLSTATE_CMAP1 );
183
184 // Write initialization command.
185
186 DEBUG_PRINT_LOCATION( "before init" );
187 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) INITIALIZE ) );
188 }
189
190 //--------------------------------------------------------------------------
191 // plD_line_plm()
192 //
193 // Draw a line in the current color from (x1,y1) to (x2,y2).
194 //--------------------------------------------------------------------------
195
196 void
197 plD_line_plm( PLStream *pls, short x1, short y1, short x2, short y2 )
198 {
199 PLmDev *dev = (PLmDev *) pls->dev;
200 U_SHORT xy[4];
201
202 // dbug_enter("plD_line_plm");
203
204 // Failsafe check
205
206 #ifdef DEBUG
207 if ( x1 < dev->xmin || x1 > dev->xmax ||
208 x2 < dev->xmin || x2 > dev->xmax ||
209 y1 < dev->ymin || y1 > dev->ymax ||
210 y2 < dev->ymin || y2 > dev->ymax )
211 {
212 pldebug( "plD_line_plm",
213 "coordinates out of bounds -- \nActual: (%i,%i), (%i,%i) Bounds: (%i,%i,%i,%i)\n",
214 x1, y1, x2, y2, dev->xmin, dev->xmax, dev->ymin, dev->ymax );
215 }
216 #endif
217
218 // If continuation of previous line send the LINETO command, which uses
219 // the previous (x,y) point as it's starting location. This results in a
220 // storage reduction of not quite 50%, since the instruction length for
221 // a LINETO is 5/9 of that for the LINE command, and given that most
222 // graphics applications use this command heavily.
223 //
224 // Still not quite as efficient as tektronix format since we also send the
225 // command each time (so shortest command is 25% larger), but a lot easier
226 // to implement than the tek method.
227 //
228 if ( x1 == dev->xold && y1 == dev->yold )
229 {
230 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) LINETO ) );
231
232 xy[0] = x2;
233 xy[1] = y2;
234 plm_wr( pdf_wr_2nbytes( pls->pdfs, xy, 2 ) );
235 }
236 else
237 {
238 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) LINE ) );
239
240 xy[0] = x1;
241 xy[1] = y1;
242 xy[2] = x2;
243 xy[3] = y2;
244 plm_wr( pdf_wr_2nbytes( pls->pdfs, xy, 4 ) );
245 }
246 dev->xold = x2;
247 dev->yold = y2;
248 }
249
250 //--------------------------------------------------------------------------
251 // plD_polyline_plm()
252 //
253 // Draw a polyline in the current color.
254 //--------------------------------------------------------------------------
255
256 void
257 plD_polyline_plm( PLStream *pls, short *xa, short *ya, PLINT npts )
258 {
259 PLmDev *dev = (PLmDev *) pls->dev;
260
261 dbug_enter( "plD_polyline_plm" );
262
263 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) POLYLINE ) );
264
265 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) npts ) );
266
267 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) xa, npts ) );
268 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) ya, npts ) );
269
270 dev->xold = xa[npts - 1];
271 dev->yold = ya[npts - 1];
272 }
273
274 //--------------------------------------------------------------------------
275 // plD_eop_plm()
276 //
277 // End of page.
278 //--------------------------------------------------------------------------
279
280 void
281 plD_eop_plm( PLStream *pls )
282 {
283 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) EOP ) );
284 }
285
286 //--------------------------------------------------------------------------
287 // plD_bop_plm()
288 //
289 // Set up for the next page.
290 //
291 // Page header layout as follows:
292 //
293 // BOP (U_CHAR)
294 // page number (U_SHORT)
295 // prev page offset (U_LONG)
296 // next page offset (U_LONG)
297 //
298 // Each call after the first is responsible for updating the table of
299 // contents and the next page offset from the previous page.
300 //--------------------------------------------------------------------------
301
302 void
303 plD_bop_plm( PLStream *pls )
304 {
305 PLmDev *dev = (PLmDev *) pls->dev;
306 int isfile = ( pls->output_type == 0 );
307 FPOS_T pp_offset = dev->lp_offset;
308
309 dbug_enter( "plD_bop_plm" );
310
311 dev->xold = PL_UNDEFINED;
312 dev->yold = PL_UNDEFINED;
313
314 // Update previous page header
315
316 if ( isfile )
317 UpdatePrevPagehdr( pls );
318
319 // Start next family file if necessary.
320
321 pls->bytecnt = pls->pdfs->bp;
322 plGetFam( pls );
323
324 // Update page counter
325
326 pls->page++;
327
328 // Update table of contents info & write new page header.
329
330 WritePageInfo( pls, pp_offset );
331 }
332
333 //--------------------------------------------------------------------------
334 // plD_tidy_plm()
335 //
336 // Close graphics file
337 //--------------------------------------------------------------------------
338
339 void
340 plD_tidy_plm( PLStream *pls )
341 {
342 dbug_enter( "plD_tidy_plm" );
343
344 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) CLOSE ) );
345 pdf_close( pls->pdfs );
346 free_mem( pls->dev );
347 }
348
349 //--------------------------------------------------------------------------
350 // plD_state_plm()
351 //
352 // Handle change in PLStream state (color, pen width, fill attribute, etc).
353 //--------------------------------------------------------------------------
354
355 void
356 plD_state_plm( PLStream *pls, PLINT op )
357 {
358 int i;
359
360 dbug_enter( "plD_state_plm" );
361
362 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) CHANGE_STATE ) );
363 plm_wr( pdf_wr_1byte( pls->pdfs, op ) );
364
365 switch ( op )
366 {
367 case PLSTATE_WIDTH:
368 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) ( pls->width ) ) );
369 break;
370
371 case PLSTATE_COLOR0:
372 plm_wr( pdf_wr_2bytes( pls->pdfs, (short) pls->icol0 ) );
373
374 if ( pls->icol0 == PL_RGB_COLOR )
375 {
376 plm_wr( pdf_wr_1byte( pls->pdfs, pls->curcolor.r ) );
377 plm_wr( pdf_wr_1byte( pls->pdfs, pls->curcolor.g ) );
378 plm_wr( pdf_wr_1byte( pls->pdfs, pls->curcolor.b ) );
379 }
380 break;
381
382 case PLSTATE_COLOR1:
383 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->icol1 ) );
384 break;
385
386 case PLSTATE_FILL:
387 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) pls->patt ) );
388 break;
389
390 case PLSTATE_CMAP0:
391 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->ncol0 ) );
392 for ( i = 0; i < pls->ncol0; i++ )
393 {
394 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap0[i].r ) );
395 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap0[i].g ) );
396 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap0[i].b ) );
397 }
398 break;
399
400 case PLSTATE_CMAP1:
401 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->ncol1 ) );
402 for ( i = 0; i < pls->ncol1; i++ )
403 {
404 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap1[i].r ) );
405 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap1[i].g ) );
406 plm_wr( pdf_wr_1byte( pls->pdfs, pls->cmap1[i].b ) );
407 }
408 break;
409
410 case PLSTATE_CHR:
411 // save the chrdef and chrht parameters
412 if ( strncmp( PLMETA_VERSION, "2005", 4 ) != 0 )
413 {
414 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->chrdef ) );
415 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->chrht ) );
416 }
417 break;
418
419 case PLSTATE_SYM:
420 // save the symdef and symht parameters
421 if ( strncmp( PLMETA_VERSION, "2005", 4 ) != 0 )
422 {
423 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->symdef ) );
424 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->symht ) );
425 }
426 break;
427 }
428 }
429
430 //--------------------------------------------------------------------------
431 // plD_esc_plm()
432 //
433 // Escape function. Note that any data written must be in device
434 // independent form to maintain the transportability of the metafile.
435 //
436 // Functions:
437 //
438 // PLESC_FILL Fill polygon
439 // PLESC_SWIN Set window parameters
440 //
441 //--------------------------------------------------------------------------
442
443 void
444 plD_esc_plm( PLStream *pls, PLINT op, void *ptr )
445 {
446 dbug_enter( "plD_esc_plm" );
447
448 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) ESCAPE ) );
449 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) op ) );
450
451 switch ( op )
452 {
453 case PLESC_FILL:
454 plm_fill( pls );
455 break;
456
457 case PLESC_SWIN:
458 plm_swin( pls );
459 break;
460
461 // Unicode and non-Unicode text handling
462 case PLESC_HAS_TEXT:
463 plm_text( pls, (EscText *) ptr );
464 break;
465
466 // Alternate unicode text handling
467 case PLESC_BEGIN_TEXT:
468 case PLESC_TEXT_CHAR:
469 case PLESC_CONTROL_CHAR:
470 case PLESC_END_TEXT:
471 // NOP these for now until a decision is made
472 // which method should be implemented for metafiles
473 plwarn( "plmeta: Alternate Unicode text handling is not implemented" );
474 break;
475 }
476 }
477
478 //--------------------------------------------------------------------------
479 // Private functions
480 //--------------------------------------------------------------------------
481
482 //--------------------------------------------------------------------------
483 // plm_fill()
484 //
485 // Fill polygon described in points pls->dev_x[] and pls->dev_y[].
486 //--------------------------------------------------------------------------
487
488 static void
489 plm_fill( PLStream *pls )
490 {
491 PLmDev *dev = (PLmDev *) pls->dev;
492
493 dbug_enter( "plm_fill" );
494
495 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->dev_npts ) );
496
497 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) pls->dev_x, pls->dev_npts ) );
498 plm_wr( pdf_wr_2nbytes( pls->pdfs, (U_SHORT *) pls->dev_y, pls->dev_npts ) );
499
500 dev->xold = PL_UNDEFINED;
501 dev->yold = PL_UNDEFINED;
502 }
503
504 //--------------------------------------------------------------------------
505 // plm_swin()
506 //
507 // Set window parameters.
508 // Each parameter or group of parameters is tagged to make backward
509 // compatibility easier.
510 //--------------------------------------------------------------------------
511
512 static void
513 plm_swin( PLStream *pls )
514 {
515 dbug_enter( "plm_swin" );
516 }
517
518 //--------------------------------------------------------------------------
519 // plm_text()
520 //
521 // Stores the text into the metafile.
522 //--------------------------------------------------------------------------
523
524 static void
525 plm_text( PLStream *pls, EscText *args )
526 {
527 PLmDev *dev = (PLmDev *) pls->dev;
528 size_t len;
529
530 // Write state information needed to render the text
531
532 plm_wr( pdf_wr_ieeef( pls->pdfs, pls->chrht ) );
533 plm_wr( pdf_wr_ieeef( pls->pdfs, pls->diorot ) );
534 plm_wr( pdf_wr_2bytes( pls->pdfs, pls->clpxmi ) );
535 plm_wr( pdf_wr_2bytes( pls->pdfs, pls->clpxma ) );
536 plm_wr( pdf_wr_2bytes( pls->pdfs, pls->clpymi ) );
537 plm_wr( pdf_wr_2bytes( pls->pdfs, pls->clpyma ) );
538
539 // Write the text layout information
540
541 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) args->base ) );
542 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) args->just ) );
543
544 // Do we have a rotation shear that needs to be saved
545 if ( args->xform != NULL )
546 {
547 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) args->xform[0] ) );
548 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) args->xform[1] ) );
549 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) args->xform[2] ) );
550 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) args->xform[3] ) );
551 }
552 else
553 {
554 plwarn( "plmeta: transformation matrix undefined, using a guess" );
555 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) 1.0 ) );
556 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) 0.0 ) );
557 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) 0.0 ) );
558 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) 1.0 ) );
559 }
560
561 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) args->x ) );
562 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) args->y ) );
563 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) args->refx ) );
564 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) args->refy ) );
565 plm_wr( pdf_wr_1byte( pls->pdfs, (U_CHAR) args->font_face ) );
566 plm_wr( pdf_wr_4bytes( pls->pdfs, (int) args->text_type ) );
567
568 // Was a text string passed or a plot symbol?
569 if ( args->text_type == PL_STRING_TEXT )
570 {
571 // Text string
572 len = strlen( args->string );
573 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) len ) );
574 if ( len > 0 )
575 plm_wr( pdf_wr_string( pls->pdfs, args->string ) );
576 }
577 else
578 {
579 // Plot symbol
580 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) args->symbol ) );
581 }
582
583 // Clear the last known position
584 dev->xold = PL_UNDEFINED;
585 dev->yold = PL_UNDEFINED;
586 }
587
588 //--------------------------------------------------------------------------
589 // Provide a consistent method for handling a failed fsetpos.
590 //--------------------------------------------------------------------------
591 static void
592 handle_fsetpos_failed( const char *where, const char *which, FPOS_T position )
593 {
594 char buffer[BUFFER_LEN];
595
596 // Format a standard message detailing the failure location
597 snprintf( buffer, BUFFER_LEN,
598 "%s: fsetpos to %s (%lu) failed",
599 where,
600 which,
601 (unsigned long) position );
602
603 plexit( buffer );
604 }
605
606 //--------------------------------------------------------------------------
607 // WriteFileHeader()
608 //
609 // Writes Metafile header.
610 //--------------------------------------------------------------------------
611
612 static void
613 WriteFileHeader( PLStream *pls )
614 {
615 PLmDev *dev = (PLmDev *) pls->dev;
616 FILE *file = pls->OutFile;
617 int isfile = ( pls->output_type == 0 );
618
619 dbug_enter( "WriteFileHeader(PLStream *pls" );
620
621 plm_wr( pdf_wr_header( pls->pdfs, PLMETA_HEADER ) );
622 plm_wr( pdf_wr_header( pls->pdfs, PLMETA_VERSION ) );
623
624 // Write file index info. Right now only number of pages.
625 // The order here is critical
626
627 if ( isfile )
628 {
629 // Save the position of the pages field so that it can
630 // be updated when a new page is created
631 if ( pl_fgetpos( file, &dev->index_offset ) )
632 plexit( "WriteFileHeader: fgetpos call failed" );
633 }
634
635 plm_wr( pdf_wr_header( pls->pdfs, "pages" ) );
636 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) 0 ) );
637
638 // Write initialization info. Tag via strings to make backward
639 // compatibility with old metafiles as easy as possible.
640
641 plm_wr( pdf_wr_header( pls->pdfs, "xmin" ) );
642 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->xmin ) );
643
644 plm_wr( pdf_wr_header( pls->pdfs, "xmax" ) );
645 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->xmax ) );
646
647 plm_wr( pdf_wr_header( pls->pdfs, "ymin" ) );
648 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->ymin ) );
649
650 plm_wr( pdf_wr_header( pls->pdfs, "ymax" ) );
651 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) dev->ymax ) );
652
653 plm_wr( pdf_wr_header( pls->pdfs, "pxlx" ) );
654 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) dev->pxlx ) );
655
656 plm_wr( pdf_wr_header( pls->pdfs, "pxly" ) );
657 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) dev->pxly ) );
658
659 // Geometry info, needed to properly transmit e.g. aspect ratio, via the
660 // length params. Not sure if the others are useful, but they're included
661 // for completeness.
662
663 plm_wr( pdf_wr_header( pls->pdfs, "xdpi" ) );
664 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->xdpi ) );
665
666 plm_wr( pdf_wr_header( pls->pdfs, "ydpi" ) );
667 plm_wr( pdf_wr_ieeef( pls->pdfs, (float) pls->ydpi ) );
668
669 plm_wr( pdf_wr_header( pls->pdfs, "xlength" ) );
670 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->xlength ) );
671
672 plm_wr( pdf_wr_header( pls->pdfs, "ylength" ) );
673 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->ylength ) );
674
675 plm_wr( pdf_wr_header( pls->pdfs, "xoffset" ) );
676 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->xoffset ) );
677
678 plm_wr( pdf_wr_header( pls->pdfs, "yoffset" ) );
679 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->yoffset ) );
680
681 plm_wr( pdf_wr_header( pls->pdfs, "" ) );
682 }
683
684 //--------------------------------------------------------------------------
685 // WritePageInfo()
686 //
687 // Update table of contents info & write new page header.
688 //--------------------------------------------------------------------------
689
690 static void
691 WritePageInfo( PLStream *pls, FPOS_T pp_offset )
692 {
693 PLmDev *dev = (PLmDev *) pls->dev;
694 FILE *file = pls->OutFile;
695 int isfile = ( pls->output_type == 0 );
696 U_CHAR c;
697 FPOS_T cp_offset = 0;
698
699 // Update table of contents.
700
701 if ( isfile )
702 {
703 // Get the position of this page in order to update the index
704 if ( pl_fgetpos( file, &cp_offset ) )
705 plexit( "WritePageInfo (plmeta.c): fgetpos call failed" );
706
707 UpdateIndex( pls, cp_offset );
708 }
709
710 // Write new page header
711
712 if ( dev->notfirst )
713 c = BOP;
714 else
715 {
716 c = BOP0;
717 dev->notfirst = 1;
718 }
719 plm_wr( pdf_wr_1byte( pls->pdfs, c ) );
720 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->page ) );
721 plm_wr( pdf_wr_4bytes( pls->pdfs, (U_LONG) pp_offset ) );
722 plm_wr( pdf_wr_4bytes( pls->pdfs, (U_LONG) 0 ) );
723
724 // Update last page offset with current page value
725
726 dev->lp_offset = cp_offset;
727
728 // Write some page state information just to make things nice later on
729 // Eventually there will be more
730
731 plD_state_plm( pls, PLSTATE_COLOR0 );
732 }
733
734 //--------------------------------------------------------------------------
735 // UpdatePrevPagehdr()
736 //
737 // Update previous page header.
738 //--------------------------------------------------------------------------
739
740 static void
741 UpdatePrevPagehdr( PLStream *pls )
742 {
743 PLmDev *dev = (PLmDev *) pls->dev;
744 FILE *file = pls->OutFile;
745 FPOS_T cp_offset = 0;
746
747 fflush( file );
748
749 // Determine where we are
750
751 if ( pl_fgetpos( file, &cp_offset ) )
752 plexit( "plD_bop_plm: fgetpos call failed" );
753
754 // Seek back to previous page header.
755
756 if ( dev->lp_offset > 0 )
757 {
758 FPOS_T fwbyte_offset = 0;
759
760 pldebug( "UpdatePrevPagehdr 1 (plmeta.c)",
761 "Location: %d, seeking to: %d\n",
762 (int) cp_offset, (int) dev->lp_offset );
763
764 // The forward byte offset is located exactly 7 bytes after the BOP
765 fwbyte_offset = dev->lp_offset + 7;
766 if ( pl_fsetpos( file, &fwbyte_offset ) )
767 {
768 handle_fsetpos_failed( "UpdatePrevPagehdr",
769 "fwbyte_offset", fwbyte_offset );
770 }
771
772 // DEBUG: verify current location
773
774 #ifdef DEBUG
775 if ( pl_fgetpos( file, &fwbyte_offset ) )
776 plexit( "UpdatePrevPagehdr (plmeta.c): fgetpos call failed" );
777
778 pldebug( "UpdatePrevPagehdr 2 (plmeta.c)",
779 "Now at: %d, to write: %d\n",
780 (int) fwbyte_offset, (int) cp_offset );
781 #endif
782
783 // Write forward byte offset into previous page header.
784
785 plm_wr( pdf_wr_4bytes( pls->pdfs, (U_LONG) cp_offset ) );
786 fflush( file );
787
788 // DEBUG: move back to before the write & read it to verify
789
790 #ifdef DEBUG
791 if ( pl_fsetpos( file, &fwbyte_offset ) )
792 {
793 handle_fsetpos_failed( "UpdatePrevPagehdr",
794 "fwbyte_offset", fwbyte_offset );
795 }
796 {
797 U_LONG read_offset;
798 plm_rd( pdf_rd_4bytes( pls->pdfs, &read_offset ) );
799 pldebug( "UpdatePrevPagehdr 3 (plmeta.c)",
800 "Value read as: %d\n", read_offset );
801 }
802 #endif
803
804 // Return to current page offset
805
806 if ( pl_fsetpos( file, &cp_offset ) )
807 {
808 handle_fsetpos_failed( "UpdatePrevPagehdr",
809 "cp_offset", cp_offset );
810 }
811 }
812 }
813
814 //--------------------------------------------------------------------------
815 // UpdateIndex()
816 //
817 // Update file index.
818 //--------------------------------------------------------------------------
819
820 static void
821 UpdateIndex( PLStream *pls, FPOS_T cp_offset )
822 {
823 PLmDev *dev = (PLmDev *) pls->dev;
824 FILE *file = pls->OutFile;
825
826 // Update file index. Right now only number of pages.
827 // The ordering here is critical
828
829 if ( dev->index_offset > 0 )
830 {
831 pldebug( "UpdateIndex (plmeta.c)",
832 "Location: %d, seeking to: %d\n",
833 (int) cp_offset, (int) dev->lp_offset );
834
835 if ( pl_fsetpos( file, &dev->index_offset ) )
836 {
837 handle_fsetpos_failed( "UpdateIndex",
838 "index_offset", dev->index_offset );
839 }
840 plm_wr( pdf_wr_header( pls->pdfs, "pages" ) );
841 plm_wr( pdf_wr_2bytes( pls->pdfs, (U_SHORT) pls->page ) );
842
843 pldebug( "UpdateIndex (plmeta.c)",
844 "Location: %d, seeking to: %d\n",
845 (int) dev->lp_offset, (int) cp_offset );
846
847 if ( pl_fsetpos( file, &cp_offset ) )
848 {
849 handle_fsetpos_failed( "UpdateIndex",
850 "cp_offset", cp_offset );
851 }
852 }
853 }
854
855 #else
856 int
857 pldummy_plmeta()
858 {
859 return 0;
860 }
861
862 #endif // PLD_plmeta
plplotP.h
pdf_finit
PDFstrm * pdf_finit(FILE *file)
Definition: pdfutils.c:204
PLSTATE_CMAP0
#define PLSTATE_CMAP0
Definition: plplotP.h:366
PLmDev::pxlx
PLFLT pxlx
Definition: metadefs.h:88
pdf_wr_4bytes
int pdf_wr_4bytes(PDFstrm *pdfs, U_LONG s)
Definition: pdfutils.c:804
plexit
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
LINETO
#define LINETO
Definition: metadefs.h:62
PLStream::icol1
PLINT icol1
Definition: plstrm.h:539
PLESC_CONTROL_CHAR
#define PLESC_CONTROL_CHAR
Definition: plplot.h:300
FPOS_T
#define FPOS_T
Definition: plplotP.h:141
EscText::just
PLFLT just
Definition: plplotP.h:708
BOP0
#define BOP0
Definition: metadefs.h:69
PLColor::b
unsigned char b
Definition: plplot.h:550
PLSTATE_SYM
#define PLSTATE_SYM
Definition: plplotP.h:369
PLStream::dev_fill1
PLINT dev_fill1
Definition: plstrm.h:571
DEBUG
#define DEBUG
Definition: plcore.c:43
PLStream::OutFile
FILE * OutFile
Definition: plstrm.h:575
PLESC_FILL
#define PLESC_FILL
Definition: plplot.h:279
PL_RGB_COLOR
#define PL_RGB_COLOR
Definition: plplotP.h:285
pdf_wr_header
int pdf_wr_header(PDFstrm *pdfs, PLCHAR_VECTOR header)
Definition: pdfutils.c:509
INITIALIZE
#define INITIALIZE
Definition: metadefs.h:53
PLDispatchTable::pl_esc
plD_esc_fp pl_esc
Definition: disptab.h:90
pdf_wr_string
int pdf_wr_string(PDFstrm *pdfs, PLCHAR_VECTOR string)
Definition: pdfutils.c:574
plOpenFile
void plOpenFile(PLStream *pls)
Definition: plctrl.c:2571
pdf_wr_2bytes
int pdf_wr_2bytes(PDFstrm *pdfs, U_SHORT s)
Definition: pdfutils.c:684
plDevType_FileOriented
Definition: disptab.h:13
pl_fsetpos
#define pl_fsetpos(a, b)
Definition: plplotP.h:142
pl_fgetpos
#define pl_fgetpos(a, b)
Definition: plplotP.h:143
pdf_wr_2nbytes
int pdf_wr_2nbytes(PDFstrm *pdfs, U_SHORT *s, PLINT n)
Definition: pdfutils.c:741
plGetFam
void plGetFam(PLStream *pls)
Definition: plctrl.c:2780
plD_tidy_fp
void(* plD_tidy_fp)(struct PLStream_struct *)
Definition: disptab.h:72
PLDispatchTable::pl_seq
int pl_seq
Definition: disptab.h:82
PLmDev::pxly
PLFLT pxly
Definition: metadefs.h:88
PLStream::xdpi
PLFLT xdpi
Definition: plstrm.h:616
PLStream::dev_text
PLINT dev_text
Definition: plstrm.h:572
PLStream::dev_npts
PLINT dev_npts
Definition: plstrm.h:581
PLDispatchTable::pl_MenuStr
const char * pl_MenuStr
Definition: disptab.h:79
PLStream::color
PLINT color
Definition: plstrm.h:569
PLStream::dev_unicode
PLINT dev_unicode
Definition: plstrm.h:747
PLESC_END_TEXT
#define PLESC_END_TEXT
Definition: plplot.h:301
PLDispatchTable::pl_tidy
plD_tidy_fp pl_tidy
Definition: disptab.h:88
plD_init_fp
void(* plD_init_fp)(struct PLStream_struct *)
Definition: disptab.h:67
PLStream::diorot
PLFLT diorot
Definition: plstrm.h:661
plD_eop_fp
void(* plD_eop_fp)(struct PLStream_struct *)
Definition: disptab.h:70
PLDispatchTable::pl_DevName
const char * pl_DevName
Definition: disptab.h:80
PLSTATE_COLOR0
#define PLSTATE_COLOR0
Definition: plplotP.h:363
PLmDev::notfirst
int notfirst
Definition: metadefs.h:97
PLDispatchTable::pl_init
plD_init_fp pl_init
Definition: disptab.h:83
PLSTATE_COLOR1
#define PLSTATE_COLOR1
Definition: plplotP.h:364
U_SHORT
#define U_SHORT
Definition: pdf.h:30
PLmDev::xmin
PLINT xmin
Definition: metadefs.h:91
PLStream::cmap1
PLColor * cmap1
Definition: plstrm.h:545
plm_rd
#define plm_rd(code)
Definition: metadefs.h:41
PLStream::dev_x
short * dev_x
Definition: plstrm.h:582
PLESC_TEXT_CHAR
#define PLESC_TEXT_CHAR
Definition: plplot.h:299
plFamInit
void plFamInit(PLStream *pls)
Definition: plctrl.c:2751
PLSTATE_WIDTH
#define PLSTATE_WIDTH
Definition: plplotP.h:362
PLStream::pdfs
PDFstrm * pdfs
Definition: plstrm.h:579
PLmDev::xmax
PLINT xmax
Definition: metadefs.h:91
CLOSE
#define CLOSE
Definition: metadefs.h:54
PLINT
int PLINT
Definition: plplot.h:181
PLSTATE_FILL
#define PLSTATE_FILL
Definition: plplotP.h:365
plD_line_fp
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
Definition: disptab.h:68
EscText::refy
PLINT refy
Definition: plplotP.h:717
PLStream::ncol0
PLINT ncol0
Definition: plstrm.h:539
PLColor::g
unsigned char g
Definition: plplot.h:549
PLMETA_VERSION
#define PLMETA_VERSION
Definition: metadefs.h:17
PLmDev::ymax
PLINT ymax
Definition: metadefs.h:92
plD_esc_fp
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
Definition: disptab.h:74
EscText
Definition: plplotP.h:699
PLStream::clpymi
PLINT clpymi
Definition: plstrm.h:704
plD_polyline_fp
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
Definition: disptab.h:69
snprintf
#define snprintf
Definition: plplotP.h:235
PLSTATE_CMAP1
#define PLSTATE_CMAP1
Definition: plplotP.h:367
PLStream::icol0
PLINT icol0
Definition: plstrm.h:539
PIXELS_X
#define PIXELS_X
Definition: plplotP.h:304
dbug_enter
#define dbug_enter(a)
Definition: tclMatrix.c:59
EscText::text_type
enum EscText::@5 text_type
PLStream::dev_hrshsym
PLINT dev_hrshsym
Definition: plstrm.h:753
PLStream::ylength
PLINT ylength
Definition: plstrm.h:617
ESCAPE
#define ESCAPE
Definition: metadefs.h:63
U_LONG
#define U_LONG
Definition: pdf.h:38
PLDispatchTable
Definition: disptab.h:77
PLStream::FileName
char * FileName
Definition: plstrm.h:576
PLDispatchTable::pl_bop
plD_bop_fp pl_bop
Definition: disptab.h:87
EOP
#define EOP
Definition: metadefs.h:57
pldummy_plmeta
int pldummy_plmeta()
Definition: plmeta.c:857
PLmDev::lp_offset
FPOS_T lp_offset
Definition: metadefs.h:95
LPAGE_Y
#define LPAGE_Y
Definition: plplotP.h:309
PLStream::symdef
PLFLT symdef
Definition: plstrm.h:687
PLDispatchTable::pl_line
plD_line_fp pl_line
Definition: disptab.h:84
PLMETA_HEADER
#define PLMETA_HEADER
Definition: metadefs.h:16
buffer
static PLINT * buffer
Definition: plfill.c:74
PL_UNDEFINED
#define PL_UNDEFINED
Definition: plplotP.h:219
plP_setpxl
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
Definition: plcore.c:4238
PLStream::cmap0
PLColor * cmap0
Definition: plstrm.h:544
drivers.h
plDevs.h
PLDLLIMPEXP_DRIVER
#define PLDLLIMPEXP_DRIVER
Definition: pldll.h:81
PLStream::ydpi
PLFLT ydpi
Definition: plstrm.h:616
PLStream::clpxmi
PLINT clpxmi
Definition: plstrm.h:704
pls
static PLStream * pls[PL_NSTREAMS]
Definition: plcore.h:88
plP_setphy
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
Definition: plcore.c:4249
PLmDev
Definition: metadefs.h:86
PLStream::xlength
PLINT xlength
Definition: plstrm.h:617
PLESC_BEGIN_TEXT
#define PLESC_BEGIN_TEXT
Definition: plplot.h:298
LPAGE_X
#define LPAGE_X
Definition: plplotP.h:308
LINE
#define LINE
Definition: metadefs.h:61
PLStream::yoffset
PLINT yoffset
Definition: plstrm.h:618
PLStream::dev_y
short * dev_y
Definition: plstrm.h:582
PLStream
Definition: plstrm.h:523
pdf_wr_ieeef
int pdf_wr_ieeef(PDFstrm *pdfs, float f)
Definition: pdfutils.c:916
EscText::refx
PLINT refx
Definition: plplotP.h:716
PLmDev::index_offset
FPOS_T index_offset
Definition: metadefs.h:94
PIXELS_Y
#define PIXELS_Y
Definition: plplotP.h:305
PLESC_SWIN
#define PLESC_SWIN
Definition: plplot.h:284
pdf_close
int pdf_close(PDFstrm *pdfs)
Definition: pdfutils.c:238
PLStream::chrht
PLFLT chrht
Definition: plstrm.h:686
PLStream::page
PLINT page
Definition: plstrm.h:578
plD_bop_fp
void(* plD_bop_fp)(struct PLStream_struct *)
Definition: disptab.h:71
EscText::symbol
PLINT symbol
Definition: plplotP.h:740
free_mem
#define free_mem(a)
Definition: plplotP.h:182
plD_dispatch_init_plm
PLDLLIMPEXP_DRIVER void plD_dispatch_init_plm(PLDispatchTable *pdt)
plm_wr
#define plm_wr(code)
Definition: metadefs.h:38
PLStream::patt
PLINT patt
Definition: plstrm.h:669
PLmDev::xold
PLINT xold
Definition: metadefs.h:89
PLSTATE_CHR
#define PLSTATE_CHR
Definition: plplotP.h:368
PLColor::r
unsigned char r
Definition: plplot.h:548
PLESC_HAS_TEXT
#define PLESC_HAS_TEXT
Definition: plplot.h:290
PLStream::width
PLFLT width
Definition: plstrm.h:552
plwarn
void plwarn(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1863
EscText::y
PLINT y
Definition: plplotP.h:713
CHANGE_STATE
#define CHANGE_STATE
Definition: metadefs.h:68
PLStream::curcolor
PLColor curcolor
Definition: plstrm.h:543
PLDispatchTable::pl_state
plD_state_fp pl_state
Definition: disptab.h:89
PLStream::clpxma
PLINT clpxma
Definition: plstrm.h:704
EscText::string
const char * string
Definition: plplotP.h:739
POLYLINE
#define POLYLINE
Definition: metadefs.h:65
PLDispatchTable::pl_eop
plD_eop_fp pl_eop
Definition: disptab.h:86
PDFstrm::bp
size_t bp
Definition: pdf.h:56
PLStream::xoffset
PLINT xoffset
Definition: plstrm.h:618
PLStream::ncol1
PLINT ncol1
Definition: plstrm.h:539
EscText::x
PLINT x
Definition: plplotP.h:712
PLStream::chrdef
PLFLT chrdef
Definition: plstrm.h:686
PLStream::symht
PLFLT symht
Definition: plstrm.h:687
pdf_rd_4bytes
int pdf_rd_4bytes(PDFstrm *pdfs, U_LONG *ps)
Definition: pdfutils.c:832
PLDispatchTable::pl_polyline
plD_polyline_fp pl_polyline
Definition: disptab.h:85
plD_state_fp
void(* plD_state_fp)(struct PLStream_struct *, PLINT)
Definition: disptab.h:73
PLStream::dev
void * dev
Definition: plstrm.h:594
EscText::font_face
char font_face
Definition: plplotP.h:720
BOP
#define BOP
Definition: metadefs.h:58
PLStream::bytecnt
PLINT bytecnt
Definition: plstrm.h:578
pdf_wr_1byte
int pdf_wr_1byte(PDFstrm *pdfs, U_CHAR s)
Definition: pdfutils.c:636
PLStream::dev_fill0
PLINT dev_fill0
Definition: plstrm.h:571
PLmDev::yold
PLINT yold
Definition: metadefs.h:89
PLDispatchTable::pl_type
int pl_type
Definition: disptab.h:81
PLStream::output_type
int output_type
Definition: plstrm.h:577
EscText::xform
PLFLT * xform
Definition: plplotP.h:709
U_CHAR
#define U_CHAR
Definition: pdf.h:26
metadefs.h
EscText::base
PLINT base
Definition: plplotP.h:707
PLStream::clpyma
PLINT clpyma
Definition: plstrm.h:704
PLmDev::ymin
PLINT ymin
Definition: metadefs.h:92