PLplot  5.15.0
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 
67 static char *ps_getdate( void );
68 static void ps_init( PLStream * );
69 static void fill_polygon( PLStream *pls );
70 static void proc_str( PLStream *, EscText * );
71 static 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
76 static char outbuf[OUTBUF_LEN];
77 static int text = 1;
78 static int color;
79 static int hrshsym = 1;
80 
81 static 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 
86 static unsigned char
87 plunicode2type1( const PLUNICODE index,
88  const Unicode_to_Type1_table lookup[],
89  const int number_of_entries );
90 
91 static const char *
92 get_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;
115  pdt->pl_eop = (plD_eop_fp) plD_eop_ps;
116  pdt->pl_bop = (plD_bop_fp) plD_bop_ps;
119  pdt->pl_esc = (plD_esc_fp) plD_esc_ps;
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 
137 void
139 {
140  color = 0;
141  pls->color = 0; // Not a color device
142 
143  plParseDrvOpts( ps_options );
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 
159 void
160 plD_init_psc( PLStream *pls )
161 {
162  color = 1;
163  pls->color = 1; // Is a color device
164  plParseDrvOpts( ps_options );
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 
172 static 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 
420 void
421 plD_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 
478 void
479 plD_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 
493 void
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 
506 void
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 
545  plD_state_ps( pls, PLSTATE_WIDTH );
546 }
547 
548 //--------------------------------------------------------------------------
549 // plD_tidy_ps()
550 //
551 // Close graphics file or otherwise clean up.
552 //--------------------------------------------------------------------------
553 
554 void
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 
600 void
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 
655 void
656 plD_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 
676 static 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 
739 static char *
740 ps_getdate( void )
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 
770 void
771 proc_str( PLStream *pls, EscText *args )
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 
1122 static void
1123 esc_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 
1171 static 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 //--------------------------------------------------------------------------
1207 static 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
1224  font = plP_FCI2FontName( fci, Type1Lookup, N_Type1Lookup );
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 TRMFLT(a)
Definition: ps.c:45
int plParseDrvOpts(DrvOpt *acc_opt)
Definition: plargs.c:1461
void plP_script_scale(PLBOOL ifupper, PLINT *level, PLFLT *old_scale, PLFLT *scale, PLFLT *old_offset, PLFLT *offset)
Definition: plsym.c:1302
#define XPSSIZE
Definition: ps.h:18
int llx
Definition: ps.h:51
void plgesc(char *p_esc)
Definition: plcore.c:3914
#define OUTBUF_LEN
Definition: ps.c:75
#define ENLARGE
Definition: ps.h:17
PLINT ymax
Definition: ps.h:44
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
int width
Definition: plplotter.c:119
PLINT ymin
Definition: ps.h:44
PLINT xold
Definition: ps.h:41
PLFLT just
Definition: plplotP.h:708
unsigned char b
Definition: plplot.h:550
PLINT xmax
Definition: ps.h:43
int if_symbol_font
Definition: ps.h:53
PLDLLIMPEXP_DRIVER void plD_dispatch_init_psc(PLDispatchTable *pdt)
#define PLESC_FILL
Definition: plplot.h:279
void plD_init_psc(PLStream *)
plD_esc_fp pl_esc
Definition: disptab.h:90
static const Unicode_to_Type1_table unicode_to_symbol_lookup_table[194]
PLUINT PLUNICODE
Definition: plplot.h:201
#define PL_FCI_SYMBOL
Definition: plplot.h:384
const Unicode_to_Type1_table * lookup
Definition: ps.h:54
void plOpenFile(PLStream *pls)
Definition: plctrl.c:2571
PLINT yold
Definition: ps.h:41
void plCloseFile(PLStream *pls)
Definition: plctrl.c:2635
static const int number_of_entries_in_unicode_to_standard_table
void plGetFam(PLStream *pls)
Definition: plctrl.c:2780
void(* plD_tidy_fp)(struct PLStream_struct *)
Definition: disptab.h:72
PLINT dev_text
Definition: plstrm.h:572
PLFLT xdpi
Definition: plstrm.h:616
PLINT dev_npts
Definition: plstrm.h:581
const char * pl_MenuStr
Definition: disptab.h:79
static void ps_init(PLStream *)
Definition: ps.c:173
PLINT color
Definition: plstrm.h:569
PLINT dev_unicode
Definition: plstrm.h:747
void plD_init_ps(PLStream *)
void plD_esc_ps(PLStream *pls, PLINT op, void *ptr)
Definition: ps.c:656
plD_tidy_fp pl_tidy
Definition: disptab.h:88
#define MAX(a, b)
Definition: dsplint.c:28
void(* plD_init_fp)(struct PLStream_struct *)
Definition: disptab.h:67
#define plsdiori
Definition: plplot.h:809
PLFLT diorot
Definition: plstrm.h:661
static char * ps_getdate(void)
Definition: ps.c:740
void(* plD_eop_fp)(struct PLStream_struct *)
Definition: disptab.h:70
const char * pl_DevName
Definition: disptab.h:80
#define PLSTATE_COLOR0
Definition: plplotP.h:363
plD_init_fp pl_init
Definition: disptab.h:83
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1894
void plD_state_ps(PLStream *pls, PLINT op)
Definition: ps.c:601
PLINT xmin
Definition: ps.h:43
PLINT ylen
Definition: ps.h:44
#define PLSTATE_COLOR1
Definition: plplotP.h:364
#define PSY
Definition: ps.h:23
#define OF
Definition: ps.h:24
#define PSX
Definition: ps.h:22
PLDLLIMPEXP_DRIVER void plD_dispatch_init_ps(PLDispatchTable *pdt)
short * dev_x
Definition: plstrm.h:582
void plFamInit(PLStream *pls)
Definition: plctrl.c:2751
#define PLSTATE_WIDTH
Definition: plplotP.h:362
#define plgfont
Definition: plplot.h:737
static int color
Definition: ps.c:78
int PLINT
Definition: plplot.h:181
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
#define MIN(a, b)
Definition: dsplint.c:29
static const int number_of_entries_in_unicode_to_symbol_table
#define YOFFSET
Definition: ps.h:21
PLINT portrait
Definition: plstrm.h:665
#define RISE_FACTOR
Definition: ps.c:760
#define LINELENGTH
Definition: ps.h:13
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
Definition: disptab.h:68
static unsigned char plunicode2type1(const PLUNICODE index, const Unicode_to_Type1_table lookup[], const int number_of_entries)
Definition: ps.c:1172
unsigned char g
Definition: plplot.h:549
int urx
Definition: ps.h:51
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
Definition: disptab.h:74
int ury
Definition: ps.h:51
PLINT clpymi
Definition: plstrm.h:704
#define MIN_WIDTH
Definition: ps.h:25
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
Definition: disptab.h:69
#define snprintf
Definition: plplotP.h:235
PLINT termin
Definition: plstrm.h:568
PLINT icol0
Definition: plstrm.h:539
#define TRUE
Definition: plplotP.h:176
PLINT dev_hrshsym
Definition: plstrm.h:753
PLINT ylength
Definition: plstrm.h:617
#define N_Type1Lookup
Definition: plfci-type1.h:41
#define FALSE
Definition: plplotP.h:177
plD_bop_fp pl_bop
Definition: disptab.h:87
#define DEF_WIDTH
Definition: ps.h:27
static const char * get_font(PSDev *dev, PLUNICODE fci)
Definition: ps.c:1208
void difilt(PLINT *xsc, PLINT *ysc, PLINT npts, PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma)
Definition: plcore.c:1460
#define LPAGE_Y
Definition: plplotP.h:309
void plD_tidy_ps(PLStream *pls)
Definition: ps.c:555
#define ORIENTATION
Definition: plplotP.h:358
plD_line_fp pl_line
Definition: disptab.h:84
static const FCI_to_FontName_Table Type1Lookup[N_Type1Lookup]
Definition: plfci-type1.h:42
#define XSIZE
Definition: ps.h:15
static void proc_str(PLStream *, EscText *)
Definition: ps.c:771
#define PL_UNDEFINED
Definition: plplotP.h:219
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
Definition: plcore.c:4238
PLColor * cmap0
Definition: plstrm.h:544
PLINT xlen
Definition: ps.h:43
#define YPSSIZE
Definition: ps.h:19
#define COPIES
Definition: ps.h:14
void plD_line_ps(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
Definition: ps.c:421
#define PLDLLIMPEXP_DRIVER
Definition: pldll.h:81
#define XOFFSET
Definition: ps.h:20
static void fill_polygon(PLStream *pls)
Definition: ps.c:677
#define MAX_WIDTH
Definition: ps.h:26
PLFLT ydpi
Definition: plstrm.h:616
PLINT clpxmi
Definition: plstrm.h:704
static PLStream * pls[PL_NSTREAMS]
Definition: plcore.h:88
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
Definition: plcore.c:4249
#define plgfci
Definition: plplot.h:735
PLINT family
Definition: plstrm.h:570
Definition: ps.h:38
PLINT xlength
Definition: plstrm.h:617
void plRotationShear(PLFLT *xFormMatrix, PLFLT *rotation, PLFLT *shear, PLFLT *stride)
Definition: plot3d.c:2767
#define LPAGE_X
Definition: plplotP.h:308
PLINT yoffset
Definition: plstrm.h:618
static void esc_purge(unsigned char *, unsigned char *)
Definition: ps.c:1123
int ptcnt
Definition: ps.h:51
unsigned short unicode_array_len
Definition: plplotP.h:736
short * dev_y
Definition: plstrm.h:582
PLDLLIMPEXP_DRIVER const char * plD_DEVICE_INFO_ps
Definition: ps.c:49
void plD_bop_ps(PLStream *pls)
Definition: ps.c:507
#define YSIZE
Definition: ps.h:16
static int text
Definition: ps.c:77
int nlookup
Definition: ps.h:53
float PLFLT
Definition: plplot.h:163
PLINT linepos
Definition: plstrm.h:578
PLFLT chrht
Definition: plstrm.h:686
PLINT page
Definition: plstrm.h:578
void(* plD_bop_fp)(struct PLStream_struct *)
Definition: disptab.h:71
#define PLPLOT_VERSION
Definition: plConfig.h:54
void plRotPhy(PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax, PLINT *px, PLINT *py)
Definition: plctrl.c:2824
#define PI
Definition: plplotP.h:290
PLCHAR_VECTOR plP_FCI2FontName(PLUNICODE fci, const FCI_to_FontName_Table lookup[], const int nlookup)
Definition: plsym.c:1548
int lly
Definition: ps.h:51
unsigned char r
Definition: plplot.h:548
#define PLESC_HAS_TEXT
Definition: plplot.h:290
PLFLT width
Definition: plstrm.h:552
void plwarn(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1863
PLINT y
Definition: plplotP.h:713
static char outbuf[OUTBUF_LEN]
Definition: ps.c:76
#define PROC_STR_STRING_LENGTH
static DrvOpt ps_options[]
Definition: ps.c:81
void plD_polyline_ps(PLStream *pls, short *xa, short *ya, PLINT npts)
Definition: ps.c:479
PLColor curcolor
Definition: plstrm.h:543
plD_state_fp pl_state
Definition: disptab.h:89
PLINT clpxma
Definition: plstrm.h:704
static int hrshsym
Definition: ps.c:79
plD_eop_fp pl_eop
Definition: disptab.h:86
PLINT xoffset
Definition: plstrm.h:618
PLINT x
Definition: plplotP.h:712
static const Unicode_to_Type1_table unicode_to_standard_lookup_table[154]
plD_polyline_fp pl_polyline
Definition: disptab.h:85
void(* plD_state_fp)(struct PLStream_struct *, PLINT)
Definition: disptab.h:73
PLUNICODE * unicode_array
Definition: plplotP.h:735
void * dev
Definition: plstrm.h:594
void plD_eop_ps(PLStream *pls)
Definition: ps.c:494
PLINT freeaspect
Definition: plstrm.h:665
PLINT bytecnt
Definition: plstrm.h:578
PLINT dev_fill0
Definition: plstrm.h:571
PLFLT * xform
Definition: plplotP.h:709
PLINT dev_eofill
Definition: plstrm.h:788
PLINT base
Definition: plplotP.h:707
PLINT clpyma
Definition: plstrm.h:704
#define PL_FCI_MARK
Definition: plplot.h:370