extern "C" { #include } #include "graph.h" #include "graph_ps.h" extern "C" { #include } void checkfree (void *ptr); char *checkstrdup (char *ptr); char *checkmalloc (unsigned int len); void *checkrealloc (void *ptr_in, int size); #define MMTOPOINTS(v) ((int) ((double) (v)/25.4*72.0)) static char *ps_procs= "%% New path\n" "/NP {\n" " newpath\n" " moveto\n" "} def\n\n" "%% Append path\n" "/AP {\n" " /ary exch def\n" " 0 2 ary length 1 sub\n" " {\n" " /x exch def ary x get ary x 1 add get lineto\n" " } for\n" "} def\n\n" "%% Draw Lines\n" "/DL {\n" " AP stroke\n" "} def\n\n" "%% Fill polygon\n" "/FP {\n" " AP closepath eofill\n" "} def\n\n" "%% Draw string\n" "/DS {\n" " 3 1 roll moveto show\n" "} def\n\n" "%% Fill arc (close)\n" "/FAC {\n" " /s save def\n" " 6 -2 roll scale\n" " newpath\n" " 4 -2 roll 0.5 5 -2 roll arc\n" " closepath fill s restore\n" "} def\n\n" "%% Fill arc (not close)\n" "/FAN {\n" " /s save def\n" " 6 -2 roll scale\n" " newpath\n" " 3 index 3 index moveto\n" " 4 -2 roll 0.5 5 -2 roll arc\n" " closepath fill s restore\n" "} def\n\n" "%% Draw arc\n" "/DA {\n" " /s save def\n" " 6 -2 roll scale\n" " newpath\n" " 4 -2 roll 0.5 5 -2 roll arc\n" " scale stroke s restore\n" "} def\n\n" "%% Set color\n" "/SC {\n" " setrgbcolor\n" "} def\n\n" "%% set font\n" "/Helvetica findfont\n" " dup length dict begin\n" " {1 index /FID ne {def} {pop pop} ifelse} forall\n" " /Encoding ISOLatin1Encoding def\n" " currentdict\n" "end\n" "%% Set linewidth\n" "/LW {\n" " setlinewidth\n" "} def\n\n" "/LT1 {\n" " [] 0 setdash\n" "} def\n\n" "/LT2 {\n" " [5 3] 0 setdash\n" "} def\n\n" "/LT3 {\n" " [1 3] 0 setdash\n" "} def\n\n" "/LT4 {\n" " [5 3 1 3] 0 setdash\n" "} def\n\n" "/LT5 {\n" " [5 3 1 3 1 3] 0 setdash\n" "} def\n\n" "/F1 exch definefont pop\n\n" "/SF {/F1 findfont 9 scalefont setfont} def\n\n"; char *ISO2PS (char *string) { unsigned char *in= (unsigned char *) string; int i, inlen= strlen ((const char *) in); char *ptr; static char table [256][5], len [256], undef=1; static char out [3000]; if (undef) { undef= 0; for (i= 0; i< 256; ++i) { table [i][0]= '?'; table [i][1]= '\0'; len [i]= 1; } /* ASCII */ for (i= 32; i<= 126; i++) { table [i][0]= i; table [i][1]= '\0'; len [i]= 1; } /* ISO latin 1 */ for (i= 160; i<= 255; i++) { sprintf (table[i], "\\%o", i); len [i]= 4; } /* Special characters */ strcpy (table ['('], "\\("); len ['(']= 2; strcpy (table [')'], "\\)"); len [')']= 2; strcpy (table ['\\'], "\\\\"); len ['\\']= 2; } out[0]='\0'; ptr= out; for (i= 0; i< inlen; ++i) { strcpy (ptr, table [in[i]]); ptr+= len [in[i]]; } return (out); } void PSWindow::PSLineContext (GWindow::GGC gc) { int aux; if (context [gc].colorindex!= current_context.colorindex) { aux= context [gc].colorindex; fprintf (fout, "%g %g %g SC\n", color [aux].red, color [aux].green, color [aux].blue); current_context.colorindex= aux; } if (context [gc].linewidth!= current_context.linewidth) { fprintf (fout, "%d LW\n", context [gc].linewidth); current_context.linewidth= context [gc].linewidth; } if (context [gc].linetype!= current_context.linetype) { aux= context [gc].linetype; if (aux>= 1 && aux <= 5) fprintf (fout, "LT%d\n", aux); else fprintf (fout, "LT1\n"); current_context.linetype= context [gc].linetype; } } void PSWindow::PSFillContext (GWindow::GGC gc) { int aux; if (context [gc].colorindex!= current_context.colorindex) { aux= context [gc].colorindex; fprintf (fout, "%g %g %g SC\n", color [aux].red, color [aux].green, color [aux].blue); current_context.colorindex= aux; } } PSWindow::PSWindow (FILE *fout) { this->fout= fout; default_context.colorindex= -1; /* -1: Foreground, -2: Background */ default_context.linewidth= 1; default_context.linetype= 1; /* solid line */ context= NULL; ncontexts= 0; current_context.colorindex= -9; /* invalid */ current_context.linewidth= -1; /* invalid */ current_context.linetype= -1; /* invalid */ color= (PSColor *) checkmalloc (2* sizeof (PSColor)); ncolors= 0; /* first color is black (foreground) */ color [0].red= 0.0; color [0].green= 0.0; color [0].blue= 0.0; /* second color is white (background) */ color [1].red= 1.0; color [1].green= 1.0; color [1].blue= 1.0; /* force reset of current graphics-state */ current_context.colorindex= -1; } PSWindow::~PSWindow (void) { checkfree (color); checkfree (context); } GWindow::GGC PSWindow::GCreateGC (void) { context= (ggc *) checkrealloc (context, (ncontexts+ 1)* sizeof (ggc)); context [ncontexts]= default_context; return (ncontexts++); } void PSWindow::PSWriteFunctions (void) { fprintf (fout, ps_procs); } void PSWindow::GClearWindow (void) { current_context.colorindex= -9; /* invalid */ current_context.linewidth= -1; /* invalid */ current_context.linetype= -1; /* invalid */ /* Set defaultfont */ fprintf (fout, "SF\n"); } void PSWindow::GDrawImageString (GWindow::GGC gc, int x, int y, char *string) { PSLineContext (gc); fprintf (fout, "%d %d (%s) DS\n", x, height- y, ISO2PS (string)); } void PSWindow::GDrawString (GWindow::GGC gc, int x, int y, char *string) { PSLineContext (gc); fprintf (fout, "%d %d (%s) DS\n", x, height- y, ISO2PS (string)); } void PSWindow::GDrawLines (GWindow::GGC gc, GPoint *vect, int len) { int blocksize= 16; if (len== 0) return; PSLineContext (gc); for (int i= 0; i< len; ++i) { if (i % blocksize== 0) if (i== 0) { fprintf (fout, "%d %d NP [", vect[i].x, height- vect[i].y); continue; } else fprintf (fout, "] AP\n["); fprintf (fout, "%d %d ", vect[i].x, height- vect[i].y); } fprintf (fout, "] DL\n"); } void PSWindow::GFillPolygon (GWindow::GGC gc, GPoint *vect, int len) { int i, blocksize= 16; if (len< 2) return; PSFillContext (gc); for (i= 0; i< len; ++i) { if (i % blocksize== 0) if (i== 0) { fprintf (fout, "%d %d NP [", vect[i].x, height- vect[i].y); continue; } else fprintf (fout, "] AP\n["); fprintf (fout, "%d %d ", vect[i].x, height- vect[i].y); } fprintf (fout, "] FP\n"); } void PSWindow::GFillArc (GWindow::GGC gc, int x, int y, int w, int h, int start, int end, int close) { PSFillContext (gc); if (close) fprintf (fout, "%g %g %g %g %g %g FAC\n", (float) w, (float) h, (float) (x+w/2)/w, (float) (height- (y+h/2))/h, start/ 64.0, (end+start)/ 64.0); else fprintf (fout, "%g %g %g %g %g %g FAN\n", (float) w, (float) h, (float) (x+w/2)/w, (float) (height- (y+h/2))/h, start/ 64.0, (end+start)/ 64.0); } void PSWindow::GDrawArc (GWindow::GGC gc, int x, int y, int w, int h, int start, int end) { PSLineContext (gc); fprintf (fout, "%g %g %g %g %g %g %g %g DA\n", (float) 1.0/w, (float) 1.0/h, (float) w, (float) h, (float) (x+w/2)/w, (float) (height- (y+h/2))/h, start/ 64.0, (end+start)/ 64.0); /* , current_context.linewidth); */ } /* -1: Foreground, -2: Background */ void PSWindow::GSetForeground (GWindow::GGC gc, int color) { if (color< -2 || color>= ncolors) { fprintf (stderr, "color %d outside range %d\n", color, (int) gc); abort (); } context [gc].colorindex= color+ 2; } void PSWindow::GSetColorTable (GColor *colors_in, int ncolors, int) { int i; /* copy rgb color-values */ checkfree (color); color= (PSColor *) checkmalloc ((ncolors+2)* sizeof (PSColor)); this->ncolors= ncolors; for (i= 0; i< ncolors; i++) { color [i+2].red= colors_in [i].red/ 256.0; color [i+2].green= colors_in [i].green/ 256.0; color [i+2].blue= colors_in [i].blue/ 256.0; } /* first color is white (background) */ color [0].red= 1.0; color [0].green= 1.0; color [0].blue= 1.0; /* second color is black (foreground) */ color [1].red= 0.0; color [1].green= 0.0; color [1].blue= 0.0; /* force reset of current graphics-state */ current_context.colorindex= -1; } void PSWindow::GSetLineWidth (PSWindow::GGC gc, int width) { context [gc].linewidth= width; } void PSWindow::GSetLineType (PSWindow::GGC gc, int type) { context [gc].linetype= type; }