00001
00002
00003
00004
00005
00006 #include "plDevs.h"
00007
00008 #ifdef PLD_pstex
00009
00010 #include "plplotP.h"
00011 #include "drivers.h"
00012 #include "ps.h"
00013
00014
00015 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_pstex =
00016 "pstex:Combined Postscript/LaTeX files:0:pstex:41:pstex\n";
00017
00018
00019
00020
00021
00022
00023
00024
00025 static void parse_str( const char *str, char *dest );
00026 static void proc_str( PLStream *pls, EscText *args );
00027 static int color = 1;
00028
00029 static DrvOpt pstex_options[] = { { "color", DRV_INT, &color,
00030 "Color Postscript/LaTeX (color=1|0)" },
00031 { NULL, DRV_INT, NULL, NULL} };
00032
00033 void plD_dispatch_init_pstex( PLDispatchTable *pdt )
00034 {
00035 #ifndef ENABLE_DYNDRIVERS
00036 pdt->pl_MenuStr = "Combined Postscript/LaTeX files";
00037 pdt->pl_DevName = "pstex";
00038 #endif
00039 pdt->pl_type = plDevType_FileOriented;
00040 pdt->pl_seq = 41;
00041 pdt->pl_init = (plD_init_fp) plD_init_pstex;
00042 pdt->pl_line = (plD_line_fp) plD_line_ps;
00043 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_ps;
00044 pdt->pl_eop = (plD_eop_fp) plD_eop_ps;
00045 pdt->pl_bop = (plD_bop_fp) plD_bop_pstex;
00046 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_pstex;
00047 pdt->pl_state = (plD_state_fp) plD_state_ps;
00048 pdt->pl_esc = (plD_esc_fp) plD_esc_pstex;
00049 }
00050
00051 void
00052 plD_init_pstex( PLStream *pls )
00053 {
00054 char *ofile;
00055 size_t len;
00056 PSDev *dev;
00057 FILE *fp;
00058
00059 plParseDrvOpts( pstex_options );
00060 if ( color )
00061 plD_init_psc( pls );
00062 else
00063 plD_init_psm( pls );
00064
00065 dev = (PSDev *) pls->dev;
00066
00067 pls->dev_text = 1;
00068 pls->dev_unicode = 0;
00069
00070
00071 len = strlen( pls->FileName ) + 3;
00072 ofile = (char *) malloc( sizeof ( char ) * len );
00073 snprintf( ofile, len, "%s_t", pls->FileName );
00074 fp = fopen( ofile, "w" );
00075 free( ofile );
00076 dev->fp = fp;
00077
00078 fprintf( fp, "\\begin{picture}(0,0)(0,0)%%\n" );
00079 fprintf( fp, "\\includegraphics[scale=1.,clip]{%s}%%\n", pls->FileName );
00080 fprintf( fp, "\\end{picture}%%\n" );
00081
00082 fprintf( fp, "\\setlength{\\unitlength}{%fbp}%%\n", 1.0 / ENLARGE );
00083 fprintf( fp, "\\begingroup\\makeatletter\\ifx\\SetFigFont\\undefined%%\n" );
00084 fprintf( fp, "\\gdef\\SetFigFont#1#2#3#4#5{%%\n" );
00085 fprintf( fp, "\\reset@font\\fontsize{#1}{#2pt}%%\n" );
00086 fprintf( fp, "\\fontfamily{#3}\\fontseries{#4}\\fontshape{#5}%%\n" );
00087 fprintf( fp, "\\selectfont}%%\n" );
00088 fprintf( fp, "\\fi\\endgroup%%\n" );
00089
00090 dev->cur_pos = ftell( fp );
00091 fprintf( fp, "\\begin{picture}(xxxxxx,xxxxxx)(xxxxxx,xxxxxx)%%\n" );
00092 }
00093
00094 void
00095 plD_esc_pstex( PLStream *pls, PLINT op, void *ptr )
00096 {
00097 switch ( op )
00098 {
00099 case PLESC_HAS_TEXT:
00100 proc_str( pls, ptr );
00101 break;
00102 default:
00103 plD_esc_ps( pls, op, ptr );
00104 }
00105 }
00106
00107 void
00108 plD_bop_pstex( PLStream *pls )
00109 {
00110 plD_bop_ps( pls );
00111 plGetFam( pls );
00112 }
00113
00114 void
00115 plD_tidy_pstex( PLStream *pls )
00116 {
00117 PSDev *dev = (PSDev *) pls->dev;
00118 PLFLT scale;
00119 FILE *fp;
00120
00121 plD_tidy_ps( pls );
00122
00123 scale = pls->xpmm * 25.4 / 72.;
00124
00125 fp = dev->fp;
00126 fprintf( fp, "\\end{picture}\n" );
00127
00128 fseek( fp, dev->cur_pos, SEEK_SET );
00129 fprintf( fp, "\\begin{picture}(%d,%d)(%d,%d)%%\n%%",
00130 ROUND( ( dev->urx - dev->llx ) * scale ),
00131 ROUND( ( dev->ury - dev->lly ) * scale ),
00132 ROUND( ( dev->llx - XOFFSET ) * scale ),
00133 ROUND( ( dev->lly - YOFFSET ) * scale ) );
00134
00135 plCloseFile( pls );
00136 }
00137
00138 void
00139 proc_str( PLStream *pls, EscText *args )
00140 {
00141 PLFLT *t = args->xform;
00142 PLFLT a1, alpha, ft_ht, angle;
00143 char cptr[256], jst, ref;
00144 PSDev *dev = (PSDev *) pls->dev;
00145 PLINT clxmin, clxmax, clymin, clymax;
00146 FILE *fp;
00147
00148 fp = dev->fp;
00149
00150
00151 ft_ht = 1.6 * pls->chrht * 72.0 / 25.4;
00152
00153
00154 angle = ( (PLFLT) ( ORIENTATION - 1 ) + pls->diorot ) * 90.;
00155 a1 = acos( t[0] ) * 180. / PI;
00156 if ( t[2] > 0. )
00157 alpha = a1 - angle - 90.;
00158 else
00159 alpha = 360. - a1 - angle - 90.;
00160
00161
00162 parse_str( args->string, cptr );
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 if ( args->base == 2 )
00173 ref = 't';
00174 else if ( args->base == 1 )
00175 ref = 'b';
00176 else
00177 ref = 'c';
00178
00179
00180
00181
00182
00183
00184
00185 if ( args->just == 0.5 )
00186 jst = 'c';
00187 else if ( args->just == 1. )
00188 jst = 'r';
00189 else
00190 {
00191 jst = 'l';
00192 args->x = args->refx;
00193 args->y = args->refy;
00194 }
00195
00196
00197 difilt( &args->x, &args->y, 1, &clxmin, &clxmax, &clymin, &clymax );
00198
00199
00200
00201
00202
00203
00204 if ( args->x < clxmin || args->x > clxmax || args->y < clymin || args->y > clymax )
00205 return;
00206
00207 plRotPhy( ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
00208 &( args->x ), &( args->y ) );
00209
00210 #ifdef DEBUG
00211 fprintf( fp, "\\put(%d,%d){\\circle{10}}\n",
00212 args->x, args->y );
00213 #endif
00214
00215 fprintf( fp, "\\put(%d,%d){\\rotatebox{%.1f}{\\makebox(0,0)[%c%c]{\\SetFigFont{%.1f}{12}",
00216 args->x, args->y, alpha, jst, ref, ft_ht );
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 switch ( pls->cfont )
00229 {
00230 case ( 1 ): fprintf( fp, "{\\familydefault}" ); break;
00231 case ( 2 ): fprintf( fp, "{\\rmdefault}" ); break;
00232 case ( 3 ): fprintf( fp, "{\\itdefault}" ); break;
00233 case ( 4 ): fprintf( fp, "{\\sfdefault}" ); break;
00234 default: fprintf( fp, "{\\familydefault}" );
00235 }
00236
00237 fprintf( fp, "{\\mddefault}{\\updefault}\n" );
00238
00239
00240
00241 if ( color )
00242 fprintf( fp, "\\special{ps: %.3f %.3f %.3f setrgbcolor}{",
00243 pls->curcolor.r / 255., pls->curcolor.g / 255., pls->curcolor.b / 255. );
00244 else
00245 fprintf( fp, "\\special{ps: 0 0 0 setrgbcolor}{" );
00246
00247 fprintf( fp, "%% Your text follows:\n" );
00248 fprintf( fp, "%s\n", cptr );
00249 fprintf( fp, "}}}}" );
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 dev->llx = MIN( dev->llx, args->x - ft_ht * 25.4 / 72. * pls->xpmm );
00260 dev->lly = MIN( dev->lly, args->y - ft_ht * 25.4 / 72. * pls->ypmm );
00261 dev->urx = MAX( dev->urx, args->x + ft_ht * 25.4 / 72. * pls->xpmm );
00262 dev->ury = MAX( dev->ury, args->y + ft_ht * 25.4 / 72. * pls->ypmm );
00263 }
00264
00265 void
00266 parse_str( const char *str, char *dest )
00267 {
00268 int n, opened = 0, raised = 0, overline = 0, underline = 0, fontset = 0, math = 0;
00269 char *tp = dest, c, esc;
00270 char greek[] = "abgGdDezyhHiklLmncCopPrsStuUfFxqQwW";
00271 char *mathgreek[] = { "alpha", "beta", "gamma", "Gamma", "delta", "Delta",
00272 "epsilon", "zeta", "eta", "theta", "Theta", "iota",
00273 "kappa", "lambda", "Lambda", "mu", "nu", "xi", "Xi",
00274 "o", "pi", "Pi", "rho", "sigma", "Sigma","tau",
00275 "upsilon", "Upsilon", "phi", "Phi", "chi",
00276 "psi", "Psi", "omega", "Omega" };
00277
00278 plgesc( &esc );
00279
00280 while ( *str )
00281 {
00282 if ( *str != esc )
00283 {
00284 *tp++ = *str++;
00285 continue;
00286 }
00287 str++;
00288
00289 switch ( *str++ )
00290 {
00291 case 'u':
00292 if ( raised < 0 )
00293 {
00294 *tp++ = '}';
00295 opened--;
00296 }
00297 else
00298 {
00299 n = sprintf( tp, "\\raisebox{%.2fex}{", 0.6 );
00300 tp += n; opened++;
00301 }
00302 raised++;
00303 break;
00304
00305 case 'd':
00306 if ( raised > 0 )
00307 {
00308 *tp++ = '}';
00309 opened--;
00310 }
00311 else
00312 {
00313 n = sprintf( tp, "\\raisebox{%.2fex}{", -0.6 );
00314 tp += n; opened++;
00315 }
00316 raised--;
00317 break;
00318
00319 case 'b':
00320 n = sprintf( tp, "\\hspace{-1em}" );
00321 tp += n;
00322 break;
00323
00324 case '+':
00325 if ( overline )
00326 {
00327 if ( --math )
00328 *tp++ = '}';
00329 else
00330 {
00331 n = sprintf( tp, "}$" );
00332 tp += n;
00333 }
00334 overline--; opened--;
00335 }
00336 else
00337 {
00338 if ( !math )
00339 *tp++ = '$';
00340
00341 n = sprintf( tp, "\\overline{" );
00342 tp += n; overline++; opened++; math++;
00343 }
00344 break;
00345
00346 case '-':
00347 if ( underline )
00348 {
00349 if ( --math )
00350 *tp++ = '}';
00351 else
00352 {
00353 n = sprintf( tp, "}$" );
00354 tp += n;
00355 }
00356 underline--; opened--;
00357 }
00358 else
00359 {
00360 if ( !math )
00361 *tp++ = '$';
00362
00363 n = sprintf( tp, "\\underline{" );
00364 tp += n; underline++; opened++; math++;
00365 }
00366 break;
00367
00368 case 'g':
00369 c = *str++;
00370 n = plP_strpos( greek, c );
00371 if ( n != -1 )
00372 {
00373 if ( !math )
00374 *tp++ = '$';
00375
00376 *tp++ = '\\';
00377 strcpy( tp, mathgreek[n] );
00378 if ( isupper( c ) )
00379 *tp = toupper( *tp );
00380 tp += strlen( mathgreek[n] );
00381 if ( !math )
00382 *tp++ = '$';
00383 }
00384 else
00385 *tp++ = c;
00386
00387 break;
00388
00389 case '(':
00390 plwarn( "'g(...)' text escape sequence not processed." );
00391 while ( *str++ != ')' )
00392 ;
00393 break;
00394
00395 case 'f':
00396
00397 switch ( *str++ )
00398 {
00399 case 'n':
00400 while ( fontset-- )
00401 {
00402 *tp++ = '}';
00403 opened--;
00404 }
00405
00406 if ( math )
00407 {
00408 *tp++ = '$';
00409 math = 0;
00410 }
00411
00412 n = sprintf( tp, "\\normalfont " );
00413 tp += n;
00414 break;
00415
00416 case 'r':
00417 if ( math )
00418 n = sprintf( tp, "\\mathrm{" );
00419 else
00420 n = sprintf( tp, "\\textrm{" );
00421
00422 tp += n; opened++; fontset++;
00423 break;
00424
00425 case 'i':
00426 if ( math )
00427 n = sprintf( tp, "\\mathit{" );
00428 else
00429 n = sprintf( tp, "\\textit{" );
00430
00431 tp += n; opened++; fontset++;
00432 break;
00433
00434 case 's':
00435 if ( math )
00436 n = sprintf( tp, "\\mathsf{" );
00437 else
00438 n = sprintf( tp, "\\textsf{" );
00439
00440 tp += n; opened++; fontset++;
00441 break;
00442 }
00443
00444 default:
00445 if ( *str == esc )
00446 *tp++ = esc;
00447 }
00448 }
00449
00450 while ( opened-- )
00451 *tp++ = '}';
00452 *tp = '\0';
00453 }
00454
00455 #else
00456 int
00457 pldummy_pstex()
00458 {
00459 return 0;
00460 }
00461
00462 #endif // PLD_pstexdev