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