/***************************************************************************** * Module to handle PostScript output. * * * * Written by: Gershon Elber Ver 1.0, Apr. 1990 * *****************************************************************************/ #ifdef __MSDOS__ #include #else #include #endif #include #include #include #include "program.h" #include "genmat.h" #include "interact.h" #include "graphgen.h" static FILE *PSFile = NULL; /* Used to save PostScript text file. */ static void (* SavedMoveToPtr)(RealType Coord[3]); static void (* SavedDrawToPtr)(RealType Coord[3]); static void PSMoveTo(RealType Coord[3]); static void PSDrawTo(RealType Coord[3]); /***************************************************************************** * Routine to save the current view as PostScript text file. * * Although this routine dumps EPSF-1.2 compatible code, it still dumps * * the 'showpage' command. The 'showpage' is allowed by the EPSF document and * * it is the responsibility of the including program to disable showpage. * *****************************************************************************/ void SavePostScript(IPObjectStruct *Objects) { int i; time_t time1970 = time(NULL); char *p, FileName[PATH_NAME_LEN]; static char FileCount = '0'; static char *PSHeader[] = { "%!PS-Adobe-2.0 EPSF-1.2", "%%BoundingBox: 36 108 540 612", /* 7x7 inches, LL at [0.5, 1.5]. */ "%%Title:", "%%Creator: Poly3d", "%%CreationDate:", "%%EndComments", "", "gsave", "", "72 72 scale", /* First scale to inches, se we can speak in inches. */ "4.0 5.0 translate", /* To Center of image area. */ "3.5 3.5 scale", /* Make the universe -1..1 on both X and Y. */ "", "/line {", " newpath", " moveto", " lineto", " stroke", "} def", "", "/setdashline {", " [0.012 0.024] 0 setdash", "} def", "", "/setfullline {", " [] 0 setdash", "} def", "", "0.006 setlinewidth", /* Set some default line attributes. */ "1 setlinecap", "1 setlinejoin", "setfullline", "", NULL }; static char *PSTrailer[] = { "", "showpage", "grestore", NULL }; strcpy(FileName, GENERIC_PS_FILE); if ((p = strchr(FileName, '#')) != NULL) { *p = FileCount; if (FileCount++ == '9') FileCount = '0'; } if ((PSFile = fopen(FileName, "wt")) == NULL) { GGTone(700, 200); return; } for (i = 0; PSHeader[i] != NULL; i++) { if (strcmp(PSHeader[i], "%%Title:") == 0) fprintf(PSFile, "%s %s\n", PSHeader[i], GlblFirstDataFileName); else if (strcmp(PSHeader[i], "%%CreationDate:") == 0) fprintf(PSFile, "%s %s", PSHeader[i], ctime(&time1970)); else fprintf(PSFile, "%s\n", PSHeader[i]); } SavedMoveToPtr = MoveToPtr; SavedDrawToPtr = DrawToPtr; MoveToPtr = PSMoveTo; DrawToPtr = PSDrawTo; DrawAllObjects(Objects); MoveToPtr = SavedMoveToPtr; DrawToPtr = SavedDrawToPtr; for (i = 0; PSTrailer[i] != NULL; i++) fprintf(PSFile, "%s\n", PSTrailer[i]); fclose(PSFile); } static RealType LastCoord[3]; /* Used to store last point we moved/draw to. */ /***************************************************************************** * Routine to mave to 3D point given as Coord[3], using Mat transform. * *****************************************************************************/ static void PSMoveTo(RealType Coord[3]) { MultVecby4by4(LastCoord, Coord, CrntViewMat); /* Set last point coord. */ } /***************************************************************************** * Routine to draw to 3D point given as Coord[3], using Mat transform, from * * the last point we moved to. * *****************************************************************************/ static void PSDrawTo(RealType Coord[3]) { static DashState = FALSE; RealType NewCoord[3], MiddleCoord[3], t; MultVecby4by4(NewCoord, Coord, CrntViewMat); /* Set last point coord. */ if (GlblClosedObject && NewCoord[2] < LastCoord[2]) { GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType)); return; } /* Implementation of simple depth cue - if line is >Z or = 0.0 && NewCoord[2] >= 0.0 || ABS(LastCoord[2] - NewCoord[2]) < EPSILON) { if (GlblDepthCue && DashState) { fprintf(PSFile, "setfullline\n"); DashState = FALSE; } fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]); fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]); } else { /* Line intersect Z = 0 plane. */ t = LastCoord[2] / (LastCoord[2] - NewCoord[2]); MiddleCoord[0] = LastCoord[0] * (1.0 - t) + NewCoord[0] * t; MiddleCoord[1] = LastCoord[1] * (1.0 - t) + NewCoord[1] * t; if (GlblDepthCue && DashState) { fprintf(PSFile, "setfullline\n"); DashState = FALSE; } if (LastCoord[2] > 0.0) { fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]); fprintf(PSFile, "%10.7lf %10.7lf line\n", MiddleCoord[0], MiddleCoord[1]); } else { fprintf(PSFile, "%10.7lf %10.7lf ", MiddleCoord[0], MiddleCoord[1]); fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]); } if (GlblDepthCue && !DashState) { fprintf(PSFile, "setdashline\n"); DashState = TRUE; } if (LastCoord[2] < 0.0) { fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]); fprintf(PSFile, "%10.7lf %10.7lf line\n", MiddleCoord[0], MiddleCoord[1]); } else { fprintf(PSFile, "%10.7lf %10.7lf ", MiddleCoord[0], MiddleCoord[1]); fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]); } } GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType)); /* Current point. */ }