/* $Id: psdriv.cc,v 1.3 1996/10/11 11:30:10 roitzsch Exp $ (C)opyright 1996 by Konrad-Zuse-Center, Berlin All rights reserved. Part of the Kaskade distribution */ #include #include #include #include #include "drivers.h" #include "driversimp.h" //#include // extern "C" system(char*); #define K180PI 57.29578 #define PTTOINCH 0.0139 #define INCHTOPT 72.0 #define PTTOCM 0.035277778 #define CMTOPT 28.346457 #define COLORS 64 #define GRAYS 24 #define TRANSX(X) (xreal)((X)*(graph->xScal)+(graph->xTrans)+(graph->wdOrgX)) #define TRANSY(Y) (xreal)((Y)*(graph->yScal)+(graph->yTrans)+(graph->wdOrgY)) #define Q_TRANSX(X) (xreal)((X)*(graph->xScal)+(graph->xTrans)+(graph->wdOrgY)) #define Q_TRANSY(Y) (xreal)((graph->wdOrgX)-((Y)*(graph->yScal)+(graph->yTrans))) static const xreal fontSize[3] = { 8.0, 10.0, 12.0 }, lineWidth[3] = { 0.01, 0.6, 1.5 }; static const char *pattern[] = { "1 2", "1 4", "3 3", "6 3", "5 3 1 3", "5 3 1 3 1 3", "" }; static const char *psFName = "minigraph"; static const xreal leftMargin = 2.0*CMTOPT, rightMargin = 1.5*CMTOPT, topMargin = 2.0*CMTOPT, bottomMargin = 2.0*CMTOPT; #define MAXPSMARKERS 7 static const char *psMarkers[MAXPSMARKERS] = { "", "MK1", "MK2", "MK3", "MK4", "MK5", "MK6" }; /*-------------------------------------------------------------------------*/ void PSDriverImp::Clipping(GRAPHIC *graph) { int col = graph->backgrCol; if (graph->id == PS_QUER) { fprintf(graph->file, "NP %f %f M\n", (float)(graph->wdOrgX+0.8), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX+0.8), (float)(graph->wdOrgY+graph->wdWdth+0.5)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-graph->wdHght-0.6), (float)(graph->wdOrgY+graph->wdWdth+0.5)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-graph->wdHght-0.6), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX+0.8), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "clip\n"); fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); fprintf(graph->file, "NP %f %f M\n", (float)(graph->wdOrgX), (float)(graph->wdOrgY)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX), (float)(graph->wdOrgY+graph->wdWdth)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-graph->wdHght), (float)(graph->wdOrgY+graph->wdWdth)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-graph->wdHght), (float)(graph->wdOrgY)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX), (float)(graph->wdOrgY)); fprintf(graph->file, "F\n"); graph->firstClip = False; (graph->line_count) += 13; return; } fprintf(graph->file, "NP %f %f M\n", (float)(graph->wdOrgX-0.6), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX+graph->wdWdth +0.8), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX+graph->wdWdth +0.8), (float)(graph->wdOrgY+graph->wdHght +0.5)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-0.6), (float)(graph->wdOrgY+graph->wdHght +0.5)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-0.6), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "clip\n"); (graph->line_count) += 6; if (red[col] != 1 || green[col] != 1 || blue[col] != 1) { fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); fprintf(graph->file, "NP %f %f M\n", (float)(graph->wdOrgX-0.6), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX+graph->wdWdth+0.8), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX+graph->wdWdth+0.8), (float)(graph->wdOrgY+graph->wdHght+0.5)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-0.6), (float)(graph->wdOrgY+graph->wdHght+0.5)); fprintf(graph->file, "%f %f L\n", (float)(graph->wdOrgX-0.6), (float)(graph->wdOrgY-0.8)); fprintf(graph->file, "F\n"); (graph->line_count) += 7; } graph->firstClip = False; return; } int PSDriverImp::OpenPort(GRAPHIC *graph) { time_t t; if ((graph->file) == 0) graph->file = fopen(graph->fileName,"w"); else return False; if ((graph->file) == 0) { fprintf(miniErrorFile,"MiniGraphic - zibwop : Can not open file '%s' !\n", graph->fileName); return False; } fprintf(graph->file, "%%!PS-Adobe-2.0\n"); // was 1.0 fprintf(graph->file, "%%%%Title: %s\n", graph->fileName); fprintf(graph->file, "%%%%Creator: MiniGraphic\n"); #ifndef __FreeBSD__ fprintf(graph->file, "%%%%For: %s\n", cuserid(0)); #endif time(&t); fprintf(graph->file, "%%%%CreationDate: %s", ctime(&t)); fprintf(graph->file, "%%%%Pages: (atend)\n"); fprintf(graph->file, "%%%%DocumentFonts: Times-Roman Symbol\n"); fprintf(graph->file, "%%%%BoundingBox: (atend)\n"); fprintf(graph->file, "%%%%EndComments\n"); fprintf(graph->file, "/NP {newpath} def\n"); fprintf(graph->file, "/M {moveto} def\n"); fprintf(graph->file, "/L {lineto} def\n"); fprintf(graph->file, "/F {fill} def\n"); fprintf(graph->file, "/R {rotate} def\n"); fprintf(graph->file, "/SL {setlinewidth} def\n"); fprintf(graph->file, "/SD {setdash} def\n"); fprintf(graph->file, "/SF {findfont exch scalefont setfont} def\n"); fprintf(graph->file, "/H {/Helvetica} def\n"); fprintf(graph->file, "/SC {setrgbcolor} def\n"); fprintf(graph->file, "/S {stroke} def\n"); fprintf(graph->file, "/SH {show} def\n"); fprintf(graph->file, "/MK1 {10 /Times-Roman SF (*) stringwidth pop 0.49 mul neg -4.9 rmoveto (*) SH} def\n"); fprintf(graph->file, "/MK2 {10 /Symbol SF (\\264) stringwidth pop 0.5 mul neg -2.7 rmoveto (\\264) SH} def\n"); fprintf(graph->file, "/MK3 {10 /Times-Roman SF (+) stringwidth pop 0.5 mul neg -2.5 rmoveto (+) SH} def\n"); fprintf(graph->file, "/MK4 {10 /Times-Roman SF(\\267) stringwidth pop 0.5 mul neg -3.3 rmoveto (\\267) SH} def\n"); fprintf(graph->file, "/MK5 {10 /Symbol SF(\\304) stringwidth pop 0.5 mul neg -3.5 rmoveto (\\304) SH} def\n"); fprintf(graph->file, "/MK6 {10 /Symbol SF(\\305) stringwidth pop 0.5 mul neg -3.5 rmoveto (\\305) SH} def\n"); fprintf(graph->file, "%%%%EndProlog\n"); fprintf(graph->file, "%%%%Page ? 1\n"); fprintf(graph->file, "%.4f SL\n", lineWidth[graph->drPenSz]); fprintf(graph->file, "%.4f %s SF\n", fontSize[graph->drFntSz], graph->fontName); fprintf(graph->file, "2 setlinejoin\n"); (graph->line_count) += 32; graph->ready = True; return True; } int PSDriverImp::NewPict(GRAPHIC *graph) { if (!graph->ready) return True; if (graph->id == PS_TEX) { fprintf(miniErrorFile,"MiniGraphic - zibclr : not possible on TEX-files !"); return False; } fprintf(graph->file, "showpage\n"); fprintf(graph->file, "%%%%Page ? %d\n", ++graph->page_count); Clipping(graph); graph->line_count += 2; return True; } int PSDriverImp::Close(GRAPHIC *graph) { if (!graph->ready) if (!OpenPort(graph)) return False; if (graph->id != PS_TEX) fprintf(graph->file, "showpage\n"); fprintf(graph->file, "%%%%Trailer\n"); // convert file: char line[512]; sprintf (line,"%s.tmp", graph->fileName); FILE* fout; if (!(fout=fopen(line,"w"))) { fprintf(graph->file, "%%%%Pages: %d\n", graph->page_count); fprintf(graph->file, "%%%%BoundingBox: %d %d %d %d\n", graph->wdOrgX, graph->wdOrgY, (graph->wdOrgX + graph->wdWdth), (graph->wdOrgY + graph->wdHght) ); printf("\n\n*** close: cannot convert output file %s\n",graph->fileName); fclose(graph->file); } else { int pageNo; fclose(graph->file); graph->file = fopen(graph->fileName,"r"); while (fgets(line, 512, graph->file)) { if (strstr(line, "%%Pages:")) fprintf(fout, "%%%%Pages: %d\n", graph->page_count); else if (strstr(line, "%%BoundingBox:")) fprintf(fout, "%%%%BoundingBox: %d %d %d %d\n",graph->wdOrgX, graph->wdOrgY, (graph->wdOrgX + graph->wdWdth), (graph->wdOrgY + graph->wdHght) ); else if (strstr(line, "%%Page ")) { sscanf (line, "%*s%*s%d", &pageNo); fprintf(fout, "%%%%Page %1d %1d\n", graph->page_count, pageNo); } else fputs (line, fout); } fclose(fout); fclose(graph->file); sprintf (line,"mv %s.tmp %s", graph->fileName, graph->fileName); system (line); } graph->file = 0; file = True; graph->line_count += 4; fprintf(miniErrorFile,"MiniGraphic - close : %d lines written to ", graph->line_count); fprintf(miniErrorFile,"Postscript file '%s' !\n", graph->fileName); return True; } /*-------------------------------------------------------------------------*/ int PSDriverImp::PLine(GRAPHIC *graph, float* xx, float* yy, int n) { int k, col = graph->penCol; float x, y; if (graph->firstClip) Clipping(graph); fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); x = xx[0]; y = yy[0]; if (graph->id == PS_QUER) fprintf(graph->file, "NP %.3f %.3f M\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "NP %.3f %.3f M\n", TRANSX(x), TRANSY(y)); for (k = 1; k < n; k++) { x = xx[k]; y = yy[k]; if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f L\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "%.3f %.3f L\n", TRANSX(x), TRANSY(y)); } fprintf(graph->file, "S\n"); (graph->line_count) += n+2; return True; } int PSDriverImp::PLine(GRAPHIC *graph, double* xx, double* yy, int n) { int k, col = graph->penCol; double x, y; if (graph->firstClip) Clipping(graph); fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); x = xx[0]; y = yy[0]; if (graph->id == PS_QUER) fprintf(graph->file, "NP %.3f %.3f M\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "NP %.3f %.3f M\n", TRANSX(x), TRANSY(y)); for (k = 1; k < n; k++) { x = xx[k]; y = yy[k]; if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f L\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "%.3f %.3f L\n", TRANSX(x), TRANSY(y)); } fprintf(graph->file, "S\n"); (graph->line_count) += n+2; return True; } /*-------------------------------------------------------------------------*/ int PSDriverImp::PMarker(GRAPHIC *graph, float* xx, float* yy, int n) { int k, col = graph->mrkCol; float x, y; if (graph->firstClip) Clipping(graph); fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); for (k = 0; k < n; k++) { x = xx[k]; y = yy[k]; if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f M %s\n", Q_TRANSY(y), Q_TRANSX(x), psMarkers[graph->mark]); else fprintf(graph->file, "%.3f %.3f M %s\n", TRANSX(x), TRANSY(y), psMarkers[graph->mark]); } fprintf(graph->file, "%.4f %s SF\n", fontSize[graph->drFntSz], graph->fontName); (graph->line_count) += n+2; return True; } int PSDriverImp::PMarker(GRAPHIC *graph, double* xx, double* yy, int n) { int k, col = graph->mrkCol; double x, y; if (graph->firstClip) Clipping(graph); fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); for (k = 0; k < n; k++) { x = xx[k]; y = yy[k]; if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f M %s\n", Q_TRANSY(y), Q_TRANSX(x), psMarkers[graph->mark]); else fprintf(graph->file, "%.3f %.3f M %s\n", TRANSX(x), TRANSY(y), psMarkers[graph->mark]); } fprintf(graph->file, "%.4f %s SF\n", fontSize[graph->drFntSz], graph->fontName); (graph->line_count) += n+2; return True; } /*-------------------------------------------------------------------------*/ int PSDriverImp::Text (GRAPHIC *graph, double x, double y, char* s) { int col = graph->fntCol; if (graph->firstClip) Clipping(graph); fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f M 90 R (%s) SH -90 R\n", Q_TRANSY(y), Q_TRANSX(x), s); else fprintf(graph->file, "%.3f %.3f M (%s) SH\n", TRANSX(x), TRANSY(y), s); (graph->line_count) += 2; return True; } /*-------------------------------------------------------------------------*/ int PSDriverImp::Fill(GRAPHIC *graph, float* xx, float* yy, int n) { int k, col = graph->fllCol; float x, y; if (graph->firstClip) Clipping(graph); x = xx[0]; y = yy[0]; fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); if (graph->id == PS_QUER) fprintf(graph->file, "NP %.3f %.3f M\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "NP %.3f %.3f M\n", TRANSX(x), TRANSY(y)); for (k = 1; k < n; k++) { x = xx[k]; y = yy[k]; if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f L\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "%.3f %.3f L\n", TRANSX(x), TRANSY(y)); } fprintf(graph->file, "F\n"); (graph->line_count) += n+2; return True; } int PSDriverImp::Fill(GRAPHIC *graph, double* xx, double* yy, int n) { int k, col = graph->fllCol; double x, y; if (graph->firstClip) Clipping(graph); x = xx[0]; y = yy[0]; fprintf(graph->file, " %.4f %.4f %.4f SC\n", red[col], green[col], blue[col]); if (graph->id == PS_QUER) fprintf(graph->file, "NP %.3f %.3f M\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "NP %.3f %.3f M\n", TRANSX(x), TRANSY(y)); for (k = 1; k < n; k++) { x = xx[k]; y = yy[k]; if (graph->id == PS_QUER) fprintf(graph->file, "%.3f %.3f L\n", Q_TRANSY(y), Q_TRANSX(x)); else fprintf(graph->file, "%.3f %.3f L\n", TRANSX(x), TRANSY(y)); } fprintf(graph->file, "F\n"); (graph->line_count) += n+2; return True; } /*-------------------------------------------------------------------------*/ int PSDriverImp::Color(int col_no, int rVal, int gVal, int bVal) { red[col_no] = rVal/255.0; green[col_no] = gVal/255.0; blue[col_no] = bVal/255.0; return True; } /*-------------------------------------------------------------------------*/ int PSDriverImp::Settings(GRAPHIC *graph, int type, char* str) { int n; switch (type) { case CAPTION : case FILENAME: delete graph->fileName; n = strlen(str); graph->fileName = new char[n+1]; strcpy(graph->fileName, str); break; default: fprintf(miniErrorFile,"MiniGraphic - set : unkown type %d for ps !\n", type); return False; } if (!graph->ready) if (!OpenPort(graph)) return False; return True; } int PSDriverImp::Settings(GRAPHIC *graph, int type, int iVal) { if (! graph->ready) if (!OpenPort(graph)) return False; switch (type) { case WDORGX : if ((iVal >= 0) && (iVal <= graph->right)) graph->wdOrgX = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : wrong value for WDORGX %d !\n", iVal); return False; } break; case WDORGY : if ((iVal >= 0) && (iVal <= graph->top)) graph->wdOrgY = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : wrong value for WDORGY %d !\n", iVal); return False; } break; case WDWDTH : if (graph->id == PS_QUER) { if ((iVal >= 0) && (iVal + graph->wdOrgY <= graph->top)) { graph->wdWdth = iVal; break; } } else if ((iVal >= 0) && (iVal + graph->wdOrgX <= graph->right)) { graph->wdWdth = iVal; break; } fprintf(miniErrorFile,"MiniGraphic - set : wrong value for WDWDTH %d !\n", iVal); return False; case WDHGHT : if (graph->id == PS_QUER) { if ((iVal >= 0) && (graph->wdOrgX - iVal >= graph->left)) { graph->wdHght = iVal; break; } } else if ((iVal >= 0) && (iVal + graph->wdOrgY <= graph->top)) { graph->wdHght = iVal; break; } fprintf(miniErrorFile,"MiniGraphic - set : wrong value for WDHGHT %d !\n", iVal); return False; case MARKER: if ((iVal >= 0)&&(iVal < MAXPSMARKERS)) graph->mark = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set: unknown marker %d !\n", iVal); return False; } break; case PENSIZE: if ((iVal >= SMALL) && (iVal <= BIG)) { graph->drPenSz = iVal; fprintf(graph->file, "%.4f SL\n", lineWidth[graph->drPenSz]); (graph->line_count)++; } else { fprintf(miniErrorFile,"MiniGraphic - set : wrong value for PENSIZE %d !\n", iVal); return False; } break; case LINESTYLE: if ((iVal >= DOTTED) && (iVal <= SOLID)) { graph->linestyle = iVal; fprintf(graph->file, "[%s] 0 SD\n", pattern[graph->linestyle]); (graph->line_count)++; } else { fprintf(miniErrorFile,"MiniGraphic - set : wrong value for LINESTYLE %d !\n", iVal); return False; } break; case FONTSIZE: if ((iVal >= SMALL) && (iVal <= BIG)) { graph->drFntSz = iVal; fprintf(graph->file, "%.4f %s SF\n", fontSize[graph->drFntSz], graph->fontName); (graph->line_count)++; } else { fprintf(miniErrorFile,"MiniGraphic - set : wrong value for FONTSIZE %d !\n", iVal); return False; } break; case FILLCOL: if ((iVal >= 0) && (iVal < COLORS)) graph->fllCol = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : unknown gray %d !\n", iVal); return False; } break; case PENCOL : if ((iVal >= 0) && (iVal <= COLORS)) graph->penCol = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : unknown pencolor %d !\n", iVal); return False; } break; case FONTCOL : if ((iVal >= 0) && (iVal <= COLORS)) graph->fntCol = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : unknown fontcolor %d !\n", iVal); return False; } break; case MARKCOL : if ((iVal >= 0) && (iVal <= COLORS)) graph->mrkCol = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : unknown markercolor "); fprintf(miniErrorFile,"%d !\n", iVal); return False; } break; case BACKGRCOL : if ((iVal >= 0) && (iVal <= COLORS)) graph->backgrCol = iVal; else { fprintf(miniErrorFile,"MiniGraphic - set : unknown backgroundcolor "); fprintf(miniErrorFile,"%d !\n", iVal); return False; } break; case FONTPROP : case CAPTION : return False; /* case BUFFER : fprintf(miniErrorFile,"MiniGraphic - set : BUFFER only on X11 !\n"); return False; */ default: fprintf(miniErrorFile,"MiniGraphic - set : unkown type %d !\n", type); return False; } return True; } //------------------------------------------------------------------------- PSDriverImp:: PSDriverImp() { int i; file = True; for (i=0; i<8; ++i) { red[i] = psRed[i]; green[i] = psGreen[i]; blue[i] = psBlue[i]; } for (i = 8; i < 32; i++) red[i] = green[i] = blue[i] = (float)(i-8)/(float)(GRAYS-1); for (i = 32; i < COLORS; i++) red[i] = green[i] = blue[i] = 1.0; strcpy(fontName, "H"); /* Helvetica */ } //------------------------------------------------------------------------- int PSDriverImp:: Init(GRAPHIC *graph, float /*size*/) { graph->fileName = new char[strlen(psFName)+7]; sprintf (graph->fileName,"%s%1d.ps", psFName, graph->wdNo); graph->bottom = 0.0; graph->left = 0.0; graph->top = 840.6; graph->right = 593.8; switch (graph->id) { case PS_QUER : graph->wdOrgX = (int) (593.8-rightMargin); graph->wdOrgY = (int) (bottomMargin); graph->wdWdth = (int) (840.6-topMargin-bottomMargin); graph->wdHght = (int) (593.8-rightMargin-leftMargin); break; case PS_TEX : graph->wdOrgX = (int) (0.0); graph->wdOrgY = (int) (0.0); graph->wdWdth = (int) (593.8); graph->wdHght = (int) (840.6); break; default : graph->wdOrgX = (int) (leftMargin); graph->wdOrgY = (int) (bottomMargin); graph->wdWdth = (int) (593.8-rightMargin-leftMargin); graph->wdHght = (int) (840.6-topMargin-bottomMargin); } graph->drRes = 72.0/300.0; graph->drPenSz = SMALL; graph->linestyle = SOLID; graph->drFntSz = MEDIUM; graph->mark = STAR; graph->maxCol = COLORS; graph->maxGry = GRAYS; graph->penCol = graph->fllCol = graph->fntCol = graph->mrkCol = BLACK; graph->backgrCol = WHITE; graph->drXcm = PTTOCM; graph->drYcm = PTTOCM; graph->firstClip = True; graph->fontName = fontName; graph->caption = new char[strlen(captionName)+1]; strcpy (graph->caption, captionName); graph->file = 0; return True; }