PLplot 5.15.0
plmetafile.c
Go to the documentation of this file.
1// PLplot metafile I/O routines. Originally implemented in the plmeta
2// driver and plrender. The decision was made to provide the capability
3// to always read/write metafiles, thus the routines have been merged
4// into the core of the library.
5//
6// Copyright (C) 2006 Hazen Babcock
7// Copyright (C) 2015 Jim Dishaw
8
9//
10// This file is part of PLplot.
11//
12// PLplot is free software; you can redistribute it and/or modify
13// it under the terms of the GNU Library General Public License as published
14// by the Free Software Foundation; either version 2 of the License, or
15// (at your option) any later version.
16//
17// PLplot is distributed in the hope that it will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU Library General Public License for more details.
21//
22// You should have received a copy of the GNU Library General Public License
23// along with PLplot; if not, write to the Free Software
24// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25//
26//
27
28#define NEED_PLDEBUG
29#include "plplotP.h"
30#include "metadefs.h"
31#include <stddef.h> // For the offsetof() macro
32
33#define MAX_BUFFER 256 // Character buffer size for reading records
34
35#if defined ( _MSC_VER ) && _MSC_VER <= 1500
36// Older versions of Visual Studio (2005 perhaps 2008) do not define uint8_t
37// The newer versions of Visual Studio will not install on Vista or older
38// versions of Windows.
39typedef unsigned char uint8_t;
40#endif
41
42// Not all platforms support the lround() function and the coordinate system
43// representation is going to be redone, thus this is just a placeholder until
44// everything is sorted out.
45#define PLFLT2COORD( a ) ( (short) ceil( a ) )
46
47// Status codes
49{
57 PLM_SUCCESS = 0
58};
59
60// Portable data format types (perhaps should be defined elsewhere?)
62{
63 PDF_NULL = 0, // No-data type
64 PDF_UBYTE, // one-byte unsigned integer
65 PDF_USHORT, // two-byte unsigned integer
66 PDF_ULONG, // four-byte unsigned integer
67 PDF_IEEEF // IEEE 32 bit floating point
68};
69
70// Data types used by PLplot (perhaps should be defined elsewhere?)
72{
73 PLP_NULL = 0, // No-data type
81};
82
83// Data format entry structure
85{
86 char *name; // Name of the field
87 enum _pdf_types pdf_type; // Field data type in metafile
88 enum _plp_types plp_type; // Field data type in PLplot
89 const size_t offset; // Byte offset in the plmeta device
90};
91
92// Metafile index information header
93static const struct _plm_format index_2005_header[] = {
94 { "pages", PDF_USHORT, PLP_USHORT, offsetof( PLmIndex, pages ) },
95 // Last entry, do not change
96 { NULL, PDF_NULL, PLP_NULL, 0 }
97};
98
99// Device information header
100static const struct _plm_format dev_2005_header[] = {
101 { "xmin", PDF_USHORT, PLP_PLINT, offsetof( PLmDev, xmin ) },
102 { "xmax", PDF_USHORT, PLP_PLINT, offsetof( PLmDev, xmax ) },
103 { "ymin", PDF_USHORT, PLP_PLINT, offsetof( PLmDev, ymin ) },
104 { "ymax", PDF_USHORT, PLP_PLINT, offsetof( PLmDev, ymax ) },
105 { "pxlx", PDF_IEEEF, PLP_PLFLT, offsetof( PLmDev, pxlx ) },
106 { "pxly", PDF_IEEEF, PLP_PLFLT, offsetof( PLmDev, pxly ) },
107 // Last entry, do not change
108 { NULL, PDF_NULL, PLP_NULL, 0 }
109};
110
111// Plot information header
112static const struct _plm_format plot_2005_header[] = {
113 { "xdpi", PDF_IEEEF, PLP_PLFLT, offsetof( PLStream, xdpi ) },
114 { "ydpi", PDF_IEEEF, PLP_PLFLT, offsetof( PLStream, ydpi ) },
115 { "xlength", PDF_USHORT, PLP_PLINT, offsetof( PLStream, xlength ) },
116 { "ylength", PDF_USHORT, PLP_PLINT, offsetof( PLStream, ylength ) },
117 { "xoffset", PDF_USHORT, PLP_PLINT, offsetof( PLStream, xoffset ) },
118 { "yoffset", PDF_USHORT, PLP_PLINT, offsetof( PLStream, yoffset ) },
119 { "", PDF_NULL, PLP_NULL, 0 },
120 // Last entry, do not change
121 { NULL, 0, 0 }
122};
123
124// Page information header
125static const struct _plm_format page_2005_header[] = {
126 { "", PDF_USHORT, PLP_PLINT, offsetof( PLmDev, page ) },
127 { "", PDF_ULONG, PLP_PLINT, offsetof( PLmDev, lp_offset ) },
128 { "", PDF_ULONG, PLP_NULL, 0 }
129};
130
131static struct _plm_version
132{
137} metafile_format[] = {
141
142static
144 void *dest, enum _plp_types type )
145{
146 enum _plm_status rc = PLM_SUCCESS;
147
148 switch ( type )
149 {
150 case PLP_NULL:
151 break;
152 case PLP_UBYTE:
153 *(uint8_t *) dest = x;
154 break;
155 case PLP_UCHAR:
156 *(unsigned char *) dest = x;
157 break;
158 case PLP_USHORT:
159 *(U_SHORT *) dest = x;
160 break;
161 case PLP_SHORT:
162 *(short *) dest = x;
163 break;
164 case PLP_PLINT:
165 *(PLINT *) dest = x;
166 break;
167 case PLP_PLFLT:
168 *(PLFLT *) dest = x;
169 break;
170 case PLP_ULONG:
171 *(U_LONG *) dest = x;
172 break;
173 default:
174 plwarn( "Unhandled datatype conversion in set_plp_value." );
176 break;
177 }
178
179 return rc;
180}
181
182static
184 void *dest, enum _plp_types type )
185{
186 enum _plm_status rc = PLM_SUCCESS;
187
188 switch ( type )
189 {
190 case PLP_NULL:
191 break;
192 case PLP_UBYTE:
193 *(uint8_t *) dest = x;
194 break;
195 case PLP_UCHAR:
196 *(unsigned char *) dest = x;
197 break;
198 case PLP_USHORT:
199 *(U_SHORT *) dest = x;
200 break;
201 case PLP_SHORT:
202 *(short *) dest = x;
203 break;
204 case PLP_PLINT:
205 *(PLINT *) dest = x;
206 break;
207 case PLP_PLFLT:
208 *(PLFLT *) dest = x;
209 break;
210 case PLP_ULONG:
211 *(U_LONG *) dest = x;
212 break;
213 default:
214 plwarn( "Unhandled datatype conversion in set_plp_value." );
216 break;
217 }
218
219 return rc;
220}
221
222static
223enum _plm_status set_ulong_plp_value( unsigned long x,
224 void *dest, enum _plp_types type )
225{
226 enum _plm_status rc = PLM_SUCCESS;
227
228 switch ( type )
229 {
230 case PLP_NULL:
231 break;
232 case PLP_UBYTE:
233 *(uint8_t *) dest = x;
234 break;
235 case PLP_UCHAR:
236 *(unsigned char *) dest = x;
237 break;
238 case PLP_USHORT:
239 *(U_SHORT *) dest = x;
240 break;
241 case PLP_SHORT:
242 *(short *) dest = x;
243 break;
244 case PLP_PLINT:
245 *(PLINT *) dest = x;
246 break;
247 case PLP_PLFLT:
248 *(PLFLT *) dest = x;
249 break;
250 case PLP_ULONG:
251 *(U_LONG *) dest = x;
252 break;
253 default:
254 plwarn( "Unhandled datatype conversion in set_plp_value." );
256 break;
257 }
258
259 return rc;
260}
261
262static
264 void *dest, enum _plp_types type )
265{
266 enum _plm_status rc = PLM_SUCCESS;
267
268 switch ( type )
269 {
270 case PLP_NULL:
271 break;
272 case PLP_UBYTE:
273 *(uint8_t *) dest = x;
274 break;
275 case PLP_UCHAR:
276 *(unsigned char *) dest = x;
277 break;
278 case PLP_USHORT:
279 *(U_SHORT *) dest = x;
280 break;
281 case PLP_SHORT:
282 *(short *) dest = x;
283 break;
284 case PLP_PLINT:
285 *(PLINT *) dest = x;
286 break;
287 case PLP_PLFLT:
288 *(PLFLT *) dest = x;
289 break;
290 case PLP_ULONG:
291 *(U_LONG *) dest = x;
292 break;
293 default:
294 plwarn( "Unhandled datatype conversion in set_plp_value." );
296 break;
297 }
298
299 return rc;
300}
301
302static
304 enum _pdf_types from_type,
305 enum _plp_types to_type,
306 void *dest )
307{
308 uint8_t b;
309 unsigned long l;
310 U_SHORT x;
311 float f;
312 enum _plm_status rc;
313 int pdf_rc = 0;
314
315 switch ( from_type )
316 {
317 case PLP_NULL:
318 pdf_rc = 0;
319 rc = PLM_SUCCESS;
320 break;
321
322 case PDF_UBYTE: // Unsigned one-byte integer
323 if ( ( pdf_rc = pdf_rd_1byte( plm, &b ) ) == 0 )
324 rc = set_ubyte_plp_value( b, dest, to_type );
325 break;
326
327 case PDF_USHORT: // Unsigned two-byte integer
328 if ( ( pdf_rc = pdf_rd_2bytes( plm, &x ) ) == 0 )
329 rc = set_ushort_plp_value( x, dest, to_type );
330 break;
331
332 case PDF_ULONG: // Unsigned four-byte integer
333 if ( ( pdf_rc = pdf_rd_4bytes( plm, &l ) ) == 0 )
334 rc = set_ulong_plp_value( l, dest, to_type );
335 break;
336
337 case PDF_IEEEF: // IEEE 32 bit float
338 if ( ( pdf_rc = pdf_rd_ieeef( plm, &f ) ) == 0 )
339 rc = set_ieeef_plp_value( f, dest, to_type );
340 break;
341
342 default:
343 plwarn( "Unhandled datatype conversion in read_entry." );
345 break;
346 }
347
348 if ( pdf_rc == 0 )
349 return rc;
350 else
351 return PLM_READ_ERROR;
352}
353
354static
356 size_t bytes,
357 char *dest )
358{
359 int rc;
360
361 rc = pdf_rd_string( plm, dest, bytes );
362
363 if ( rc == 0 )
364 return PLM_SUCCESS;
365 else
366 return PLM_READ_ERROR;
367}
368
369//--------------------------------------------------------------------------
370// read_metafile_header()
371//
372// Attempts to read the metafile header information in order to see if
373// is a metafile and identify the version.
374//--------------------------------------------------------------------------
375static
377{
378 char buffer[MAX_BUFFER];
379 PLINT version;
380 PLINT num_format_entries = sizeof ( metafile_format ) / sizeof ( struct _plm_version );
381
382 dbug_enter( "read_metafile_enter()" );
383
384 // Attempt to identify that this is a PLplot metafile
385 plm_rd( pdf_rd_header( plm, buffer ) );
386 if ( strcmp( buffer, PLMETA_HEADER ) != 0 )
387 {
388 return PLM_NOT_PLMETA_FILE;
389 }
390
391 // Attempt to identify the version number
392 plm_rd( pdf_rd_header( plm, buffer ) );
393 for ( version = 0;
394 version < num_format_entries
395 && strcmp( metafile_format[version].identifier, buffer ) != 0;
396 version++ )
397 ;
398
399 if ( version >= num_format_entries )
400 return ( PLM_UNKNOWN_VERSION );
401
402 dev->version = version;
403
404 return PLM_SUCCESS;
405}
406
407static
408void check_buffer_size( PLmDev *dev, size_t need_size )
409{
410 // Do we have enough space?
411 if ( need_size > dev->buffer_size )
412 {
413 // Nope, free the current buffer if it is allocated
414 if ( dev->buffer != NULL )
415 free( dev->buffer );
416
417 dev->buffer = malloc( need_size );
418 if ( dev->buffer == NULL )
419 {
420 plexit( "plmetafie: Insufficient memory for temporary storage" );
421 }
422 dev->buffer_size = need_size;
423 }
424}
425
426//--------------------------------------------------------------------------
427// read_header()
428//
429// Read a header block from the plot metafile.
430//
431// NOTE: Currently we enforce rigid adherence to the order
432// specified by the format. This can be changed so that the
433// entries a looked up instead.
434//--------------------------------------------------------------------------
435static
437 const struct _plm_format *header,
438 uint8_t * dest )
439{
440 char buffer[MAX_BUFFER];
441 unsigned int entry;
442 enum _plm_status rc;
443
444 for ( entry = 0;
445 header[entry].name != NULL;
446 entry++ )
447 {
448 // Get the name of this field and verify it is correct
449 plm_rd( pdf_rd_header( plm, buffer ) );
450 if ( strcmp( header[entry].name, buffer ) != 0 )
451 {
452 return PLM_FORMAT_ERROR;
453 }
454
455 rc = read_entry( plm,
456 header[entry].pdf_type,
457 header[entry].plp_type,
458 dest + header[entry].offset );
459
460 if ( rc != PLM_SUCCESS )
461 return rc;
462 }
463
464 return PLM_SUCCESS;
465}
466
467//--------------------------------------------------------------------------
468// read_line()
469//
470// Process a LINE command from the metafile
471//--------------------------------------------------------------------------
472static
474{
475 PLFLT x1, y1, x2, y2;
476 short x[2], y[2];
477 enum _plm_status rc;
478
479 // Read the start and end points
480 // The metafile stores the points as x,y pairs
481 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &x1 );
482 if ( rc != PLM_SUCCESS )
483 return rc;
484 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &y1 );
485 if ( rc != PLM_SUCCESS )
486 return rc;
487 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &x2 );
488 if ( rc != PLM_SUCCESS )
489 return rc;
490 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &y2 );
491 if ( rc != PLM_SUCCESS )
492 return rc;
493
494 // Transform the coordinates from the meta device to the current
495 // device coordinate system
496 x[0] = PLFLT2COORD( dev->mfpcxa * x1 + dev->mfpcxb );
497 y[0] = PLFLT2COORD( dev->mfpcya * y1 + dev->mfpcyb );
498 x[1] = PLFLT2COORD( dev->mfpcxa * x2 + dev->mfpcxb );
499 y[1] = PLFLT2COORD( dev->mfpcya * y2 + dev->mfpcyb );
500
501 // Draw the line
502 plP_line( x, y );
503
504 // Preserve the last XY coords for the LINETO command
505 dev->xold = (short) x[1];
506 dev->yold = (short) y[1];
507
508 return PLM_SUCCESS;
509}
510
511//--------------------------------------------------------------------------
512// read_lineto()
513//
514// Process a LINE command from the metafile
515//--------------------------------------------------------------------------
516static
518{
519 PLFLT x2, y2;
520 short x[2], y[2];
521 int i;
522 enum _plm_status rc;
523
524 // Set the start to the last known position
525 x[0] = (PLFLT) dev->xold;
526 y[0] = (PLFLT) dev->yold;
527
528 // Read the end point
529 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &x2 );
530 if ( rc != PLM_SUCCESS )
531 return rc;
532 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &y2 );
533 if ( rc != PLM_SUCCESS )
534 return rc;
535
536 // Transform the coordinates from the meta device to the current
537 // device coordinate system
538 x[1] = PLFLT2COORD( dev->mfpcxa * x2 + dev->mfpcxb );
539 y[1] = PLFLT2COORD( dev->mfpcya * y2 + dev->mfpcyb );
540
541 // Draw the line
542 plP_line( x, y );
543
544 // Preserve the last XY coords for the LINETO command
545 dev->xold = (short) x[1];
546 dev->yold = (short) y[1];
547
548 return PLM_SUCCESS;
549}
550
551//--------------------------------------------------------------------------
552// read_polyline()
553//
554// Process a POLYLINE command from the metafile
555//--------------------------------------------------------------------------
556static
558{
559 PLINT i, npts;
560 PLFLT x, y;
561 short *xd, *yd;
562 enum _plm_status rc;
563
564 // Read the number of control points and put into the plot buffer
565 rc = read_entry( plm, PDF_USHORT, PLP_PLINT, &npts );
566 if ( rc != PLM_SUCCESS )
567 return rc;
568
569 // Setup temporary storage. We need 2 * npts to store the X,Y pairs
570 check_buffer_size( dev, sizeof ( short ) * npts * 2 );
571 // Setup storage for the x values and y values
572 xd = (short *) ( dev->buffer );
573 yd = ( (short *) ( dev->buffer ) ) + npts;
574
575 // Read the points and insert into the plot buffer
576 // The x values
577 for ( i = 0; i < npts; i++ )
578 {
579 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &x );
580 if ( rc != PLM_SUCCESS )
581 return rc;
582
583 // Transform the coordinates from the meta device to the current
584 // device coordinate system
585 xd[i] = PLFLT2COORD( dev->mfpcxa * x + dev->mfpcxb );
586 }
587 // Preserve the last X value for the LINETO command
588 dev->xold = xd[npts - 1];
589
590 // The y values
591 for ( i = 0; i < npts; i++ )
592 {
593 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &y );
594 if ( rc != PLM_SUCCESS )
595 return rc;
596
597 // Transform the coordinates from the meta device to the current
598 // device coordinate system
599 yd[i] = PLFLT2COORD( dev->mfpcya * y + dev->mfpcyb );
600 }
601 // Preserve the last Y value for the LINETO command
602 dev->yold = yd[npts - 1];
603
604 // Draw the line
605 plP_polyline( xd, yd, npts );
606
607 return PLM_SUCCESS;
608}
609
610//--------------------------------------------------------------------------
611// read_escape()
612//
613// Process a escape command from the metafile
614//--------------------------------------------------------------------------
615static
617{
618 uint8_t op;
619 enum _plm_status rc = PLM_SUCCESS;
620
621 // Read the state operation, return if an error
622 if ( pdf_rd_1byte( plm, &op ) != 0 )
623 return PLM_FORMAT_ERROR;
624
625 switch ( op )
626 {
627 case PLESC_FILL:
628 {
629 PLINT i, npts;
630 PLFLT x, y;
631 short *xd, *yd;
632
633 // Get the number of control points for the fill
634 rc = read_entry( plm, PDF_USHORT, PLP_PLINT, &npts );
635 if ( rc != PLM_SUCCESS )
636 return rc;
637
638 // Setup temporary storage. We need 2 * npts to store the X,Y pairs
639 check_buffer_size( dev, sizeof ( short ) * npts * 2 );
640 // Setup storage for the x values and y values
641 xd = (short *) ( dev->buffer );
642 yd = ( (short *) ( dev->buffer ) ) + npts;
643
644 for ( i = 0; i < npts; i++ )
645 {
646 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &x );
647 if ( rc != PLM_SUCCESS )
648 return rc;
649
650 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &y );
651 if ( rc != PLM_SUCCESS )
652 return rc;
653
654 // Transform the coordinates from the meta device to the current
655 // device coordinate system
656 xd[i] = PLFLT2COORD( dev->mfpcxa * x + dev->mfpcxb );
657 yd[i] = PLFLT2COORD( dev->mfpcya * y + dev->mfpcyb );
658 }
659
660 plP_fill( xd, yd, npts );
661 }
662 break;
663
664 case PLESC_SWIN:
665 rc = PLM_SUCCESS;
666 break;
667
668
669 // Text handling. The metafile contains unprocessed string
670 // data
671 case PLESC_HAS_TEXT:
672 {
674 PLFLT xform[4];
675 PLUNICODE fci, ch;
676 PLINT i;
677 PLFLT xmin, xmax, ymin, ymax;
678 PLFLT x, y, refx, refy;
679 size_t len;
680
681 // Setup storage for the transformation matrix
682 text.xform = xform;
683
684 // Read the information from the metafile
685 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &pls->chrht );
686 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &pls->diorot );
687 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &xmin );
688 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &xmax );
689 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &ymin );
690 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &ymax );
691
692 rc = read_entry( plm, PDF_USHORT, PLP_PLINT, &text.base );
693 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &text.just );
694 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &text.xform[0] );
695 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &text.xform[1] );
696 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &text.xform[2] );
697 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &text.xform[3] );
698 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &x );
699 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &y );
700 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &refx );
701 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &refy );
702 rc = read_entry( plm, PDF_UBYTE, PLP_UCHAR, &text.font_face );
703
704 // Check for a size mismatch that indicates a problem in the
705 // library that the developers need to fix
706 if ( sizeof ( text.text_type ) != sizeof ( U_LONG ) )
707 {
708 plwarn( "plmetafile: Serious library error! text_type != U_LONG" );
709 return PLM_FORMAT_ERROR;
710 }
711 rc = read_entry( plm, PDF_ULONG, PLP_ULONG, &text.text_type );
712
713 // Translate coordinates to the device coordinate system
714 pls->clpxmi = PLFLT2COORD( dev->mfpcxa * xmin + dev->mfpcxb );
715 pls->clpxma = PLFLT2COORD( dev->mfpcxa * xmax + dev->mfpcxb );
716 pls->clpymi = PLFLT2COORD( dev->mfpcxa * ymin + dev->mfpcxb );
717 pls->clpyma = PLFLT2COORD( dev->mfpcxa * ymax + dev->mfpcxb );
718
719 text.x = PLFLT2COORD( dev->mfpcxa * x + dev->mfpcxb );
720 text.y = PLFLT2COORD( dev->mfpcya * y + dev->mfpcyb );
721 text.refx = PLFLT2COORD( dev->mfpcxa * refx + dev->mfpcxb );
722 text.refy = PLFLT2COORD( dev->mfpcya * refy + dev->mfpcyb );
723
724 if ( text.text_type == PL_STRING_TEXT )
725 {
726 // Retrieve the text string
727 rc = read_entry( plm, PDF_USHORT, PLP_ULONG, &len );
728
729 // Add one to the length for the NUL character. The metafile
730 // format stores the NUL, so we must read it.
731 len++;
732
733 // Check that we have enough storage for the string
734 check_buffer_size( dev, len * sizeof ( char ) );
735
736 // Read the string from the metafile
737 rc = read_string( plm, len, dev->buffer );
738
739 text.string = (char *) dev->buffer;
740
741 // Call the text rendering routine
742 plP_text(
743 text.base, text.just, text.xform,
744 text.x, text.y,
745 text.refx, text.refy,
746 text.string );
747 }
748 else
749 {
750 rc = read_entry( plm, PDF_USHORT, PLP_PLINT, &text.symbol );
751 plhrsh( text.symbol, text.x, text.y );
752 }
753 }
754 rc = PLM_SUCCESS;
755 break;
756
757 // Alternate unicode text handling
758 case PLESC_BEGIN_TEXT:
759 case PLESC_TEXT_CHAR:
761 case PLESC_END_TEXT:
762 // NOP these for now until a decision is made
763 // which method should be implemented for metafiles
764 plwarn( "plmetafile: Alternate Unicode text handling is not implemented" );
765 rc = PLM_INVALID_CMD;
766 break;
767
768 default:
769 break;
770 }
771
772 return rc;
773}
774
775//--------------------------------------------------------------------------
776// read_state()
777//
778// Process a state command from the metafile
779//--------------------------------------------------------------------------
780static
782{
783 uint8_t op;
784 enum _plm_status rc = PLM_SUCCESS;
785
786 // Read the state operation, return if an error
787 if ( pdf_rd_1byte( plm, &op ) != 0 )
788 return PLM_FORMAT_ERROR;
789
790 switch ( op )
791 {
792 case PLSTATE_WIDTH:
793 pldebug( "state: WIDTH" );
794
795 rc = read_entry( plm, PDF_USHORT, PLP_PLFLT, &( pls->width ) );
796 if ( rc != PLM_SUCCESS )
797 return rc;
798
799 break;
800
801 case PLSTATE_COLOR0:
802 case PLSTATE_COLOR1:
803 pldebug( "state: COLOR0/COLOR1" );
804
805 {
806 PLINT icol;
807
808 // Read the color index number
809 rc = read_entry( plm, PDF_USHORT, PLP_PLINT, &icol );
810 if ( rc != PLM_SUCCESS )
811 return rc;
812
813 // Was pen 0 set to an RGB value rather than color index?
814 if ( op == PLSTATE_COLOR0 && icol != PL_RGB_COLOR )
815 {
816 pls->icol0 = icol;
817 pls->curcolor.r = pls->cmap0[icol].r;
818 pls->curcolor.g = pls->cmap0[icol].g;
819 pls->curcolor.b = pls->cmap0[icol].b;
820 pls->curcolor.a = pls->cmap0[icol].a;
821 }
822 else if ( op == PLSTATE_COLOR1 )
823 {
824 pls->icol1 = icol;
825 pls->curcolor.r = pls->cmap1[icol].r;
826 pls->curcolor.g = pls->cmap1[icol].g;
827 pls->curcolor.b = pls->cmap1[icol].b;
828 pls->curcolor.a = pls->cmap1[icol].a;
829 }
830 else
831 {
832 // Get the RGB value and copy to the plot buffer
834
835 rc = read_entry( plm, PDF_UBYTE, PLP_UCHAR, &color.r );
836 if ( rc != PLM_SUCCESS )
837 return rc;
838
839 rc = read_entry( plm, PDF_UBYTE, PLP_UCHAR, &color.g );
840 if ( rc != PLM_SUCCESS )
841 return rc;
842
843 rc = read_entry( plm, PDF_UBYTE, PLP_UCHAR, &color.b );
844 if ( rc != PLM_SUCCESS )
845 return rc;
846
847 pls->icol0 = icol;
848 pls->curcolor.r = color.r;
849 pls->curcolor.g = color.g;
850 pls->curcolor.b = color.b;
851 pls->curcolor.a = 1.0;
852 }
853 }
854 break;
855
856 case PLSTATE_FILL:
857 pldebug( "state: FILL" );
858
859 // Read the pattern and put into the plot buffer
860 rc = read_entry( plm, PDF_USHORT, PLP_UCHAR, &( pls->patt ) );
861 if ( rc != PLM_SUCCESS )
862 return rc;
863
864 break;
865
866 case PLSTATE_CMAP0:
867 case PLSTATE_CMAP1:
868 pldebug( "state: CMAP0/CMAP1" );
869
870 {
871 PLINT i, ncol;
872 PLINT *r, *g, *b;
873 PLFLT *alpha;
874 void *ptr;
875
876 // Read the number of colors
877 rc = read_entry( plm, PDF_USHORT, PLP_PLINT, &ncol );
878 if ( rc != PLM_SUCCESS )
879 return rc;
880
881 // Check that temporary storage is sized correctly
883 dev,
884 sizeof ( PLINT ) * ncol * 3 // R, G, B values
885 + sizeof ( PLFLT ) * ncol ); // alpha channel values
886 ptr = dev->buffer;
887 r = (PLINT *) ptr;
888 ptr = ( (PLINT *) ptr ) + ncol;
889 g = (PLINT *) ptr;
890 ptr = ( (PLINT *) ptr ) + ncol;
891 b = (PLINT *) ptr;
892 ptr = ( (PLINT *) ptr ) + ncol;
893 alpha = (PLFLT *) ptr;
894
895 // Read the colormap
896 for ( i = 0; i < ncol; i++ )
897 {
898 rc = read_entry( plm, PDF_UBYTE, PLP_PLINT, &( r[i] ) );
899 if ( rc != PLM_SUCCESS )
900 return rc;
901
902 rc = read_entry( plm, PDF_UBYTE, PLP_PLINT, &( g[i] ) );
903 if ( rc != PLM_SUCCESS )
904 return rc;
905
906 rc = read_entry( plm, PDF_UBYTE, PLP_PLINT, &( b[i] ) );
907 if ( rc != PLM_SUCCESS )
908 return rc;
909
910 alpha[i] = 1.0;
911 }
912
913 // Call the colormap API so that memory is correctly allocated
914 // instead of plP_state( PLSTATE_CMAP0 );
915 if ( op == PLSTATE_CMAP0 )
916 plscmap0a( r, g, b, alpha, ncol );
917 else
918 plscmap1a( r, g, b, alpha, ncol );
919
920 // Return here because plscmap0a and plscmap1a call
921 // plP_state( PLSTATE_CMAP0 or PLSTATE_CMAP1 )
922 return PLM_SUCCESS;
923 }
924 break;
925
926 case PLSTATE_CHR:
927 pldebug( "state: CHR" );
928
929 // The 2005 version and earlier do not support this operation
930 if ( 1 )
931 {
932 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &( pls->chrdef ) );
933 if ( rc != PLM_SUCCESS )
934 return rc;
935
936 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &( pls->chrht ) );
937 if ( rc != PLM_SUCCESS )
938 return rc;
939 }
940 break;
941
942 case PLSTATE_SYM:
943 pldebug( "state: SYM" );
944
945 // The 2005 version and earlier do not support this operation
946 if ( 1 )
947 {
948 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &( pls->symdef ) );
949 if ( rc != PLM_SUCCESS )
950 return rc;
951
952 rc = read_entry( plm, PDF_IEEEF, PLP_PLFLT, &( pls->symht ) );
953 if ( rc != PLM_SUCCESS )
954 return rc;
955 }
956 break;
957
958 default:
959 pldebug( "state: INVALID STATE" );
960 return PLM_INVALID_STATE;
961 }
962
963 plP_state( op );
964
965 return PLM_SUCCESS;
966}
967
968//--------------------------------------------------------------------------
969// read_plot_commands()
970//
971// Reads the plot commands from the metafile and places them into the
972// plot buffer
973//--------------------------------------------------------------------------
974static
976{
977 uint8_t cmd;
978 enum _plm_status rc = PLM_SUCCESS;
979
980 dbug_enter( "read_plot_commands()" );
981
982 // Read the metafile until a non-zero result occurs, which typically
983 // indicates an end-of-file condition
984 while ( rc == PLM_SUCCESS && pdf_rd_1byte( plm, &cmd ) == 0 )
985 {
986 switch ( cmd )
987 {
988 case INITIALIZE:
989 pldebug( "cmd: INITIALIZE" );
990 // No action needed
991 break;
992
993 case CLOSE:
994 pldebug( "cmd: CLOSE" );
995 // No action needed
996 break;
997
998 case EOP:
999 pldebug( "cmd: EOP" );
1000
1001 plP_eop();
1002 break;
1003
1004 case BOP:
1005 case BOP0: // First BOP in a file
1006 pldebug( "cmd: BOP/BOP0" );
1007
1008 // Read the metadata for this page
1009 rc = read_entry( plm,
1012 (uint8_t *) dev + page_2005_header[0].offset );
1013 if ( rc != PLM_SUCCESS )
1014 break;
1015
1016 rc = read_entry( plm,
1019 (uint8_t *) dev + page_2005_header[1].offset );
1020 if ( rc != PLM_SUCCESS )
1021 break;
1022
1023 rc = read_entry( plm,
1026 (uint8_t *) dev + page_2005_header[2].offset );
1027 if ( rc != PLM_SUCCESS )
1028 break;
1029
1030 plP_bop();
1031
1032 break;
1033
1034 case LINE:
1035 pldebug( "cmd: LINE" );
1036
1037 rc = read_line( plm, dev, pls );
1038 break;
1039
1040 case LINETO:
1041 pldebug( "cmd: LINETO" );
1042
1043 rc = read_lineto( plm, dev, pls );
1044 break;
1045
1046 case ESCAPE:
1047 pldebug( "cmd: ESCAPE" );
1048
1049 rc = read_escape( plm, dev, pls );
1050 break;
1051
1052 case POLYLINE:
1053 pldebug( "cmd: POLYLINE" );
1054
1055 rc = read_polyline( plm, dev, pls );
1056 break;
1057
1058 case CHANGE_STATE:
1059 pldebug( "cmd: CHANGE_STATE" );
1060
1061 rc = read_state( plm, dev, pls );
1062 break;
1063
1064 case END_OF_FIELD:
1065 pldebug( "cmd: EOF" );
1066
1067 // No action needed
1068
1069 break;
1070
1071 case SWITCH_TO_TEXT: // Obsolete, replaced by ESCAPE
1072 case SWITCH_TO_GRAPH: // Obsolete, replaced by ESCAPE
1073 case NEW_COLOR: // Obsolete, replaced by CHANGE_STATE
1074 case NEW_WIDTH: // Obsolete, replaced by CHANGE_STATE
1075 case ADVANCE: // Obsolete, BOP/EOP used instead
1076 case NEW_COLOR1:
1077 pldebug( "cmd: OBSOLETE CMD" );
1078 plabort( "OBSOLETE CMD" );
1079
1080 break;
1081
1082 default:
1083 pldebug( "cmd: INVALID CMD" );
1084 plabort( "INVALID CMD" );
1085
1086 return PLM_INVALID_CMD;
1087 }
1088 }
1089
1090 return PLM_SUCCESS;
1091}
1092
1093static
1095{
1096 PLmDev *dev = pls->dev;
1097
1098 mf_dev->mfpcxa = (PLFLT) dev->xlen
1099 / (PLFLT) ( mf_dev->xmax - mf_dev->xmin );
1100 mf_dev->mfpcxb = (PLFLT) dev->xmin;
1101 mf_dev->mfpcya = (PLFLT) dev->ylen
1102 / (PLFLT) ( mf_dev->ymax - mf_dev->ymin );
1103 mf_dev->mfpcyb = (PLFLT) dev->ymin;
1104}
1105
1106//--------------------------------------------------------------------------
1107// plreadmetafile()
1108//
1121//--------------------------------------------------------------------------
1122void plreadmetafile( char *infile )
1123{
1124 PDFstrm *plm = NULL;
1125 PLStream mf_pls;
1126 PLmDev mf_dev;
1127 PLmIndex index;
1128 enum _plm_status rc;
1129
1130 if ( plsc->mf_infile == NULL && infile == NULL )
1131 {
1132 plexit( "No PLplot metafile set for input" );
1133 }
1134 else if ( infile != NULL )
1135 {
1136 plm = pdf_fopen( infile, "rb" );
1137 }
1138 else
1139 {
1140 plm = pdf_fopen( plsc->mf_infile, "rb" );
1141 }
1142 if ( plm == NULL )
1143 {
1144 plexit( "Unable to open PLplot metafile for input" );
1145 }
1146
1147 // Intialize the metafile device
1148 mf_dev.buffer = NULL;
1149 mf_dev.buffer_size = 0;
1150
1151 // Read the file header
1152 if ( ( rc = read_metafile_header( plm, &mf_dev ) ) != PLM_SUCCESS )
1153 {
1154 pdf_close( plm );
1155 plwarn( "Failed to parse PLplot metafile, ignoring file." );
1156 return;
1157 }
1158
1159 // Read the index header
1160 rc = read_header( plm,
1162 (U_CHAR *) &index );
1163 if ( rc != PLM_SUCCESS )
1164 {
1165 pdf_close( plm );
1166 plwarn( "Corrupted index in metafile, ignoring file." );
1167 return;
1168 }
1169
1170 // Read the device header
1171 rc = read_header( plm,
1173 (U_CHAR *) &mf_dev );
1174 if ( rc != PLM_SUCCESS )
1175 {
1176 pdf_close( plm );
1177 plwarn( "Corrupted device information in metafile, ignoring file." );
1178 return;
1179 }
1180
1181 // Read the plot header into a local version of a plot stream.
1182 // We do this because some of the parameters from the metafile may
1183 // be invalid or inappropriate for the current plot device
1184 // (e.g. xlength = 0). The plspage() call should be smart enough
1185 // to setup the page correctly.
1186 rc = read_header( plm,
1188 (U_CHAR *) &mf_pls );
1189 if ( rc != PLM_SUCCESS )
1190 {
1191 pdf_close( plm );
1192 plwarn( "Corrupted device information in metafile, ignoring file." );
1193 return;
1194 }
1195
1196 // Is the plot stream initialized?
1197 if ( plsc->level == 0 )
1198 {
1199 // No, we must intialize it in order to get the
1200 // device configuation set
1201 plinit();
1202 }
1203 setup_page( &mf_dev, plsc );
1204
1205 // At this point we should be in the plot commands
1206 rc = read_plot_commands( plm, &mf_dev, plsc );
1207 if ( rc != PLM_SUCCESS )
1208 {
1209 pdf_close( plm );
1210 plwarn( "Corrupted plot information in metafile, ignoring file." );
1211 return;
1212 }
1213
1214 pdf_close( plm );
1215
1216 // Free the temporary storage
1217 if ( mf_dev.buffer != NULL )
1218 free( mf_dev.buffer );
1219}
const char header[]
Definition: deltaT-gen.c:41
#define NEW_WIDTH
Definition: metadefs.h:60
#define CLOSE
Definition: metadefs.h:54
#define LINETO
Definition: metadefs.h:62
#define END_OF_FIELD
Definition: metadefs.h:74
#define PLMETA_HEADER
Definition: metadefs.h:16
#define INITIALIZE
Definition: metadefs.h:53
#define EOP
Definition: metadefs.h:57
#define BOP0
Definition: metadefs.h:69
#define BOP
Definition: metadefs.h:58
#define NEW_COLOR
Definition: metadefs.h:59
#define PLMETA_VERSION
Definition: metadefs.h:17
#define SWITCH_TO_TEXT
Definition: metadefs.h:55
#define plm_rd(code)
Definition: metadefs.h:41
#define SWITCH_TO_GRAPH
Definition: metadefs.h:56
#define CHANGE_STATE
Definition: metadefs.h:68
#define NEW_COLOR1
Definition: metadefs.h:67
#define ADVANCE
Definition: metadefs.h:64
#define POLYLINE
Definition: metadefs.h:65
#define LINE
Definition: metadefs.h:61
#define ESCAPE
Definition: metadefs.h:63
#define U_LONG
Definition: pdf.h:38
#define U_SHORT
Definition: pdf.h:30
#define U_CHAR
Definition: pdf.h:26
int pdf_rd_4bytes(PDFstrm *pdfs, U_LONG *ps)
Definition: pdfutils.c:832
int pdf_rd_header(PDFstrm *pdfs, char *header)
Definition: pdfutils.c:542
PDFstrm * pdf_fopen(PLCHAR_VECTOR filename, PLCHAR_VECTOR mode)
Definition: pdfutils.c:74
int pdf_rd_2bytes(PDFstrm *pdfs, U_SHORT *ps)
Definition: pdfutils.c:710
int pdf_rd_1byte(PDFstrm *pdfs, U_CHAR *ps)
Definition: pdfutils.c:660
int pdf_close(PDFstrm *pdfs)
Definition: pdfutils.c:238
int pdf_rd_ieeef(PDFstrm *pdfs, float *pf)
Definition: pdfutils.c:992
int pdf_rd_string(PDFstrm *pdfs, char *string, int nmax)
Definition: pdfutils.c:604
void plP_state(PLINT op)
Definition: plcore.c:256
void plP_polyline(short *x, short *y, PLINT npts)
Definition: plcore.c:417
void plP_text(PLINT base, PLFLT just, PLFLT *xform, PLINT x, PLINT y, PLINT refx, PLINT refy, PLCHAR_VECTOR string)
Definition: plcore.c:1186
void plP_bop(void)
Definition: plcore.c:198
void plP_eop(void)
Definition: plcore.c:164
void plP_line(short *x, short *y)
Definition: plcore.c:388
void plP_fill(short *x, short *y, PLINT npts)
Definition: plcore.c:451
static PLStream * pls[PL_NSTREAMS]
Definition: plcore.h:88
void plwarn(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1863
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1894
static PLINT * buffer
Definition: plfill.c:74
static enum _plm_status read_state(PDFstrm *plm, PLmDev *dev, PLStream *pls)
Definition: plmetafile.c:781
static enum _plm_status set_ieeef_plp_value(float x, void *dest, enum _plp_types type)
Definition: plmetafile.c:263
_plp_types
Definition: plmetafile.c:72
@ PLP_USHORT
Definition: plmetafile.c:76
@ PLP_PLINT
Definition: plmetafile.c:78
@ PLP_PLFLT
Definition: plmetafile.c:79
@ PLP_NULL
Definition: plmetafile.c:73
@ PLP_SHORT
Definition: plmetafile.c:77
@ PLP_ULONG
Definition: plmetafile.c:80
@ PLP_UBYTE
Definition: plmetafile.c:74
@ PLP_UCHAR
Definition: plmetafile.c:75
static enum _plm_status set_ushort_plp_value(U_SHORT x, void *dest, enum _plp_types type)
Definition: plmetafile.c:183
static void setup_page(PLmDev *mf_dev, PLStream *pls)
Definition: plmetafile.c:1094
static enum _plm_status read_polyline(PDFstrm *plm, PLmDev *dev, PLStream *pls)
Definition: plmetafile.c:557
#define MAX_BUFFER
Definition: plmetafile.c:33
static enum _plm_status read_string(PDFstrm *plm, size_t bytes, char *dest)
Definition: plmetafile.c:355
_plm_status
Definition: plmetafile.c:49
@ PLM_INVALID_STATE
Definition: plmetafile.c:52
@ PLM_FORMAT_ERROR
Definition: plmetafile.c:54
@ PLM_SUCCESS
Definition: plmetafile.c:57
@ PLM_UNKNOWN_DATATYPE
Definition: plmetafile.c:51
@ PLM_UNKNOWN_VERSION
Definition: plmetafile.c:55
@ PLM_INVALID_CMD
Definition: plmetafile.c:53
@ PLM_NOT_PLMETA_FILE
Definition: plmetafile.c:56
@ PLM_READ_ERROR
Definition: plmetafile.c:50
void plreadmetafile(char *infile)
Definition: plmetafile.c:1122
static const struct _plm_format page_2005_header[]
Definition: plmetafile.c:125
#define PLFLT2COORD(a)
Definition: plmetafile.c:45
static const struct _plm_format plot_2005_header[]
Definition: plmetafile.c:112
static enum _plm_status read_metafile_header(PDFstrm *plm, PLmDev *dev)
Definition: plmetafile.c:376
static enum _plm_status read_line(PDFstrm *plm, PLmDev *dev, PLStream *pls)
Definition: plmetafile.c:473
static enum _plm_status read_escape(PDFstrm *plm, PLmDev *dev, PLStream *pls)
Definition: plmetafile.c:616
static enum _plm_status read_plot_commands(PDFstrm *plm, PLmDev *dev, PLStream *pls)
Definition: plmetafile.c:975
static struct _plm_version metafile_format[]
static enum _plm_status read_header(PDFstrm *plm, const struct _plm_format *header, uint8_t *dest)
Definition: plmetafile.c:436
static enum _plm_status set_ulong_plp_value(unsigned long x, void *dest, enum _plp_types type)
Definition: plmetafile.c:223
static enum _plm_status read_lineto(PDFstrm *plm, PLmDev *dev, PLStream *pls)
Definition: plmetafile.c:517
static const struct _plm_format index_2005_header[]
Definition: plmetafile.c:93
static enum _plm_status set_ubyte_plp_value(uint8_t x, void *dest, enum _plp_types type)
Definition: plmetafile.c:143
static const struct _plm_format dev_2005_header[]
Definition: plmetafile.c:100
_pdf_types
Definition: plmetafile.c:62
@ PDF_USHORT
Definition: plmetafile.c:65
@ PDF_UBYTE
Definition: plmetafile.c:64
@ PDF_NULL
Definition: plmetafile.c:63
@ PDF_IEEEF
Definition: plmetafile.c:67
@ PDF_ULONG
Definition: plmetafile.c:66
static enum _plm_status read_entry(PDFstrm *plm, enum _pdf_types from_type, enum _plp_types to_type, void *dest)
Definition: plmetafile.c:303
static void check_buffer_size(PLmDev *dev, size_t need_size)
Definition: plmetafile.c:408
#define PLSTATE_FILL
Definition: plplotP.h:365
#define PLSTATE_CHR
Definition: plplotP.h:368
#define PLSTATE_SYM
Definition: plplotP.h:369
#define PLSTATE_WIDTH
Definition: plplotP.h:362
#define PLSTATE_CMAP0
Definition: plplotP.h:366
#define PLSTATE_COLOR1
Definition: plplotP.h:364
#define PLSTATE_CMAP1
Definition: plplotP.h:367
#define PL_RGB_COLOR
Definition: plplotP.h:285
#define PLSTATE_COLOR0
Definition: plplotP.h:363
#define plinit
Definition: plplot.h:755
#define PLESC_HAS_TEXT
Definition: plplot.h:290
#define PLESC_CONTROL_CHAR
Definition: plplot.h:300
PLUINT PLUNICODE
Definition: plplot.h:201
float PLFLT
Definition: plplot.h:163
#define PLESC_END_TEXT
Definition: plplot.h:301
const char * PLCHAR_VECTOR
Definition: plplot.h:243
#define PLESC_TEXT_CHAR
Definition: plplot.h:299
#define plscmap0a
Definition: plplot.h:792
#define plscmap1a
Definition: plplot.h:795
#define PLESC_FILL
Definition: plplot.h:279
#define PLESC_SWIN
Definition: plplot.h:284
#define PLESC_BEGIN_TEXT
Definition: plplot.h:298
int PLINT
Definition: plplot.h:181
void xform(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
void plhrsh(PLINT ch, PLINT x, PLINT y)
Definition: plsym.c:359
static int color
Definition: ps.c:78
static int text
Definition: ps.c:77
Definition: pdf.h:50
PLFLT a
Definition: plplot.h:551
unsigned char r
Definition: plplot.h:548
unsigned char g
Definition: plplot.h:549
unsigned char b
Definition: plplot.h:550
PLFLT symht
Definition: plstrm.h:687
PLINT clpymi
Definition: plstrm.h:704
PLFLT symdef
Definition: plstrm.h:687
PLColor * cmap0
Definition: plstrm.h:544
PLINT clpyma
Definition: plstrm.h:704
PLFLT width
Definition: plstrm.h:552
PLFLT chrht
Definition: plstrm.h:686
PLColor curcolor
Definition: plstrm.h:543
PLINT icol1
Definition: plstrm.h:539
PLFLT chrdef
Definition: plstrm.h:686
PLINT patt
Definition: plstrm.h:669
void * dev
Definition: plstrm.h:594
PLColor * cmap1
Definition: plstrm.h:545
PLINT clpxmi
Definition: plstrm.h:704
PLINT clpxma
Definition: plstrm.h:704
PLINT icol0
Definition: plstrm.h:539
PLFLT diorot
Definition: plstrm.h:661
PLINT xlen
Definition: metadefs.h:91
PLINT ylen
Definition: metadefs.h:92
PLFLT mfpcxa
Definition: metadefs.h:104
PLFLT mfpcya
Definition: metadefs.h:105
size_t buffer_size
Definition: metadefs.h:109
PLINT version
Definition: metadefs.h:99
PLFLT mfpcxb
Definition: metadefs.h:104
PLINT ymax
Definition: metadefs.h:92
PLFLT mfpcyb
Definition: metadefs.h:105
PLINT ymin
Definition: metadefs.h:92
void * buffer
Definition: metadefs.h:108
PLINT yold
Definition: metadefs.h:89
PLINT xmin
Definition: metadefs.h:91
PLINT xold
Definition: metadefs.h:89
PLINT xmax
Definition: metadefs.h:91
enum _plp_types plp_type
Definition: plmetafile.c:88
char * name
Definition: plmetafile.c:86
enum _pdf_types pdf_type
Definition: plmetafile.c:87
const size_t offset
Definition: plmetafile.c:89
const struct _plm_format * device_header
Definition: plmetafile.c:135
PLCHAR_VECTOR identifier
Definition: plmetafile.c:133
const struct _plm_format * index_header
Definition: plmetafile.c:134
const struct _plm_format * plot_header
Definition: plmetafile.c:136
#define dbug_enter(a)
Definition: tclMatrix.c:59
static const char * name
Definition: tkMain.c:135