PLplot: plmeta.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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