34 #if defined ( PLD_psttf )
50 #define TRMFLT( a ) ( ( fabs( a ) < 5.0e-4 ) ? 0.0 : ( a ) )
58 "psttf:PostScript File (monochrome):0:psttf:55:psttfm\n"
59 "psttfc:PostScript File (color):0:psttf:56:psttfc\n";
67 static char *ps_getdate(
void );
73 #define OUTBUF_LEN 128
74 static char outbuf[OUTBUF_LEN];
81 #define N_Pango_Lookup 5
83 const char * DefaultFamilyLookup[N_Pango_Lookup] = {
91 const char * EnvFamilyLookup[N_Pango_Lookup] = {
92 "PLPLOT_FREETYPE_SANS_FAMILY",
93 "PLPLOT_FREETYPE_SERIF_FAMILY",
94 "PLPLOT_FREETYPE_MONO_FAMILY",
95 "PLPLOT_FREETYPE_SCRIPT_FAMILY",
96 "PLPLOT_FREETYPE_SYMBOL_FAMILY"
99 #define FAMILY_LOOKUP_LEN 1024
102 const FontWeight WeightLookup[2] = {
107 const FontStyle StyleLookup[3] = {
113 static DrvOpt ps_options[] = { {
"text",
DRV_INT, &
text,
"Use Postscript text (text=0|1)" },
114 {
"color",
DRV_INT, &color,
"Use color (color=0|1)" },
115 {
"hrshsym",
DRV_INT, &
hrshsym,
"Use Hershey symbol set (hrshsym=0|1)" },
116 { NULL,
DRV_INT, NULL, NULL } };
124 const char *menustr,
const char *devnam,
127 #ifndef ENABLE_DYNDRIVERS
148 psttf_dispatch_init_helper( pdt,
149 "PostScript File (monochrome)",
"psttf",
156 psttf_dispatch_init_helper( pdt,
157 "PostScript File (color)",
"psttfc",
192 #define MAX_NUM_TRIES 10
199 PostscriptDocument *doc;
208 if ( pls->
xdpi <= 0 )
210 if ( pls->
ydpi <= 0 )
236 if ( pls->
psdoc != NULL )
237 delete (PostscriptDocument *) pls->
psdoc;
239 pls->
psdoc =
new PostscriptDocument();
240 doc = (PostscriptDocument *) ( pls->
psdoc );
241 doc->osBody() << fixed;
242 doc->osBody().precision( 3 );
246 if ( pls->
dev != NULL )
247 free( (
void *) pls->
dev );
249 pls->
dev = calloc( 1, (
size_t)
sizeof (
PSDev ) );
250 if ( pls->
dev == NULL )
251 plexit(
"ps_init: Out of memory." );
292 for ( i = 0; i < N_Pango_Lookup; i++ )
294 if ( ( a = getenv( EnvFamilyLookup[i] ) ) != NULL )
317 PostscriptDocument *doc = (PostscriptDocument *) ( pls->
psdoc );
319 doc->osHeader() <<
"%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
321 doc->osHeader() <<
"%%Title: PLplot Graph\n";
322 doc->osHeader() <<
"%%Creator: PLplot Version " <<
VERSION <<
"\n";
323 doc->osHeader() <<
"%%CreationDate: " << ps_getdate() <<
"\n";
324 doc->osHeader() <<
"%%Pages: (atend)\n";
325 doc->osHeader() <<
"%%EndComments\n\n";
330 doc->osHeader() <<
"/PSSave save def\n";
334 doc->osHeader() <<
"/PSDict 200 dict def\n";
335 doc->osHeader() <<
"PSDict begin\n";
337 doc->osHeader() <<
"/@restore /restore load def\n";
338 doc->osHeader() <<
"/restore\n";
339 doc->osHeader() <<
" {vmstatus pop\n";
340 doc->osHeader() <<
" dup @VMused lt {pop @VMused} if\n";
341 doc->osHeader() <<
" exch pop exch @restore /@VMused exch def\n";
342 doc->osHeader() <<
" } def\n";
343 doc->osHeader() <<
"/@pri\n";
344 doc->osHeader() <<
" {\n";
345 doc->osHeader() <<
" ( ) print\n";
346 doc->osHeader() <<
" ( ) cvs print\n";
347 doc->osHeader() <<
" } def\n";
351 doc->osHeader() <<
"/@copies\n";
352 doc->osHeader() <<
" {\n";
353 doc->osHeader() <<
" /#copies exch def\n";
354 doc->osHeader() <<
" } def\n";
358 doc->osHeader() <<
"/@start\n";
359 doc->osHeader() <<
" {\n";
360 doc->osHeader() <<
" vmstatus pop /@VMused exch def pop\n";
361 doc->osHeader() <<
" } def\n";
365 doc->osHeader() <<
"/@end\n";
366 doc->osHeader() <<
" {flush\n";
367 doc->osHeader() <<
" end\n";
368 doc->osHeader() <<
" PSSave restore\n";
369 doc->osHeader() <<
" } def\n";
374 doc->osHeader() <<
"/bop\n";
375 doc->osHeader() <<
" {\n";
376 doc->osHeader() <<
" /SaveImage save def\n";
377 doc->osHeader() <<
" } def\n";
381 doc->osHeader() <<
"/eop\n";
382 doc->osHeader() <<
" {\n";
383 doc->osHeader() <<
" showpage\n";
384 doc->osHeader() <<
" SaveImage restore\n";
385 doc->osHeader() <<
" } def\n";
389 doc->osHeader() <<
"/@line\n";
390 doc->osHeader() <<
" {0 setlinecap\n";
391 doc->osHeader() <<
" 0 setlinejoin\n";
392 doc->osHeader() <<
" 1 setmiterlimit\n";
393 doc->osHeader() <<
" } def\n";
397 doc->osHeader() <<
"/@hsize {/hs exch def} def\n";
398 doc->osHeader() <<
"/@vsize {/vs exch def} def\n";
402 doc->osHeader() <<
"/@hoffset {/ho exch def} def\n";
403 doc->osHeader() <<
"/@voffset {/vo exch def} def\n";
407 doc->osHeader() <<
"/lw " << (int) (
413 doc->osHeader() <<
"/@SetPlot\n";
414 doc->osHeader() <<
" {\n";
415 doc->osHeader() <<
" ho vo translate\n";
416 doc->osHeader() <<
" XScale YScale scale\n";
417 doc->osHeader() <<
" lw setlinewidth\n";
418 doc->osHeader() <<
" } def\n";
422 doc->osHeader() <<
"/XScale\n";
423 doc->osHeader() <<
" {hs " <<
YPSSIZE <<
" div} def\n";
424 doc->osHeader() <<
"/YScale\n";
425 doc->osHeader() <<
" {vs " <<
XPSSIZE <<
" div} def\n";
429 doc->osHeader() <<
"/M {moveto} def\n";
430 doc->osHeader() <<
"/D {lineto} def\n";
431 doc->osHeader() <<
"/A {0.5 0 360 arc} def\n";
432 doc->osHeader() <<
"/S {stroke} def\n";
433 doc->osHeader() <<
"/Z {stroke newpath} def\n";
435 doc->osHeader() <<
"/F {closepath gsave eofill grestore stroke} def\n";
437 doc->osHeader() <<
"/F {closepath gsave fill grestore stroke} def\n";
438 doc->osHeader() <<
"/N {newpath} def\n";
439 doc->osHeader() <<
"/C {setrgbcolor} def\n";
440 doc->osHeader() <<
"/G {setgray} def\n";
441 doc->osHeader() <<
"/W {setlinewidth} def\n";
442 doc->osHeader() <<
"/R {rotate} def\n";
443 doc->osHeader() <<
"/B {Z " <<
XMIN <<
" " <<
YMIN <<
" M " <<
XMIN <<
" " <<
YMAX <<
" D " <<
XMAX <<
" " <<
YMAX <<
" D " <<
XMAX <<
" " <<
YMIN <<
" D " <<
XMIN <<
" " <<
YMIN <<
" closepath} def\n";
444 doc->osHeader() <<
"/CL {newpath M D D D closepath clip} def\n";
448 doc->osHeader() <<
"end\n\n";
452 doc->osHeader() <<
"PSDict begin\n";
453 doc->osHeader() <<
"@start\n";
454 doc->osHeader() <<
COPIES <<
" @copies\n";
455 doc->osHeader() <<
"@line\n";
456 doc->osHeader() <<
YSIZE <<
" @hsize\n";
457 doc->osHeader() <<
XSIZE <<
" @vsize\n";
458 doc->osHeader() <<
YOFFSET <<
" @hoffset\n";
459 doc->osHeader() <<
XOFFSET <<
" @voffset\n";
461 doc->osHeader() <<
"@SetPlot\n" << endl;
474 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
475 PLINT x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
486 doc->osBody() <<
'\n';
490 doc->osBody() <<
' ';
492 snprintf( outbuf, OUTBUF_LEN,
"%d %d D", x2, y2 );
498 doc->osBody() <<
" Z\n";
501 if ( x1 == x2 && y1 == y2 )
502 snprintf( outbuf, OUTBUF_LEN,
"%d %d A", x1, y1 );
504 snprintf( outbuf, OUTBUF_LEN,
"%d %d M %d %d D", x1, y1, x2, y2 );
517 doc->osBody() << outbuf;
518 pls->
bytecnt += 1 + strlen( outbuf );
534 for ( i = 0; i < npts - 1; i++ )
547 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
548 doc->osBody() <<
" S\neop\n";
562 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
573 doc->osBody() <<
"%%Page: " << (int) pls->
page <<
" 1\n";
575 doc->osBody() <<
"%%Page: " << (int) pls->
page <<
" " << (
int) pls->
page <<
"\n";
577 doc->osBody() <<
"bop\n";
581 if ( pls->
cmap0[0].
r != 0xFF ||
582 pls->
cmap0[0].
g != 0xFF ||
589 doc->osBody() <<
"B " << r <<
" " << g <<
" " << b <<
" C F\n";
611 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
629 doc->osFooter() <<
"%%Pages: 1\n";
631 doc->osFooter() <<
"%%Pages: " << (int) pls->
page <<
"\n";
633 doc->osFooter() <<
"@end" << endl;
641 if ( !strcmp( pls->
FileName,
"-" ) )
643 doc->write( cout, dev->
llx, dev->
lly, dev->
urx, dev->
ury );
650 doc->write( out, dev->
llx, dev->
lly, dev->
urx, dev->
ury );
668 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
675 ( pls->
width > MAX_WIDTH ) ? MAX_WIDTH : pls->
width;
677 doc->osBody() <<
" S\n" << width <<
" W";
686 doc->osBody() <<
" S\n" << ( pls->
icol0 ? 0.0 : 1.0 ) <<
" G";
697 doc->osBody() <<
" S\n" << r <<
" " << g <<
" " << b <<
" C";
702 doc->osBody() <<
" S\n" << 1.0 - r <<
" G";
711 doc->osBody() <<
" " << (int) dev->
xold <<
" " << (
int) dev->
yold <<
" M \n";
746 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
747 PLINT n, ix = 0, iy = 0;
750 doc->osBody() <<
" Z\n";
752 for ( n = 0; n < pls->
dev_npts; n++ )
754 x = pls->
dev_x[ix++];
755 y = pls->
dev_y[iy++];
765 snprintf( outbuf, OUTBUF_LEN,
"N %d %d M", x, y );
770 doc->osBody() << outbuf;
771 pls->
bytecnt += strlen( outbuf );
777 doc->osBody() <<
'\n';
781 doc->osBody() <<
' ';
785 snprintf( outbuf, OUTBUF_LEN,
"%d %d D", x, y );
791 doc->osBody() << outbuf;
792 pls->
bytecnt += strlen( outbuf );
797 doc->osBody() <<
" F ";
813 t = time( (time_t *) 0 );
816 *( p + len - 1 ) =
'\0';
826 # define RISE_FACTOR 0.6
840 PLFLT theta, shear, stride;
844 PostscriptDocument *doc = (PostscriptDocument *) pls->
psdoc;
850 #define PROC_STR_STRING_LENGTH 1000
851 char *strp, str[PROC_STR_STRING_LENGTH], *cur_strp,
852 cur_str[PROC_STR_STRING_LENGTH];
853 float font_factor = 1.4;
854 PLINT clxmin, clxmax, clymin, clymax;
855 PLINT clipx[4], clipy[4];
857 PLFLT scale = 1., up = 0.;
866 char *fonts[PROC_STR_STRING_LENGTH];
867 FontStyle styles[PROC_STR_STRING_LENGTH];
868 FontWeight weights[PROC_STR_STRING_LENGTH];
871 unsigned char fontfamily, fontstyle, fontweight;
872 PLFLT old_sscale, sscale, old_soffset, soffset, dup;
886 font = (
char *) FamilyLookup[fontfamily];
887 weight = WeightLookup[fontweight];
888 style = StyleLookup[fontstyle];
892 fprintf( stderr,
"fci = 0x%x, font name pointer = NULL \n", fci );
893 plabort(
"proc_str: FCI inconsistent with TrueTypeLookup; "
894 "internal PLplot error" );
907 if ( ( f < PROC_STR_STRING_LENGTH ) && ( s + 3 < PROC_STR_STRING_LENGTH ) )
912 fonts[f] = (
char *) FamilyLookup[fontfamily];
913 weights[f] = WeightLookup[fontweight];
914 styles[f] = StyleLookup[fontstyle];
915 if ( fonts[f] == NULL )
917 fprintf( stderr,
"string-supplied FCI = 0x%x, font name pointer = NULL \n", cur_text[j] );
918 plabort(
"proc_str: string-supplied FCI inconsistent with font lookup;" );
928 else if ( s + 1 < PROC_STR_STRING_LENGTH )
943 ft_ht = pls->
chrht * 72.0 / 25.4;
950 tt[0] = t[0] * cs + t[2] * sn;
951 tt[1] = t[1] * cs + t[3] * sn;
952 tt[2] = -t[0] * sn + t[2] * cs;
953 tt[3] = -t[1] * sn + t[3] * cs;
967 if ( args->
base == 2 )
969 else if ( args->
base == 1 )
972 offset = -
ENLARGE * ft_ht / 2.;
976 args->
y += (int) ( offset * cos( theta ) );
977 args->
x -= (int) ( offset * sin( theta ) );
981 &( args->
x ), &( args->
y ) );
996 difilt( clipx, clipy, 4, &clxmin, &clxmax, &clymin, &clymax );
998 &clipx[0], &clipy[0] );
1000 &clipx[1], &clipy[1] );
1002 &clipx[2], &clipy[2] );
1004 &clipx[3], &clipy[3] );
1005 doc->osBody() <<
" gsave " << clipx[0] <<
" " << clipy[0] <<
" " <<
1006 clipx[1] <<
" " << clipy[1] <<
" " << clipx[2] <<
" " <<
1007 clipy[2] <<
" " << clipx[3] <<
" " << clipy[3] <<
" CL\n";
1010 doc->osBody() <<
" " << args->
x <<
" " << args->
y <<
" M\n";
1013 doc->osBody() <<
"gsave " << TRMFLT( theta * 180. /
PI ) <<
" R\n";
1015 doc->osBody() <<
"[" << TRMFLT( tt[0] ) <<
" " << TRMFLT( tt[2] ) <<
" " << TRMFLT( tt[1] )
1016 <<
" " << TRMFLT( tt[3] ) <<
" 0 0] concat\n";
1027 if ( *cur_strp == esc )
1031 if ( *cur_strp == esc )
1033 *strp++ = *cur_strp++;
1035 else if ( *cur_strp ==
'f' )
1038 if ( *cur_strp++ !=
'f' )
1042 plabort(
"proc_str, internal PLplot logic error;"
1043 "wrong escf escape sequence" );
1048 weight = weights[f];
1053 switch ( *cur_strp++ )
1058 &old_sscale, &sscale, &old_soffset, &soffset );
1064 dup = -0.5 * ( 1.0 - sscale );
1071 &old_sscale, &sscale, &old_soffset, &soffset );
1077 dup = 0.5 * ( 1.0 - sscale );
1087 plwarn(
"'+', '-', and 'b/B' text escape sequences not processed." );
1095 while ( *cur_strp && *cur_strp != esc )
1097 *strp++ = *cur_strp++;
1104 doc->setFont( font, style, weight );
1105 doc->setFontSize( font_factor *
ENLARGE * ft_ht * scale );
1106 doc->get_dimensions( (
const char *) str, &lineSpacing, &xAdvance, &ymintmp, &ymaxtmp );
1108 }
while ( *cur_strp );
1112 xmin = -xmax * args->
just;
1123 doc->osBody() <<
" gsave " << TRMFLT( xmin * tt[0] ) <<
" " <<
1124 TRMFLT( xmin * tt[2] ) <<
" rmoveto\n";
1134 if ( *cur_strp == esc )
1138 if ( *cur_strp == esc )
1140 *strp++ = *cur_strp++;
1142 else if ( *cur_strp ==
'f' )
1145 if ( *cur_strp++ !=
'f' )
1149 plabort(
"proc_str, internal PLplot logic error;"
1150 "wrong escf escape sequence" );
1155 weight = weights[f];
1161 switch ( *cur_strp++ )
1166 &old_sscale, &sscale, &old_soffset, &soffset );
1172 dup = -0.5 * ( 1.0 - sscale );
1179 &old_sscale, &sscale, &old_soffset, &soffset );
1185 dup = 0.5 * ( 1.0 - sscale );
1195 plwarn(
"'+', '-', and 'b/B' text escape sequences not processed." );
1203 while ( *cur_strp && *cur_strp != esc )
1205 *strp++ = *cur_strp++;
1212 doc->setFont( font, style, weight );
1213 doc->setFontSize( font_factor *
ENLARGE * ft_ht * scale );
1214 doc->get_dimensions( (
const char *) str, &lineSpacing, &xAdvance, &ymintmp, &ymaxtmp );
1215 ymin =
MIN( ymintmp + up, ymin );
1216 ymax =
MAX( ymaxtmp + up, ymax );
1222 doc->osBody() <<
"gsave " << TRMFLT( up * tt[1] ) <<
" " << TRMFLT( up * tt[3] ) <<
" rmoveto\n";
1225 doc->osBody() << show( (
const char *) str );
1229 doc->osBody() <<
"grestore " << TRMFLT( xAdvance * tt[0] ) <<
" " << TRMFLT( xAdvance * tt[2] ) <<
" rmoveto\n";
1230 }
while ( *cur_strp );
1232 doc->osBody() <<
"grestore\n";
1233 doc->osBody() <<
"grestore\n";
1234 doc->osBody() <<
"grestore\n";
1242 xx[0] = (
PLINT) ( t[0] * xmin + t[1] * ymin );
1243 yy[0] = (
PLINT) ( t[2] * xmin + t[3] * ymin );
1244 xx[1] = (
PLINT) ( t[0] * xmin + t[1] * ymax );
1245 yy[1] = (
PLINT) ( t[2] * xmin + t[3] * ymax );
1246 xx[2] = (
PLINT) ( t[0] * xmax + t[1] * ymin );
1247 yy[2] = (
PLINT) ( t[2] * xmax + t[3] * ymin );
1248 xx[3] = (
PLINT) ( t[0] * xmax + t[1] * ymax );
1249 yy[3] = (
PLINT) ( t[2] * xmax + t[3] * ymax );
1257 xmin =
MIN(
MIN(
MIN( xx[0], xx[1] ), xx[2] ), xx[3] ) + args->
x;
1258 xmax =
MAX(
MAX(
MAX( xx[0], xx[1] ), xx[2] ), xx[3] ) + args->
x;
1259 ymin =
MIN(
MIN(
MIN( yy[0], yy[1] ), yy[2] ), yy[3] ) + args->
y;
1260 ymax =
MAX(
MAX(
MAX( yy[0], yy[1] ), yy[2] ), yy[3] ) + args->
y;
1262 dev->
llx = (int) (
MIN( dev->
llx, xmin ) );
1263 dev->
lly = (int) (
MIN( dev->
lly, ymin ) );
1264 dev->
urx = (int) (
MAX( dev->
urx, xmax ) );
1265 dev->
ury = (int) (
MAX( dev->
ury, ymax ) );
1320 #endif // defined(PLD_psttf) || ....