PLplot 5.15.0
Loading...
Searching...
No Matches
ps.c
Go to the documentation of this file.
1// PLplot PostScript device driver.
2//
3// Copyright (C) 1992-2001 Geoffrey Furnish
4// Copyright (C) 1992-2001 Maurice LeBrun
5// Copyright (C) 2000-2018 Alan W. Irwin
6// Copyright (C) 2001-2002 Joao Cardoso
7// Copyright (C) 2001-2004 Rafael Laboissiere
8// Copyright (C) 2004-2005 Thomas J. Duck
9// Copyright (C) 2005 Andrew Ross
10//
11// This file is part of PLplot.
12//
13// PLplot is free software; you can redistribute it and/or modify
14// it under the terms of the GNU Library General Public License as published
15// by the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PLplot is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU Library General Public License for more details.
22//
23// You should have received a copy of the GNU Library General Public License
24// along with PLplot; if not, write to the Free Software
25// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26//
27//
28
29#include "plDevs.h"
30
31#define DEBUG
32
33#define NEED_PLDEBUG
34#include "plplotP.h"
35#include "drivers.h"
36#include "ps.h"
37
38#include <string.h>
39#include <time.h>
40#include "plunicode-type1.h"
41#include "plfci-type1.h"
42
43// Define macro to truncate small values to zero - prevents
44// printf printing -0.000
45#define TRMFLT( a ) ( ( fabs( a ) < 5.0e-4 ) ? 0.0 : ( a ) )
46
47// Device info
48
50#ifdef PLD_ps
51 "ps:PostScript File (monochrome):0:ps:29:ps\n"
52#endif
53#ifdef PLD_psc
54 "psc:PostScript File (color):0:ps:30:psc\n"
55#endif
56;
57
58// Prototypes for functions in this file.
59
60#ifdef PLD_ps
62#endif
63#ifdef PLD_psc
65#endif
66
67static char *ps_getdate( void );
68static void ps_init( PLStream * );
69static void fill_polygon( PLStream *pls );
70static void proc_str( PLStream *, EscText * );
71static void esc_purge( unsigned char *, unsigned char * );
73 const char *menustr, const char *devnam,
74 int type, int seq, plD_init_fp init );
75#define OUTBUF_LEN 128
76static char outbuf[OUTBUF_LEN];
77static int text = 1;
78static int color;
79static int hrshsym = 1;
80
81static DrvOpt ps_options[] = { { "text", DRV_INT, &text, "Use Postscript text (text=0|1)" },
82 { "color", DRV_INT, &color, "Use color (color=0|1)" },
83 { "hrshsym", DRV_INT, &hrshsym, "Use Hershey symbol set (hrshsym=0|1)" },
84 { NULL, DRV_INT, NULL, NULL } };
85
86static unsigned char
87plunicode2type1( const PLUNICODE index,
88 const Unicode_to_Type1_table lookup[],
89 const int number_of_entries );
90
91static const char *
92get_font( PSDev* dev, PLUNICODE fci );
93
94// text > 0 uses some postscript tricks, namely a transformation matrix
95// that scales, rotates (with slanting) and offsets text strings.
96// It has yet some bugs for 3d plots.
97
98
100 const char *menustr, const char *devnam,
101 int type, int seq, plD_init_fp init )
102{
103#ifndef ENABLE_DYNDRIVERS
104 pdt->pl_MenuStr = (char *) menustr;
105 pdt->pl_DevName = (char *) devnam;
106#else
107 (void) menustr; // Cast to void to silence compiler warnings about unused parameters
108 (void) devnam;
109#endif
110 pdt->pl_type = type;
111 pdt->pl_seq = seq;
112 pdt->pl_init = init;
120}
121
122#ifdef PLD_ps
124{
126 "PostScript File (monochrome)", "ps",
129}
130
131//--------------------------------------------------------------------------
132// plD_init_ps()
133//
134// Initialize device.
135//--------------------------------------------------------------------------
136
137void
139{
140 color = 0;
141 pls->color = 0; // Not a color device
142
144 if ( color )
145 pls->color = 1; // But user wants color
146 ps_init( pls );
147}
148#endif //#ifdef PLD_ps
149
150#ifdef PLD_psc
152{
154 "PostScript File (color)", "psc",
157}
158
159void
161{
162 color = 1;
163 pls->color = 1; // Is a color device
165
166 if ( !color )
167 pls->color = 0; // But user does not want color
168 ps_init( pls );
169}
170#endif //#ifdef PLD_psc
171
172static void
174{
175 PSDev *dev;
176
177 PLFLT pxlx, pxly;
178
179 // Set default values - 7.5 x 10 [inches] (72 points = 1 inch)
180 if ( pls->xlength <= 0 || pls->ylength <= 0 )
181 {
182 pls->xlength = 540;
183 pls->ylength = 720;
184 pls->xoffset = 32;
185 pls->yoffset = 32;
186 }
187 if ( pls->xdpi <= 0 )
188 pls->xdpi = 72.;
189 if ( pls->ydpi <= 0 )
190 pls->ydpi = 72.;
191
192 pxlx = YPSSIZE / LPAGE_X;
193 pxly = XPSSIZE / LPAGE_Y;
194
195 if ( text )
196 {
197 pls->dev_text = 1; // want to draw text
198 pls->dev_unicode = 1; // want unicode
199 if ( hrshsym )
200 pls->dev_hrshsym = 1; // want Hershey symbols
201 }
202
203 pls->dev_fill0 = 1; // Can do solid fills
204
205// Initialize family file info
206
207 plFamInit( pls );
208
209// Prompt for a file name if not already set
210
211 plOpenFile( pls );
212
213// Allocate and initialize device-specific data
214
215 if ( pls->dev != NULL )
216 free( (void *) pls->dev );
217
218 pls->dev = calloc( 1, (size_t) sizeof ( PSDev ) );
219 if ( pls->dev == NULL )
220 plexit( "ps_init: Out of memory." );
221
222 dev = (PSDev *) pls->dev;
223
224 dev->xold = PL_UNDEFINED;
225 dev->yold = PL_UNDEFINED;
226
227 plP_setpxl( pxlx, pxly );
228
229 dev->llx = XPSSIZE;
230 dev->lly = YPSSIZE;
231 dev->urx = 0;
232 dev->ury = 0;
233 dev->ptcnt = 0;
234
235// Rotate by 90 degrees since portrait mode addressing is used
236
237 dev->xmin = 0;
238 dev->ymin = 0;
239 dev->xmax = PSY;
240 dev->ymax = PSX;
241 dev->xlen = dev->xmax - dev->xmin;
242 dev->ylen = dev->ymax - dev->ymin;
243
244 plP_setphy( dev->xmin, dev->xmax, dev->ymin, dev->ymax );
245
246// If portrait mode is specified, then set up an additional rotation
247// transformation with aspect ratio allowed to adjust via freeaspect.
248// Default orientation is landscape (ORIENTATION == 3 or 90 deg rotation
249// counter-clockwise from portrait). (Legacy PLplot used seascape
250// which was equivalent to ORIENTATION == 1 or 90 deg clockwise rotation
251// from portrait.)
252
253 if ( pls->portrait )
254 {
255 plsdiori( (PLFLT) ( 4 - ORIENTATION ) );
256 pls->freeaspect = 1;
257 }
258
259// Header comments into PostScript file
260
261 fprintf( OF, "%%!PS-Adobe-2.0 EPSF-2.0\n" );
262 fprintf( OF, "%%%%BoundingBox: \n" );
263 fprintf( OF, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" );
264
265 fprintf( OF, "%%%%Title: PLplot Graph\n" );
266 fprintf( OF, "%%%%Creator: PLplot Version %s\n", PLPLOT_VERSION );
267 fprintf( OF, "%%%%CreationDate: %s\n", ps_getdate() );
268 fprintf( OF, "%%%%Pages: (atend)\n" );
269 fprintf( OF, "%%%%EndComments\n\n" );
270
271// Definitions
272// Save VM state
273
274 fprintf( OF, "/PSSave save def\n" );
275
276// Define a dictionary and start using it
277
278 fprintf( OF, "/PSDict 200 dict def\n" );
279 fprintf( OF, "PSDict begin\n" );
280
281 fprintf( OF, "/@restore /restore load def\n" );
282 fprintf( OF, "/restore\n" );
283 fprintf( OF, " {vmstatus pop\n" );
284 fprintf( OF, " dup @VMused lt {pop @VMused} if\n" );
285 fprintf( OF, " exch pop exch @restore /@VMused exch def\n" );
286 fprintf( OF, " } def\n" );
287 fprintf( OF, "/@pri\n" );
288 fprintf( OF, " {\n" );
289 fprintf( OF, " ( ) print\n" );
290 fprintf( OF, " ( ) cvs print\n" );
291 fprintf( OF, " } def\n" );
292
293// n @copies -
294
295 fprintf( OF, "/@copies\n" );
296 fprintf( OF, " {\n" );
297 fprintf( OF, " /#copies exch def\n" );
298 fprintf( OF, " } def\n" );
299
300// - @start - -- start everything
301
302 fprintf( OF, "/@start\n" );
303 fprintf( OF, " {\n" );
304 fprintf( OF, " vmstatus pop /@VMused exch def pop\n" );
305 fprintf( OF, " } def\n" );
306
307// - @end - -- finished
308
309 fprintf( OF, "/@end\n" );
310 fprintf( OF, " {flush\n" );
311 fprintf( OF, " end\n" );
312 fprintf( OF, " PSSave restore\n" );
313 fprintf( OF, " } def\n" );
314
315// bop - -- begin a new page
316// Only fill background if we are using color and if the bg isn't white
317
318 fprintf( OF, "/bop\n" );
319 fprintf( OF, " {\n" );
320 fprintf( OF, " /SaveImage save def\n" );
321 fprintf( OF, " } def\n" );
322
323// - eop - -- end a page
324
325 fprintf( OF, "/eop\n" );
326 fprintf( OF, " {\n" );
327 fprintf( OF, " showpage\n" );
328 fprintf( OF, " SaveImage restore\n" );
329 fprintf( OF, " } def\n" );
330
331// Set line parameters
332
333 fprintf( OF, "/@line\n" );
334 fprintf( OF, " {0 setlinecap\n" );
335 fprintf( OF, " 0 setlinejoin\n" );
336 fprintf( OF, " 1 setmiterlimit\n" );
337 fprintf( OF, " } def\n" );
338
339// d @hsize - horizontal clipping dimension
340
341 fprintf( OF, "/@hsize {/hs exch def} def\n" );
342 fprintf( OF, "/@vsize {/vs exch def} def\n" );
343
344// d @hoffset - shift for the plots
345
346 fprintf( OF, "/@hoffset {/ho exch def} def\n" );
347 fprintf( OF, "/@voffset {/vo exch def} def\n" );
348
349// Set line width
350
351 fprintf( OF, "/lw %d def\n", (int) (
352 ( pls->width < MIN_WIDTH ) ? DEF_WIDTH :
353 ( pls->width > MAX_WIDTH ) ? MAX_WIDTH : pls->width ) );
354
355// Setup user specified offsets, scales, sizes for clipping
356
357 fprintf( OF, "/@SetPlot\n" );
358 fprintf( OF, " {\n" );
359 fprintf( OF, " ho vo translate\n" );
360 fprintf( OF, " XScale YScale scale\n" );
361 fprintf( OF, " lw setlinewidth\n" );
362 fprintf( OF, " } def\n" );
363
364// Setup x & y scales
365
366 fprintf( OF, "/XScale\n" );
367 fprintf( OF, " {hs %d div} def\n", YPSSIZE );
368 fprintf( OF, "/YScale\n" );
369 fprintf( OF, " {vs %d div} def\n", XPSSIZE );
370
371// Macro definitions of common instructions, to keep output small
372
373 fprintf( OF, "/M {moveto} def\n" );
374 fprintf( OF, "/D {lineto} def\n" );
375 fprintf( OF, "/A {0.5 0 360 arc} def\n" );
376 fprintf( OF, "/S {stroke} def\n" );
377 fprintf( OF, "/Z {stroke newpath} def\n" );
378 // Modify to use fill and stroke for better output with
379 // anti-aliasing
380 //fprintf(OF, "/F {fill} def\n");
381 if ( pls->dev_eofill )
382 fprintf( OF, "/F {closepath gsave eofill grestore stroke} def " );
383 else
384 fprintf( OF, "/F {closepath gsave fill grestore stroke} def " );
385 fprintf( OF, "/N {newpath} def" );
386 fprintf( OF, "/C {setrgbcolor} def\n" );
387 fprintf( OF, "/G {setgray} def\n" );
388 fprintf( OF, "/W {setlinewidth} def\n" );
389 fprintf( OF, "/SF {selectfont} def\n" );
390 fprintf( OF, "/R {rotate} def\n" );
391 fprintf( OF, "/SW {stringwidth 2 index mul exch 2 index mul exch rmoveto pop} bind def\n" );
392 fprintf( OF, "/B {Z %d %d M %d %d D %d %d D %d %d D %d %d closepath} def\n",
393 0, 0, 0, PSY, PSX, PSY, PSX, 0, 0, 0 );
394 fprintf( OF, "/CL {newpath M D D D closepath clip} def\n" );
395
396// End of dictionary definition
397
398 fprintf( OF, "end\n\n" );
399
400// Set up the plots
401
402 fprintf( OF, "PSDict begin\n" );
403 fprintf( OF, "@start\n" );
404 fprintf( OF, "%d @copies\n", COPIES );
405 fprintf( OF, "@line\n" );
406 fprintf( OF, "%d @hsize\n", YSIZE );
407 fprintf( OF, "%d @vsize\n", XSIZE );
408 fprintf( OF, "%d @hoffset\n", YOFFSET );
409 fprintf( OF, "%d @voffset\n", XOFFSET );
410
411 fprintf( OF, "@SetPlot\n\n" );
412}
413
414//--------------------------------------------------------------------------
415// plD_line_ps()
416//
417// Draw a line in the current color from (x1,y1) to (x2,y2).
418//--------------------------------------------------------------------------
419
420void
421plD_line_ps( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
422{
423 PSDev *dev = (PSDev *) pls->dev;
424 PLINT x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
425
426// Rotate by 90 degrees
427
428 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1 );
429 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2 );
430
431 if ( x1 == dev->xold && y1 == dev->yold && dev->ptcnt < 40 )
432 {
433 if ( pls->linepos + 12 > LINELENGTH )
434 {
435 putc( '\n', OF );
436 pls->linepos = 0;
437 }
438 else
439 putc( ' ', OF );
440
441 snprintf( outbuf, OUTBUF_LEN, "%d %d D", x2, y2 );
442 dev->ptcnt++;
443 pls->linepos += 12;
444 }
445 else
446 {
447 fprintf( OF, " Z\n" );
448 pls->linepos = 0;
449
450 if ( x1 == x2 && y1 == y2 ) // must be a single dot, draw a circle
451 snprintf( outbuf, OUTBUF_LEN, "%d %d A", x1, y1 );
452 else
453 snprintf( outbuf, OUTBUF_LEN, "%d %d M %d %d D", x1, y1, x2, y2 );
454 dev->llx = MIN( dev->llx, x1 );
455 dev->lly = MIN( dev->lly, y1 );
456 dev->urx = MAX( dev->urx, x1 );
457 dev->ury = MAX( dev->ury, y1 );
458 dev->ptcnt = 1;
459 pls->linepos += 24;
460 }
461 dev->llx = MIN( dev->llx, x2 );
462 dev->lly = MIN( dev->lly, y2 );
463 dev->urx = MAX( dev->urx, x2 );
464 dev->ury = MAX( dev->ury, y2 );
465
466 fprintf( OF, "%s", outbuf );
467 pls->bytecnt += 1 + (PLINT) strlen( outbuf );
468 dev->xold = x2;
469 dev->yold = y2;
470}
471
472//--------------------------------------------------------------------------
473// plD_polyline_ps()
474//
475// Draw a polyline in the current color.
476//--------------------------------------------------------------------------
477
478void
479plD_polyline_ps( PLStream *pls, short *xa, short *ya, PLINT npts )
480{
481 PLINT i;
482
483 for ( i = 0; i < npts - 1; i++ )
484 plD_line_ps( pls, xa[i], ya[i], xa[i + 1], ya[i + 1] );
485}
486
487//--------------------------------------------------------------------------
488// plD_eop_ps()
489//
490// End of page.
491//--------------------------------------------------------------------------
492
493void
495{
496 fprintf( OF, " S\neop\n" );
497}
498
499//--------------------------------------------------------------------------
500// plD_bop_ps()
501//
502// Set up for the next page.
503// Advance to next family file if necessary (file output).
504//--------------------------------------------------------------------------
505
506void
508{
509 PSDev *dev = (PSDev *) pls->dev;
510
511 dev->xold = PL_UNDEFINED;
512 dev->yold = PL_UNDEFINED;
513
514 if ( !pls->termin )
515 plGetFam( pls );
516
517 pls->page++;
518
519 if ( pls->family )
520 fprintf( OF, "%%%%Page: %d %d\n", (int) pls->page, 1 );
521 else
522 fprintf( OF, "%%%%Page: %d %d\n", (int) pls->page, (int) pls->page );
523
524 fprintf( OF, "bop\n" );
525 if ( pls->color )
526 {
527 PLFLT r, g, b;
528 if ( pls->cmap0[0].r != 0xFF ||
529 pls->cmap0[0].g != 0xFF ||
530 pls->cmap0[0].b != 0xFF )
531 {
532 r = ( (PLFLT) pls->cmap0[0].r ) / 255.;
533 g = ( (PLFLT) pls->cmap0[0].g ) / 255.;
534 b = ( (PLFLT) pls->cmap0[0].b ) / 255.;
535
536 fprintf( OF, "B %.4f %.4f %.4f C F\n", r, g, b );
537 }
538 }
539 pls->linepos = 0;
540
541// This ensures the color and line width are set correctly at the beginning of
542// each page
543
546}
547
548//--------------------------------------------------------------------------
549// plD_tidy_ps()
550//
551// Close graphics file or otherwise clean up.
552//--------------------------------------------------------------------------
553
554void
556{
557 PSDev *dev = (PSDev *) pls->dev;
558
559 fprintf( OF, "\n%%%%Trailer\n" );
560
561 dev->llx /= ENLARGE;
562 dev->lly /= ENLARGE;
563 dev->urx /= ENLARGE;
564 dev->ury /= ENLARGE;
565 dev->llx += YOFFSET;
566 dev->lly += XOFFSET;
567 dev->urx += YOFFSET;
568 dev->ury += XOFFSET;
569
570// changed for correct Bounding boundaries Jan Thorbecke okt 1993
571// occurs from the integer truncation -- postscript uses fp arithmetic
572
573 dev->urx += 1;
574 dev->ury += 1;
575
576 if ( pls->family )
577 fprintf( OF, "%%%%Pages: %d\n", (int) 1 );
578 else
579 fprintf( OF, "%%%%Pages: %d\n", (int) pls->page );
580
581 fprintf( OF, "@end\n" );
582 fprintf( OF, "%%%%EOF\n" );
583
584// Backtrack to write the BoundingBox at the beginning
585// Some applications don't like it atend
586
587 rewind( OF );
588 fprintf( OF, "%%!PS-Adobe-2.0 EPSF-2.0\n" );
589 fprintf( OF, "%%%%BoundingBox: %d %d %d %d\n",
590 dev->llx, dev->lly, dev->urx, dev->ury );
591 plCloseFile( pls );
592}
593
594//--------------------------------------------------------------------------
595// plD_state_ps()
596//
597// Handle change in PLStream state (color, pen width, fill attribute, etc).
598//--------------------------------------------------------------------------
599
600void
602{
603 PSDev *dev = (PSDev *) pls->dev;
604
605 switch ( op )
606 {
607 case PLSTATE_WIDTH: {
608 int width = (int) (
609 ( pls->width < MIN_WIDTH ) ? DEF_WIDTH :
610 ( pls->width > MAX_WIDTH ) ? MAX_WIDTH : pls->width );
611
612 fprintf( OF, " S\n%d W", width );
613
614 dev->xold = PL_UNDEFINED;
615 dev->yold = PL_UNDEFINED;
616 break;
617 }
618 case PLSTATE_COLOR0:
619 if ( !pls->color )
620 {
621 fprintf( OF, " S\n%.4f G", ( pls->icol0 ? 0.0 : 1.0 ) );
622 // Reinitialize current point location.
623 if ( dev->xold != PL_UNDEFINED && dev->yold != PL_UNDEFINED )
624 fprintf( OF, " %d %d M \n", (int) dev->xold, (int) dev->yold );
625 break;
626 }
627 // else fallthrough
628 case PLSTATE_COLOR1:
629 if ( pls->color )
630 {
631 PLFLT r = ( (PLFLT) pls->curcolor.r ) / 255.0;
632 PLFLT g = ( (PLFLT) pls->curcolor.g ) / 255.0;
633 PLFLT b = ( (PLFLT) pls->curcolor.b ) / 255.0;
634
635 fprintf( OF, " S\n%.4f %.4f %.4f C", r, g, b );
636 }
637 else
638 {
639 PLFLT r = ( (PLFLT) pls->curcolor.r ) / 255.0;
640 fprintf( OF, " S\n%.4f G", 1.0 - r );
641 }
642 // Reinitialize current point location.
643 if ( dev->xold != PL_UNDEFINED && dev->yold != PL_UNDEFINED )
644 fprintf( OF, " %d %d M \n", (int) dev->xold, (int) dev->yold );
645 break;
646 }
647}
648
649//--------------------------------------------------------------------------
650// plD_esc_ps()
651//
652// Escape function.
653//--------------------------------------------------------------------------
654
655void
656plD_esc_ps( PLStream *pls, PLINT op, void *ptr )
657{
658 switch ( op )
659 {
660 case PLESC_FILL:
661 fill_polygon( pls );
662 break;
663 case PLESC_HAS_TEXT:
664 proc_str( pls, (EscText *) ptr );
665 break;
666 }
667}
668
669//--------------------------------------------------------------------------
670// fill_polygon()
671//
672// Fill polygon described in points pls->dev_x[] and pls->dev_y[].
673// Only solid color fill supported.
674//--------------------------------------------------------------------------
675
676static void
678{
679 PSDev *dev = (PSDev *) pls->dev;
680 PLINT n, ix = 0, iy = 0;
681 PLINT x, y;
682
683 fprintf( OF, " Z\n" );
684
685 for ( n = 0; n < pls->dev_npts; n++ )
686 {
687 x = pls->dev_x[ix++];
688 y = pls->dev_y[iy++];
689
690// Rotate by 90 degrees
691
692 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x, &y );
693
694// First time through start with a x y moveto
695
696 if ( n == 0 )
697 {
698 snprintf( outbuf, OUTBUF_LEN, "N %d %d M", x, y );
699 dev->llx = MIN( dev->llx, x );
700 dev->lly = MIN( dev->lly, y );
701 dev->urx = MAX( dev->urx, x );
702 dev->ury = MAX( dev->ury, y );
703 fprintf( OF, "%s", outbuf );
704 pls->bytecnt += (PLINT) strlen( outbuf );
705 continue;
706 }
707
708 if ( pls->linepos + 21 > LINELENGTH )
709 {
710 putc( '\n', OF );
711 pls->linepos = 0;
712 }
713 else
714 putc( ' ', OF );
715
716 pls->bytecnt++;
717
718 snprintf( outbuf, OUTBUF_LEN, "%d %d D", x, y );
719 dev->llx = MIN( dev->llx, x );
720 dev->lly = MIN( dev->lly, y );
721 dev->urx = MAX( dev->urx, x );
722 dev->ury = MAX( dev->ury, y );
723
724 fprintf( OF, "%s", outbuf );
725 pls->bytecnt += (PLINT) strlen( outbuf );
726 pls->linepos += 21;
727 }
728 dev->xold = PL_UNDEFINED;
729 dev->yold = PL_UNDEFINED;
730 fprintf( OF, " F " );
731}
732
733//--------------------------------------------------------------------------
734// ps_getdate()
735//
736// Get the date and time
737//--------------------------------------------------------------------------
738
739static char *
741{
742 int len;
743 time_t t;
744 char *p;
745
746 t = time( (time_t *) 0 );
747 p = ctime( &t );
748 len = (int) strlen( p );
749 *( p + len - 1 ) = '\0'; // zap the newline character
750 return p;
751}
752
753
754// 0.8 should mimic the offset of first superscript/subscript level
755// implemented in plstr (plsym.c) for Hershey fonts. However, when
756// comparing with -dev xwin and -dev xcairo results changing this
757// factor to 0.6 appears to offset the centers of the letters
758// appropriately while 0.8 gives much poorer agreement with the
759// other devices.
760# define RISE_FACTOR 0.6
761
762//--------------------------------------------------------------------------
763// proc_str()
764//
765// Prints postscript strings.
766// N.B. Now unicode only, no string access!
767//
768//--------------------------------------------------------------------------
769
770void
772{
773 PLFLT *t = args->xform, tt[4]; // Transform matrices
774 PLFLT theta, shear, stride; // Rotation angle and shear from the matrix
775 PLFLT ft_ht, offset; // Font height and offset
776 PLFLT cs, sn, l1, l2;
777 PSDev *dev = (PSDev *) pls->dev;
778 const char *font;
779 char esc;
780 // Be generous. Used to store lots of font changes which take
781 // 3 characters per change.
782 #define PROC_STR_STRING_LENGTH 1000
783 unsigned char *strp, str[PROC_STR_STRING_LENGTH], *cur_strp,
784 cur_str[PROC_STR_STRING_LENGTH];
785 float font_factor = 1.4f;
786 PLINT clxmin, clxmax, clymin, clymax; // Clip limits
787 PLINT clipx[4], clipy[4]; // Current clip limits
788
789 PLFLT scale = 1., up = 0.; // Font scaling and shifting parameters
790
791 int i = 0; // String index
792
793 // unicode only! so test for it.
794 if ( args->unicode_array_len > 0 )
795 {
796 int j, s, f;
797 const char *fonts[PROC_STR_STRING_LENGTH];
798 const PLUNICODE *cur_text;
799 PLUNICODE fci, fci_save;
800 PLFLT old_sscale, sscale, old_soffset, soffset, ddup;
801 PLINT level = 0;
802 // translate from unicode into type 1 font index.
803 //
804 // Choose the font family, style, variant, and weight using
805 // the FCI (font characterization integer).
806 //
807
808 plgesc( &esc );
809 plgfci( &fci );
810 fci_save = fci;
811 font = get_font( dev, fci );
812 cur_text = args->unicode_array;
813 for ( f = s = j = 0; j < args->unicode_array_len; j++ )
814 {
815 if ( cur_text[j] & PL_FCI_MARK )
816 {
817 // process an FCI by saving it and escaping cur_str
818 // with an escff to make it a 2-character escape
819 // that is not used in legacy Hershey code
820 //
821 if ( ( f < PROC_STR_STRING_LENGTH ) && ( s + 3 < PROC_STR_STRING_LENGTH ) )
822 {
823 fci_save = cur_text[j];
824 fonts[f++] = get_font( dev, fci_save );
825 cur_str[s++] = (unsigned char) esc;
826 cur_str[s++] = 'f';
827 cur_str[s++] = 'f';
828 }
829 }
830 else if ( s + 4 < PROC_STR_STRING_LENGTH )
831 {
832#undef PL_TEST_TYPE1
833#ifdef PL_TEST_TYPE1
834 // Use this test case only to conveniently view Type1 font
835 // possibilities (as in test_type1.py example).
836 // This functionality is useless other than for this test case.
837 PLINT ifamily, istyle, iweight;
838 plgfont( &ifamily, &istyle, &iweight );
839 if ( 0 <= cur_text[j] && cur_text[j] < 256 )
840 cur_str[s++] = cur_text[j];
841 else
842 cur_str[s++] = 32;
843 // Overwrite font just for this special case.
844 if ( ifamily == PL_FCI_SYMBOL )
845 font = get_font( dev, 0 );
846 else
847 font = get_font( dev, fci );
848#else
849 cur_str[s] = plunicode2type1( cur_text[j], dev->lookup, dev->nlookup );
850 if ( cur_text[j] != ' ' && cur_str[s] == ' ' )
851 {
852 // failed lookup.
853 if ( !dev->if_symbol_font )
854 {
855 // failed standard font lookup. Use symbol
856 // font instead which will return a blank if
857 // that fails as well.
858 fonts[f++] = get_font( dev, 0 );
859 cur_str[s++] = (unsigned char) esc;
860 cur_str[s++] = 'f';
861 cur_str[s++] = 'f';
862 cur_str[s++] = plunicode2type1( cur_text[j], dev->lookup, dev->nlookup );
863 }
864 else
865 {
866 // failed symbol font lookup. Use last standard
867 // font instead which will return a blank if
868 // that fails as well.
869 fonts[f++] = get_font( dev, fci_save );
870 cur_str[s++] = (unsigned char) esc;
871 cur_str[s++] = 'f';
872 cur_str[s++] = 'f';
873 cur_str[s++] = plunicode2type1( cur_text[j], dev->lookup, dev->nlookup );
874 }
875 }
876 else
877 {
878 // lookup succeeded.
879 s++;
880 }
881#endif
882 pldebug( "proc_str", "unicode = 0x%x, type 1 code = %d\n",
883 cur_text[j], cur_str[s - 1] );
884 }
885 }
886 cur_str[s] = '\0';
887
888 // finish previous polyline
889
890 dev->xold = PL_UNDEFINED;
891 dev->yold = PL_UNDEFINED;
892
893 // Determine the font height
894 ft_ht = pls->chrht * 72.0 / 25.4; // ft_ht in points, ht is in mm
895
896
897 // The transform matrix has only rotations and shears; extract them
898 plRotationShear( t, &theta, &shear, &stride );
899 cs = cos( theta );
900 sn = sin( theta );
901 tt[0] = t[0] * cs + t[2] * sn;
902 tt[1] = t[1] * cs + t[3] * sn;
903 tt[2] = -t[0] * sn + t[2] * cs;
904 tt[3] = -t[1] * sn + t[3] * cs;
905
906 //
907 // Reference point conventions:
908 // If base = 0, it is aligned with the center of the text box
909 // If base = 1, it is aligned with the baseline of the text box
910 // If base = 2, it is aligned with the top of the text box
911 //
912 // Currently plplot only uses base=0
913 // Postscript uses base=1
914 //
915 // We must calculate the difference between the two and apply the offset.
916 //
917
918 if ( args->base == 2 ) // not supported by plplot
919 offset = ENLARGE * ft_ht / 2.; // half font height
920 else if ( args->base == 1 )
921 offset = 0.;
922 else
923 offset = -ENLARGE * ft_ht / 2.;
924
925 // Determine the adjustment for page orientation
926 theta -= PI / 2. * pls->diorot;
927 args->y += (PLINT) ( offset * cos( theta ) );
928 args->x -= (PLINT) ( offset * sin( theta ) );
929
930 // ps driver is rotated by default
931 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
932 &( args->x ), &( args->y ) );
933
934 // Correct for the fact ps driver uses landscape by default
935 theta += PI / 2.;
936
937 // Output
938 // Set clipping
939 clipx[0] = pls->clpxmi;
940 clipx[2] = pls->clpxma;
941 clipy[0] = pls->clpymi;
942 clipy[2] = pls->clpyma;
943 clipx[1] = clipx[2];
944 clipy[1] = clipy[0];
945 clipx[3] = clipx[0];
946 clipy[3] = clipy[2];
947 difilt( clipx, clipy, 4, &clxmin, &clxmax, &clymin, &clymax );
948 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
949 &clipx[0], &clipy[0] );
950 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
951 &clipx[1], &clipy[1] );
952 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
953 &clipx[2], &clipy[2] );
954 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
955 &clipx[3], &clipy[3] );
956 fprintf( OF, " gsave %d %d %d %d %d %d %d %d CL\n", clipx[0], clipy[0], clipx[1], clipy[1], clipx[2], clipy[2], clipx[3], clipy[3] );
957
958 // move to string reference point
959 fprintf( OF, " %d %d M\n", args->x, args->y );
960
961 // Save the current position and set the string rotation
962 fprintf( OF, "gsave %.3f R\n", TRMFLT( theta * 180. / PI ) );
963
964 // Purge escape sequences from string, so that postscript can find it's
965 // length. The string length is computed with the current font, and can
966 // thus be wrong if there are font change escape sequences in the string
967 //
968
969 esc_purge( str, cur_str );
970
971 fprintf( OF, "/%s %.3f SF\n", font, TRMFLT( font_factor * ENLARGE * ft_ht ) );
972
973 // Output string, while escaping the '(', ')' and '\' characters.
974 // this string is output for measurement purposes only.
975 //
976 fprintf( OF, "%.3f (", TRMFLT( -args->just ) );
977 while ( str[i] != '\0' )
978 {
979 if ( str[i] == '(' || str[i] == ')' || str[i] == '\\' )
980 fprintf( OF, "\\%c", str[i] );
981 else
982 fprintf( OF, "%c", str[i] );
983 i++;
984 }
985 fprintf( OF, ") SW\n" );
986
987
988 // Parse string for PLplot escape sequences and print everything out
989
990 cur_strp = cur_str;
991 f = 0;
992 do
993 {
994 strp = str;
995
996 if ( *cur_strp == esc )
997 {
998 cur_strp++;
999
1000 if ( *cur_strp == esc ) // <esc><esc>
1001 {
1002 *strp++ = *cur_strp++;
1003 }
1004 else if ( *cur_strp == 'f' )
1005 {
1006 cur_strp++;
1007 if ( *cur_strp++ != 'f' )
1008 {
1009 // escff occurs because of logic above. But any suffix
1010 // other than "f" should never happen.
1011 plabort( "proc_str, internal PLplot logic error;"
1012 "wrong escf escape sequence" );
1013 return;
1014 }
1015 font = fonts[f++];
1016 pldebug( "proc_str", "string-specified fci = 0x%x, font name = %s\n", fci, font );
1017 continue;
1018 }
1019 else
1020 switch ( *cur_strp++ )
1021 {
1022 case 'd': //subscript
1023 case 'D':
1024 plP_script_scale( FALSE, &level,
1025 &old_sscale, &sscale, &old_soffset, &soffset );
1026 scale = sscale;
1027 // The correction for the difference in magnitude
1028 // between the baseline and middle coordinate systems
1029 // for subscripts should be
1030 // -0.5*(base font size - superscript/subscript font size).
1031 ddup = -0.5 * ( 1.0 - sscale );
1032 up = -font_factor * ENLARGE * ft_ht * ( RISE_FACTOR * soffset + ddup );
1033 break;
1034
1035 case 'u': //superscript
1036 case 'U':
1037 plP_script_scale( TRUE, &level,
1038 &old_sscale, &sscale, &old_soffset, &soffset );
1039 scale = sscale;
1040 // The correction for the difference in magnitude
1041 // between the baseline and middle coordinate systems
1042 // for superscripts should be
1043 // 0.5*(base font size - superscript/subscript font size).
1044 ddup = 0.5 * ( 1.0 - sscale );
1045 up = font_factor * ENLARGE * ft_ht * ( RISE_FACTOR * soffset + ddup );
1046 break;
1047
1048 // ignore the next sequences
1049
1050 case '+':
1051 case '-':
1052 case 'b':
1053 case 'B':
1054 plwarn( "'+', '-', and 'b/B' text escape sequences not processed." );
1055 break;
1056 }
1057 }
1058
1059 // copy from current to next token, adding a postscript escape
1060 // char '\' if necessary
1061 //
1062 while ( *cur_strp && *cur_strp != esc )
1063 {
1064 if ( *cur_strp == '(' || *cur_strp == ')' || *cur_strp == '\\' )
1065 *strp++ = '\\';
1066 *strp++ = *cur_strp++;
1067 }
1068 *strp = '\0';
1069
1070 if ( fabs( up ) < 0.001 )
1071 up = 0.; // Watch out for small differences
1072
1073 // Apply the scaling and the shear
1074 fprintf( OF, "/%s [%.3f %.3f %.3f %.3f 0 0] SF\n",
1075 font,
1076 TRMFLT( tt[0] * font_factor * ENLARGE * ft_ht * scale ),
1077 TRMFLT( tt[2] * font_factor * ENLARGE * ft_ht * scale ),
1078 TRMFLT( tt[1] * font_factor * ENLARGE * ft_ht * scale ),
1079 TRMFLT( tt[3] * font_factor * ENLARGE * ft_ht * scale ) );
1080
1081 // if up/down escape sequences, save current point and adjust baseline;
1082 // take the shear into account
1083 if ( up != 0. )
1084 fprintf( OF, "gsave %.3f %.3f rmoveto\n", TRMFLT( up * tt[1] ), TRMFLT( up * tt[3] ) );
1085
1086 // print the string
1087 fprintf( OF, "(%s) show\n", str );
1088
1089 // back to baseline
1090 if ( up != 0. )
1091 fprintf( OF, "grestore (%s) stringwidth rmoveto\n", str );
1092 } while ( *cur_strp );
1093
1094 fprintf( OF, "grestore\n" );
1095 fprintf( OF, "grestore\n" );
1096
1097 //
1098 // keep driver happy -- needed for background and orientation.
1099 // arghhh! can't calculate it, as I only have the string reference
1100 // point, not its extent!
1101 // Still a hack - but at least it takes into account the string
1102 // length and justification. Character width is assumed to be
1103 // 0.6 * character height. Add on an extra 1.5 * character height
1104 // for safety.
1105 //
1106 cs = cos( theta );
1107 sn = sin( theta );
1108 l1 = -i * args->just;
1109 l2 = i * ( 1. - args->just );
1110 // Factor of 0.6 is an empirical fudge to convert character
1111 // height to average character width
1112 l1 *= 0.6;
1113 l2 *= 0.6;
1114
1115 dev->llx = (int) ( MIN( dev->llx, args->x + ( MIN( l1 * cs, l2 * cs ) - 1.5 ) * font_factor * ft_ht * ENLARGE ) );
1116 dev->lly = (int) ( MIN( dev->lly, args->y + ( MIN( l1 * sn, l2 * sn ) - 1.5 ) * font_factor * ft_ht * ENLARGE ) );
1117 dev->urx = (int) ( MAX( dev->urx, args->x + ( MAX( l1 * cs, l2 * cs ) + 1.5 ) * font_factor * ft_ht * ENLARGE ) );
1118 dev->ury = (int) ( MAX( dev->ury, args->y + ( MAX( l1 * sn, l2 * sn ) + 1.5 ) * font_factor * ft_ht * ENLARGE ) );
1119 }
1120}
1121
1122static void
1123esc_purge( unsigned char *dstr, unsigned char *sstr )
1124{
1125 char esc;
1126
1127 plgesc( &esc );
1128
1129 while ( *sstr )
1130 {
1131 if ( *sstr != esc )
1132 {
1133 *dstr++ = *sstr++;
1134 continue;
1135 }
1136
1137 sstr++;
1138 if ( *sstr == esc )
1139 {
1140 *dstr++ = *sstr++;
1141 continue;
1142 }
1143
1144 else
1145 {
1146 switch ( *sstr++ )
1147 {
1148 case 'f':
1149 sstr++;
1150 break; // two chars sequence
1151
1152 default:
1153 break; // single char escape
1154 }
1155 }
1156 }
1157 *dstr = '\0';
1158}
1159
1160//--------------------------------------------------------------------------
1161// unsigned char plunicode2type1 (const PLUNICODE index,
1162// const Unicode_to_Type1_table lookup[], const int number_of_entries)
1163//
1164// Function takes an input unicode index, looks through the lookup
1165// table (which must be sorted by PLUNICODE Unicode), then returns the
1166// corresponding Type1 code in the lookup table. If the Unicode index is
1167// not present the returned value is 32 (which is normally a blank
1168// for Type 1 fonts).
1169//--------------------------------------------------------------------------
1170
1171static unsigned char
1173 const Unicode_to_Type1_table lookup[],
1174 const int nlookup )
1175{
1176 int jlo = -1, jmid, jhi = nlookup;
1177 while ( jhi - jlo > 1 )
1178 {
1179 // Note that although jlo or jhi can be just outside valid
1180 // range (see initialization above) because of while condition
1181 // jlo < jmid < jhi and jmid must be in valid range.
1182 //
1183 jmid = ( jlo + jhi ) / 2;
1184 if ( index > lookup[jmid].Unicode )
1185 jlo = jmid;
1186 else if ( index < lookup[jmid].Unicode )
1187 jhi = jmid;
1188 else
1189 // We have found it!
1190 // index == lookup[jmid].Unicode
1191 //
1192 return ( lookup[jmid].Type1 );
1193 }
1194 // jlo is invalid or it is valid and index > lookup[jlo].Unicode.
1195 // jhi is invalid or it is valid and index < lookup[jhi].Unicode.
1196 // All these conditions together imply index cannot be found in lookup.
1197 // Mark with ' ' (which is normally the index for blank in type 1 fonts).
1198 //
1199 return ( ' ' );
1200}
1201
1202//--------------------------------------------------------------------------
1203// get_font( PSDev* dev, PLUNICODE fci )
1204//
1205// Sets the Type1 font.
1206//--------------------------------------------------------------------------
1207static const char *
1209{
1210 const char *font;
1211 // fci = 0 is a special value indicating the Type 1 Symbol font
1212 // is desired. This value cannot be confused with a normal FCI value
1213 // because it doesn't have the PL_FCI_MARK.
1214 if ( fci == 0 )
1215 {
1216 font = "Symbol";
1219 dev->if_symbol_font = 1;
1220 }
1221 else
1222 {
1223 // convert the fci to Base14/Type1 font information
1227 dev->if_symbol_font = 0;
1228 }
1229 pldebug( "set_font", "fci = 0x%x, font name = %s\n", fci, font );
1230 return ( font );
1231}
#define RISE_FACTOR
Definition cairo.c:1226
@ plDevType_FileOriented
Definition disptab.h:13
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
Definition disptab.h:68
void(* plD_tidy_fp)(struct PLStream_struct *)
Definition disptab.h:72
void(* plD_bop_fp)(struct PLStream_struct *)
Definition disptab.h:71
void(* plD_state_fp)(struct PLStream_struct *, PLINT)
Definition disptab.h:73
void(* plD_eop_fp)(struct PLStream_struct *)
Definition disptab.h:70
void(* plD_init_fp)(struct PLStream_struct *)
Definition disptab.h:67
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
Definition disptab.h:74
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
Definition disptab.h:69
PLDLLIMPEXP_DRIVER void plD_dispatch_init_psc(PLDispatchTable *pdt)
PLDLLIMPEXP_DRIVER void plD_dispatch_init_ps(PLDispatchTable *pdt)
#define MIN(a, b)
Definition dsplint.c:29
#define MAX(a, b)
Definition dsplint.c:28
#define PLPLOT_VERSION
Definition plConfig.h:54
int plParseDrvOpts(DrvOpt *acc_opt)
Definition plargs.c:1461
void difilt(PLINT *xsc, PLINT *ysc, PLINT npts, PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma)
Definition plcore.c:1460
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
Definition plcore.c:4238
void plgesc(char *p_esc)
Definition plcore.c:3914
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
Definition plcore.c:4249
static PLStream * pls[PL_NSTREAMS]
Definition plcore.h:88
void plFamInit(PLStream *pls)
Definition plctrl.c:2751
void plwarn(PLCHAR_VECTOR errormsg)
Definition plctrl.c:1863
void plCloseFile(PLStream *pls)
Definition plctrl.c:2635
void plOpenFile(PLStream *pls)
Definition plctrl.c:2571
void plexit(PLCHAR_VECTOR errormsg)
Definition plctrl.c:1958
void plGetFam(PLStream *pls)
Definition plctrl.c:2780
void plRotPhy(PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax, PLINT *px, PLINT *py)
Definition plctrl.c:2824
void plabort(PLCHAR_VECTOR errormsg)
Definition plctrl.c:1894
#define PLDLLIMPEXP_DRIVER
Definition pldll.h:81
static const FCI_to_FontName_Table Type1Lookup[N_Type1Lookup]
Definition plfci-type1.h:42
#define N_Type1Lookup
Definition plfci-type1.h:41
void plRotationShear(PLFLT *xFormMatrix, PLFLT *rotation, PLFLT *shear, PLFLT *stride)
Definition plot3d.c:2767
#define PI
Definition plplotP.h:290
#define LPAGE_X
Definition plplotP.h:308
#define PLSTATE_WIDTH
Definition plplotP.h:362
@ DRV_INT
Definition plplotP.h:758
#define PLSTATE_COLOR1
Definition plplotP.h:364
#define TRUE
Definition plplotP.h:176
#define FALSE
Definition plplotP.h:177
#define PL_UNDEFINED
Definition plplotP.h:219
#define LPAGE_Y
Definition plplotP.h:309
#define ORIENTATION
Definition plplotP.h:358
#define PLSTATE_COLOR0
Definition plplotP.h:363
#define plgfci
Definition plplot.h:735
#define PLESC_HAS_TEXT
Definition plplot.h:290
PLUINT PLUNICODE
Definition plplot.h:201
float PLFLT
Definition plplot.h:163
#define plgfont
Definition plplot.h:737
#define plsdiori
Definition plplot.h:809
#define PLESC_FILL
Definition plplot.h:279
int PLINT
Definition plplot.h:181
#define PL_FCI_SYMBOL
Definition plplot.h:384
#define PL_FCI_MARK
Definition plplot.h:370
PLCHAR_VECTOR plP_FCI2FontName(PLUNICODE fci, const FCI_to_FontName_Table lookup[], const int nlookup)
Definition plsym.c:1548
void plP_script_scale(PLBOOL ifupper, PLINT *level, PLFLT *old_scale, PLFLT *scale, PLFLT *old_offset, PLFLT *offset)
Definition plsym.c:1302
static const Unicode_to_Type1_table unicode_to_symbol_lookup_table[194]
static const int number_of_entries_in_unicode_to_standard_table
static const int number_of_entries_in_unicode_to_symbol_table
static const Unicode_to_Type1_table unicode_to_standard_lookup_table[154]
void plD_line_ps(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
Definition ps.c:421
static int color
Definition ps.c:78
static void proc_str(PLStream *, EscText *)
Definition ps.c:771
static void ps_init(PLStream *)
Definition ps.c:173
static const char * get_font(PSDev *dev, PLUNICODE fci)
Definition ps.c:1208
static void esc_purge(unsigned char *, unsigned char *)
Definition ps.c:1123
static unsigned char plunicode2type1(const PLUNICODE index, const Unicode_to_Type1_table lookup[], const int number_of_entries)
Definition ps.c:1172
static char * ps_getdate(void)
Definition ps.c:740
static char outbuf[OUTBUF_LEN]
Definition ps.c:76
#define OUTBUF_LEN
Definition ps.c:75
#define TRMFLT(a)
Definition ps.c:45
static void ps_dispatch_init_helper(PLDispatchTable *pdt, const char *menustr, const char *devnam, int type, int seq, plD_init_fp init)
Definition ps.c:99
void plD_eop_ps(PLStream *pls)
Definition ps.c:494
static DrvOpt ps_options[]
Definition ps.c:81
void plD_polyline_ps(PLStream *pls, short *xa, short *ya, PLINT npts)
Definition ps.c:479
PLDLLIMPEXP_DRIVER const char * plD_DEVICE_INFO_ps
Definition ps.c:49
static int hrshsym
Definition ps.c:79
static void fill_polygon(PLStream *pls)
Definition ps.c:677
void plD_esc_ps(PLStream *pls, PLINT op, void *ptr)
Definition ps.c:656
void plD_tidy_ps(PLStream *pls)
Definition ps.c:555
#define PROC_STR_STRING_LENGTH
static int text
Definition ps.c:77
void plD_bop_ps(PLStream *pls)
Definition ps.c:507
void plD_state_ps(PLStream *pls, PLINT op)
Definition ps.c:601
#define MAX_WIDTH
Definition ps.h:26
#define LINELENGTH
Definition ps.h:13
#define PSY
Definition ps.h:23
#define OF
Definition ps.h:24
#define XPSSIZE
Definition ps.h:18
#define COPIES
Definition ps.h:14
#define XOFFSET
Definition ps.h:20
#define YPSSIZE
Definition ps.h:19
#define YOFFSET
Definition ps.h:21
#define PSX
Definition ps.h:22
void plD_init_ps(PLStream *)
#define DEF_WIDTH
Definition ps.h:27
#define XSIZE
Definition ps.h:15
#define ENLARGE
Definition ps.h:17
#define MIN_WIDTH
Definition ps.h:25
void plD_init_psc(PLStream *)
#define YSIZE
Definition ps.h:16
unsigned short unicode_array_len
Definition plplotP.h:736
PLINT base
Definition plplotP.h:707
PLFLT just
Definition plplotP.h:708
PLINT x
Definition plplotP.h:712
PLUNICODE * unicode_array
Definition plplotP.h:735
PLINT y
Definition plplotP.h:713
PLFLT * xform
Definition plplotP.h:709
plD_eop_fp pl_eop
Definition disptab.h:86
const char * pl_DevName
Definition disptab.h:80
plD_esc_fp pl_esc
Definition disptab.h:90
plD_polyline_fp pl_polyline
Definition disptab.h:85
plD_state_fp pl_state
Definition disptab.h:89
plD_tidy_fp pl_tidy
Definition disptab.h:88
plD_line_fp pl_line
Definition disptab.h:84
plD_init_fp pl_init
Definition disptab.h:83
plD_bop_fp pl_bop
Definition disptab.h:87
const char * pl_MenuStr
Definition disptab.h:79
Definition ps.h:39
int llx
Definition ps.h:51
int ury
Definition ps.h:51
int if_symbol_font
Definition ps.h:53
PLINT ymin
Definition ps.h:44
PLINT ymax
Definition ps.h:44
int ptcnt
Definition ps.h:51
const Unicode_to_Type1_table * lookup
Definition ps.h:54
int lly
Definition ps.h:51
PLINT xmin
Definition ps.h:43
PLINT xold
Definition ps.h:41
int urx
Definition ps.h:51
PLINT xlen
Definition ps.h:43
PLINT ylen
Definition ps.h:44
int nlookup
Definition ps.h:53
PLINT xmax
Definition ps.h:43
PLINT yold
Definition ps.h:41