/* File: graphps.c * Author: Richard Durbin (rd@mrc-lmb.cam.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1992 * ------------------------------------------------------------------- * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: to provide postscript output for the graph package * Exported functions: graphPS(), graphPrint() * SCCS: $Id: graphps.c,v 1.64 2003/12/12 14:14:08 edgrif Exp $ * HISTORY: * Last edited: Dec 12 11:35 2003 (edgrif) * * May 11 10:42 1999 (edgrif): Corrected my own bug in PS-Adobe header. * * Apr 29 16:05 1999 (edgrif): Added code for new graphdev layer, * see Graph_Internals.html for details. * * Jan 21 14:34 1999 (edgrif): Added EPSF parameter to graphPS & * graphPSDefaults + code to make non-EPSF files. * * Jan 5 14:11 1999 (edgrif): Make graphPStitle() internal as PStitle, * it's not used anywhere. Correct code for checking string * pointers in several places (i.e. NULL ptr check AND null * string check required). * * Sep 25 16:52 1998 (edgrif): Replace #ifdef ACEDB with graph/acedb, * two references to session and one to acedb PS fonts file. * * Oct 1997 (michel): fixed the date printing * * Apr 10 (mieg): set for color laser printer (add COLOUR in psfont.wrm) * * Aug 14 18:05 1992 (rd): COLOR_SQUARES * * Jul 25 12:28 1992 (mieg): TEXT_PTR_PTR * Created: Wed May 20 08:30:44 1992 (rd) * CVS info: $Id: graphps.c,v 1.64 2003/12/12 14:14:08 edgrif Exp $ *------------------------------------------------------------------- */ #include #include #include #include #include #include #include typedef struct { ACEOUT fo; Graph_ graph; BOOL isColor; int currColor; float currLineWidth; GraphLineStyle currLineStyle ; float currTextHeight; int currTextFormat; } psContext; static int psSetColor(psContext *ps, int col) { float r, g, b, gr; if (ps->currColor == col) return ESUCCESS; ps->currColor = col; graphGetColourAsFloat(col, &r, &g, &b, &gr); if (ps->isColor) return aceOutPrint(ps->fo, "%.2f %.2f %.2f setrgbcolor\n", r, g, b); else return aceOutPrint(ps->fo, "%.2f setgray\n", gr) ; } static int psSetLineWidth(psContext *ps, float width) { if (width == ps->currLineWidth) return ESUCCESS; ps->currLineWidth = width; return aceOutPrint(ps->fo, "%f setlinewidth\n", width) ; } /* Set the line to be dashed, note that the X default is a dashed * pattern of 4 on, 4 off, I am not sure how this scales to th * poscript output, I have put "[1] for now.... */ static int psSetLineStyle(psContext *ps, GraphLineStyle style) { if (style == ps->currLineStyle) return ESUCCESS; ps->currLineStyle = style; if (style == GRAPH_LINE_SOLID) return aceOutPrint(ps->fo, "[] 0 setdash\n") ; else return aceOutPrint(ps->fo, "[1] 0 setdash\n") ; } /* This needs re-doing TODO */ static Stack psGetFontNames(void) { int nFonts = 0 ; FILE *fil; Stack fontNameStack = stackCreate(50) ; /* ACEDB-GRAPH INTERFACE: Get acedb ps fonts if any registered. */ if (getGraphAcedbGetFonts() != NULL) (getGraphAcedbGetFonts())(&fil, fontNameStack, &nFonts) ; if (nFonts < 5) { stackClear (fontNameStack) ; pushText (fontNameStack,"Helvetica") ; /* normal */ pushText (fontNameStack,"Helvetica-Oblique") ; /* italic */ pushText (fontNameStack,"Helvetica-Bold") ; /* bold */ pushText (fontNameStack,"Courier") ; /* fixed */ pushText (fontNameStack,"Times-Roman") ; /* title */ } return fontNameStack; } /*****************************************/ static int psSetFont(psContext *ps, int format, float height) { int err; if ((format == ps->currTextFormat) && (height == ps->currTextHeight)) return ESUCCESS; ps->currTextFormat = format; ps->currTextHeight = height; switch (format) { case ITALIC: if (height) err = aceOutPrint(ps->fo, "italicFont %.4f scalefont setfont\n", height) ; else err = aceOutPrint(ps->fo, "italicFont setfont\n") ; break ; case BOLD: if (height) err = aceOutPrint(ps->fo, "boldFont %.4f scalefont setfont\n", height) ; else err = aceOutPrint(ps->fo, "boldFont setfont\n") ; break ; case FIXED_WIDTH: if (height) err = aceOutPrint(ps->fo, "fixedFont %.4f scalefont setfont\n", height) ; else err = aceOutPrint(ps->fo, "fixedFont setfont\n") ; break ; case PLAIN_FORMAT: default: if (height) err = aceOutPrint(ps->fo, "defaultFont %.4f scalefont setfont\n", height) ; else err = aceOutPrint(ps->fo, "defaultFont setfont\n") ; break ; } return err; } /***********************************************/ static int psDrawBox (psContext *ps, Box box) { float x1,x2,y1,y2 ; int action, err; float pointSize = box->pointsize; float textHeight = box->textheight; int textFormat = box->format; float lineWidth = box->linewidth; GraphLineStyle lineStyle = box->line_style ; int colour = box->fcol; if ((box->bcol != TRANSPARENT) && (box->bcol != WHITE) && (box->x1 <= 999999.0)) { err = psSetColor(ps, box->bcol); if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, "%.4f %.4f %.4f %.4f rectangle fill\n", box->x1,box->y1,box->x2,box->y2) ; if (err != ESUCCESS) return err; } stackCursor (ps->graph->stack, box->mark) ; while (!stackAtEnd (ps->graph->stack)) switch (action = stackNext (ps->graph->stack, int)) { case BOX_END: return ESUCCESS; /* exit point */ case BOX_START: err = psDrawBox (ps, arrp (ps->graph->boxes, stackNext(ps->graph->stack, int), BoxStruct)); if (err != ESUCCESS) return err; break; case COLOR: colour = stackNext (ps->graph->stack,int) ; break; case TEXT_FORMAT: textFormat = stackNext (ps->graph->stack,int) ; break; case LINE_WIDTH: lineWidth = stackNext (ps->graph->stack,float); break ; case LINE_STYLE: lineStyle = stackNext (ps->graph->stack, int) ; break ; case TEXT_HEIGHT: textHeight = stackNext (ps->graph->stack,float) ; break ; case POINT_SIZE: pointSize = stackNext (ps->graph->stack,float) ; break ; case LINE: case RECTANGLE: case FILL_RECTANGLE: x1 = stackNext (ps->graph->stack,float) ; y1 = stackNext (ps->graph->stack,float) ; x2 = stackNext (ps->graph->stack,float) ; y2 = stackNext (ps->graph->stack,float) ; err = psSetColor(ps, colour); if (err != ESUCCESS) return err; err = psSetLineWidth(ps, lineWidth); if (err != ESUCCESS) return err; err = psSetLineStyle(ps, lineStyle); if (err != ESUCCESS) return err; switch (action) { case LINE: err = aceOutPrint(ps->fo, "newpath %.4f %.4f moveto %.4f %.4f lineto stroke\n", x1,y1,x2,y2) ; break ; case RECTANGLE: err = aceOutPrint(ps->fo,"%.4f %.4f %.4f %.4f rectangle stroke\n", x1,y1,x2,y2) ; break ; case FILL_RECTANGLE: err = aceOutPrint(ps->fo,"%.4f %.4f %.4f %.4f rectangle fill\n", x1,y1,x2,y2) ; break ; } if (err != ESUCCESS) return err; break ; case PIXELS: case PIXELS_RAW: { unsigned char *ip, *pixels; int w, h, line, i, j; #ifndef ACEDB_GTK int reverse[256]; unsigned char hexVal[256]; float fac ; #else unsigned char *hexVal = graphGreyRampGetMap(); #endif x1 = stackNext (ps->graph->stack, float) ; y1 = stackNext (ps->graph->stack, float) ; pixels = stackNext (ps->graph->stack, unsigned char*) ; w = stackNext (ps->graph->stack, int) ; h = stackNext (ps->graph->stack, int) ; line = stackNext (ps->graph->stack, int) ; if (action == PIXELS) { /* PIXELS are not implemented yet */ x2 = stackNext (ps->graph->stack, float) ; y2 = stackNext (ps->graph->stack, float) ; } else { x2 = x1 + w/ps->graph->xFac ; y2 = y1 + h/ps->graph->yFac ; #ifndef ACEDB_GTK graphRawMaps (0, reverse) ; if (rampMin < rampMax) fac = 0xff / (float) (rampMax - rampMin) ; else fac = 0xff / (float) (rampMin - rampMax) ; for (i = 0 ; i < 256 ; ++i) { j = reverse[i] ; if (rampMin < rampMax) { if (j < rampMin) hexVal[i] = 0 ; else if (j >= rampMax) hexVal[i] = 0xff ; else hexVal[i] = fac * (j - rampMin) ; } else { if (j < rampMax) hexVal[i] = 0xff ; else if (j >= rampMin) hexVal[i] = 0 ; else hexVal[i] = fac * (rampMin - j) ; } } #endif /* ACEDB_GTK */ err = aceOutPrint(ps->fo, "/picstring %d string def\n", w) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, " gsave") ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, " %.4f %.4f translate ", x1, y1) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, " %.4f %.4f scale\n", x2-x1, y2-y1) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, " %d %d 8", w, h) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, " [ %d 0 0 %d 0 0 ]", w, h) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, " { currentfile picstring" " readhexstring pop } image") ; ip = pixels ; for (j = 0 ; j < h ; j++) { err = aceOutPrint(ps->fo, "\n ") ; if (err != ESUCCESS) return err; for (i = 0 ; i < w ; ) { err = aceOutPrint(ps->fo, "%02x", hexVal[*ip++]) ; if (err != ESUCCESS) return err; if (!(++i % 35)) { err = aceOutPrint(ps->fo, "\n ") ; if (err != ESUCCESS) return err; } } if (i < line) ip += (line-i) ; } err = aceOutPrint(ps->fo, " grestore\n") ; if (err != ESUCCESS) return err; } } break ; case POLYGON: case LINE_SEGS: { int n = stackNext (ps->graph->stack, int) ; err = psSetColor(ps, colour); if (err != ESUCCESS) return err; err = psSetLineWidth(ps, lineWidth); if (err != ESUCCESS) return err; err = psSetLineStyle(ps, lineStyle); if (err != ESUCCESS) return err; if (n-- > 2) { err = aceOutPrint(ps->fo, "newpath %.4f %.4f moveto\n", stackNext (ps->graph->stack, float), stackNext (ps->graph->stack, float)) ; if (err != ESUCCESS) return err; while (n--) { err = aceOutPrint(ps->fo, " %.4f %.4f lineto\n", stackNext (ps->graph->stack, float), stackNext (ps->graph->stack, float)) ; if (err != ESUCCESS) return err; } if (action == POLYGON) err = aceOutPrint(ps->fo," fill\n") ; else err = aceOutPrint(ps->fo," stroke\n") ; if (err != ESUCCESS) return err; } break ; } case TEXT: case TEXT_UP: case TEXT_PTR: case TEXT_PTR_PTR: { char *cp = 0; x1 = stackNext (ps->graph->stack,float) ; y1 = stackNext (ps->graph->stack,float) ; err = psSetColor(ps, colour); if (err != ESUCCESS) return err; err = psSetLineWidth(ps, lineWidth); if (err != ESUCCESS) return err; err = psSetLineStyle(ps, lineStyle); if (err != ESUCCESS) return err; err = psSetFont(ps, textFormat, textHeight); if (err != ESUCCESS) return err; if (action == TEXT_UP) err = aceOutPrint(ps->fo, "gsave %f %f translate -90 rotate 0.6 1.0 scale" " 0.2 0.0 moveto (", x1, y1) ; else err = aceOutPrint (ps->fo, "%.4f %.4f moveto (", x1, y1) ; if (err != ESUCCESS) return err; switch (action) { case TEXT: case TEXT_UP: cp = stackNextText(ps->graph->stack) ; break; case TEXT_PTR: cp = stackNext(ps->graph->stack,char*) ; break; case TEXT_PTR_PTR: cp = *stackNext(ps->graph->stack,char**) ; break; } if (cp) while(*cp) { switch (*cp) { case '(': case ')': case '\\': err = aceOutPrint(ps->fo, "\\") ; if (err != ESUCCESS) return err; break ; } /* use binary to avoid interpreting % */ err = aceOutBinary(ps->fo, cp++, 1) ; if (err != ESUCCESS) return err; } if (action == TEXT_UP) err = aceOutPrint(ps->fo, ") show grestore\n") ; else err = aceOutPrint(ps->fo, ") show\n") ; if (err != ESUCCESS) return err; } break ; case CIRCLE: case POINT: case COLOR_SQUARES: case FILL_ARC: case ARC: x1 = stackNext (ps->graph->stack,float) ; y1 = stackNext (ps->graph->stack,float) ; err = psSetColor(ps, colour); if (err != ESUCCESS) return err; err = psSetLineWidth(ps, lineWidth); if (err != ESUCCESS) return err; err = psSetLineStyle(ps, lineStyle); if (err != ESUCCESS) return err; switch (action) { case CIRCLE: err = aceOutPrint(ps->fo,"%.4f %.4f moveto\n", x1, y1) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, "newpath %.4f %.4f %.4f 0 360 arc stroke\n", x1, y1, stackNext (ps->graph->stack,float)) ; if (err != ESUCCESS) return err; break ; case ARC: { float r = stackNext (ps->graph->stack, float) ; float ang = stackNext (ps->graph->stack, float) ; float angdiff = stackNext (ps->graph->stack, float) ; err = aceOutPrint(ps->fo, "newpath %.4f %.4f %.4f %.4f %.4f arc stroke\n", x1, y1, r, -ang-angdiff, -ang) ; if (err != ESUCCESS) return err; } break ; case FILL_ARC: { float r = stackNext (ps->graph->stack, float) ; float ang = stackNext (ps->graph->stack, float) ; float angdiff = stackNext (ps->graph->stack, float) ; err = aceOutPrint(ps->fo,"newpath %.4f %.4f moveto\n", x1, y1) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo,"%.4f %.4f %.4f %.4f %.4f arc fill\n", x1, y1, r, -ang-angdiff, -ang) ; if (err != ESUCCESS) return err; } break ; case POINT: { float psize2 = pointSize/2; err = aceOutPrint(ps->fo,"%.4f %.4f %.4f %.4f rectangle fill\n", x1-psize2,y1-psize2,x1+psize2,y1+psize2) ; if (err != ESUCCESS) return err; } break ; case COLOR_SQUARES: { char *text = stackNext (ps->graph->stack, char*) ; int n = stackNext (ps->graph->stack, int) ; int s = stackNext (ps->graph->stack, int) ; int *tints = stackNext (ps->graph->stack, int*) ; int x2 = 0; int new = 0, old = colour ; while (n--) { switch(*text^((*text)-1)) { case -1: new = WHITE; break; case 0x01: new = tints[0]; break; case 0x03: new = tints[1]; break; case 0x07: new = tints[2]; break; case 0x0f: new = tints[3]; break; case 0x1f: new = tints[4]; break; case 0x3f: new = tints[5]; break; case 0x7f: new = tints[6]; break; case 0xff: new = tints[7]; break; } if (old != new) { if (x2 > 0) { err = aceOutPrint(ps->fo, "%.4f %.4f %.4f %.4f rectangle fill\n", x1, y1, x1+x2, y1+1) ; if (err != ESUCCESS) return err; } x1 += x2; x2 = 0; err = psSetColor(ps, new); if (err != ESUCCESS) return err; old = new; } x2++; text += s ; } if (x2 > 0) { err = aceOutPrint(ps->fo, "%.4f %.4f %.4f %.4f rectangle fill\n", x1, y1, x1+x2, y1+1) ; if (err != ESUCCESS) return err; } err = psSetColor(ps, colour); if (err != ESUCCESS) return err; } break ; case IMAGE: { void* gim = stackNext (ps->graph->stack, void*) ; gim = 0 ; } break ; default: messout ("Invalid action %d received in drawPSBox",action) ; break ; } } return ESUCCESS; } static int psTitle (psContext *ps, char *title, time_t *time) { int err; err = aceOutPrint(ps->fo, "%%%%title page begin\n" "gsave\n" "20 756 translate 7 -12 scale\n" "0.0 setgray\n" "0 titleFont setfont\n" "0 -5 moveto\n" "( %s) show\n", ctime(time)) ; if (err != ESUCCESS) return err; if (title && *title) { err = aceOutPrint(ps->fo, "0 -4 moveto\n" "( %s) show\n", title) ; if (err != ESUCCESS) return err; } err = aceOutPrint(ps->fo, "grestore\n" "%%%%title page end\n") ; return err; } static int psCreateFonts(psContext *ps, Stack names) { int dy; int err; float scale1, scale1fix, scale2; if (!gFontInfo (ps->graph, 0, 0, &dy)) /* number of pixels of a character */ messcrash ("Can't get font info for current font") ; /* srk - I think these should be yFac - but this is how it always was. */ scale1 = dy/ps->graph->xFac; scale1fix = dy*1.026/ps->graph->xFac; /* orig: esr 12/94 */ scale2 = -((float)dy)/(ps->graph->aspect*ps->graph->xFac); err = aceOutPrint(ps->fo, "/defaultFont %% --\n" " /%s findfont 0 -0.7 matrix translate makefont\n" " %f %f matrix scale makefont def\n", stackNextText(names), scale1, scale2) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, "/italicFont %% --\n" " /%s findfont 0 -0.7 matrix translate makefont\n" " %f %f matrix scale makefont def\n", stackNextText(names), scale1, scale2) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, "/boldFont %% --\n" " /%s findfont 0 -0.7 matrix translate makefont\n" " %f %f matrix scale makefont def\n", stackNextText(names), scale1, scale2) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, "/fixedFont %% --\n" " /%s findfont 0 -0.7 matrix translate makefont\n" " %f %f matrix scale makefont def\n", stackNextText(names), scale1fix, scale2) ; if (err != ESUCCESS) return err; err = aceOutPrint(ps->fo, "/titleFont %% --\n" " /%s findfont 0 -0.7 matrix translate makefont\n" " %f %f matrix scale makefont def\n", stackNextText(names), scale1, scale2) ; return err; } void psGetPaperSize(PaperType t, float *pageWidth, float *pageHeight) { /* page sizes cribbed from netscape print window and scaled from original A4 numbers */ switch (t) { case PAPERTYPE_A4: *pageWidth = 558.0F; *pageHeight = 756.0F; break; case PAPERTYPE_LETTER: *pageWidth = 573.6F; *pageHeight = 710.0F; break; case PAPERTYPE_LEGAL: *pageWidth = 573.6F; *pageHeight = 905.0F; break; case PAPERTYPE_EXECUTIVE: *pageWidth = 506.1F; *pageHeight = 646.5F; break; } } /****************************************************************/ void graphPSdefaults (Graph gId, PaperType paper, BOOL *pRot, float *pFac, int *pPage) { Graph_ graph; float pageWidth, pageHeight; float h, w; float xfac, yfac, fac ; BOOL isRotate = FALSE ; graph = gGetStruct(gId); if (!graph) return; h = graph->uh ; w = graph->uw / graph->aspect ; psGetPaperSize(paper, &pageWidth, &pageHeight); switch (graph->type) { case TEXT_SCROLL: case TEXT_FULL_SCROLL: case TEXT_FIT: case TEXT_HSCROLL: if (12 * w < pageWidth) /* reduce, but never blow up */ fac = 12.0 ; else if (10 * w < pageWidth) fac = 10.0 ; else { if (w > h) { float x = w ; w = h ; h = x ; isRotate = TRUE ; if (12 * w < pageWidth) /* reduce, but never blow up */ fac = 12.0 ; else if (10 * w < pageWidth) fac = 10.0 ; else fac = .95 * pageWidth / w; } else fac = .95 * pageWidth / w; } break ; case MAP_SCROLL: case PIXEL_SCROLL: case PIXEL_FIT: case PIXEL_VSCROLL: case PIXEL_HSCROLL: case PLAIN: if (w > h) { float x = w ; w = h ; h = x ; isRotate = TRUE ; } xfac = .996 * pageWidth / w ; yfac = .996 * pageHeight / h ; fac = (xfac < yfac) ? xfac : yfac ; break ; default: messcrash ("Unknown graph type in graphPS") ; return ; } *pRot = isRotate ; *pFac = fac ; *pPage = 1 + h * fac/pageHeight ; } int graphPS (Graph gId, ACEOUT fo, char *title, BOOL doColor, BOOL isEPSF, BOOL isRotate, PaperType paper, float fac, int pages) { psContext ps; Stack fontNames; int err, i; float pageWidth, pageHeight; static char *psHeader = "%!PS-Adobe-1.0" ; static char *EPSFHeader = "EPSF-1.2" ; time_t now; ps.graph = gGetStruct(gId); if (!ps.graph) return EINVAL; time(&now); /* Set defaults, mostly set so that they will be changed the first time they are * queried with the psGetXXXX routines. */ psGetPaperSize(paper, &pageWidth, &pageHeight); ps.fo = fo; ps.isColor = doColor; ps.currColor = -1; ps.currLineWidth = -1.0; ps.currLineStyle = GRAPH_LINE_SOLID ; ps.currTextFormat = 0; ps.currTextHeight = -1.0; if (isEPSF) err = aceOutPrint(fo, "%s %s\n", psHeader, EPSFHeader) ; else err = aceOutPrint(fo, "%s\n", psHeader) ; if (err != ESUCCESS) return err; if (title && *title) err = aceOutPrint(fo,"%%%%Title: %s\n",title); else err = aceOutPrint(fo,"%%%%Title: acedb generated document\n"); if (err != ESUCCESS) return err; err = aceOutPrint(fo, "%%%%CreationDate: %s\n", ctime(&now)) ; if (err != ESUCCESS) return err; if ((pages == 1) && isEPSF) { float bx1, bx2, by1, by2 ; float ux1, ux2, uy1, uy2 ; graphBoxDim (0, &ux1, &uy1, &ux2, &uy2) ; ux1 -= gActive->ux ; ux2 -= gActive->ux ; uy1 -= gActive->uy ; uy2 -= gActive->uy ; ux1 *= fac/ps.graph->aspect ; ux2 *= fac/ps.graph->aspect ; uy1 *= -fac ; uy2 *= -fac ; if (isRotate) { bx1 = uy1 ; bx2 = uy2 ; by1 = -ux1 ; by2 = -ux2 ; bx1 += pageWidth ; bx2 += pageWidth ; by1 += pageHeight ; by2 += pageHeight ; } else { bx1 = 18 + ux1 ; bx2 = 18 + ux2 ; by1 = pageHeight + uy2 ; by2 = pageHeight + uy1 ; } err = aceOutPrint (fo,"%%%%BoundingBox: %.1f %.1f %.1f %.1f\n", bx1, by1, bx2, by2) ; if (err != ESUCCESS) return err; } err = aceOutPrint (fo,"%%%%EndComments\n"); if (err != ESUCCESS) return err; err = aceOutPrint(fo, "/rectangle %% x1 y1 x2 y2 ==> _\n" " {/y2 exch def /x2 exch def /y1 exch def /x1 exch def\n" " newpath\n" " x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto\n" " closepath\n" " } def\n") ; if (err != ESUCCESS) return err; fontNames = psGetFontNames(); stackCursor(fontNames,0) ; /* RD adopted Jean's font fix */ err = psCreateFonts(&ps, fontNames); stackDestroy(fontNames); if (err != ESUCCESS) return err; if (title && *title) { err = psTitle (&ps, title, &now); if (err != ESUCCESS) return err; } if (isRotate) err = aceOutPrint(fo, "gsave\n%f %f translate -90 rotate ", pageWidth, pageHeight) ; else err = aceOutPrint(fo, "gsave\n18 %f translate ", pageHeight) ; if (err != ESUCCESS) return err; err = aceOutPrint(fo, "%.4f %.4f scale ", fac/ps.graph->aspect, -fac) ; if (err != ESUCCESS) return err; err = aceOutPrint(fo, "%.4f %.4f translate\n", -(ps.graph->ux), -(ps.graph->uy)) ; if (err != ESUCCESS) return err; for (i = 0 ; i < pages ; i++) { err = psDrawBox (&ps, arrp(ps.graph->boxes, 0, BoxStruct)); if (err != ESUCCESS) return err; err = aceOutPrint(fo, "\ngsave showpage grestore\n\n") ; if (err != ESUCCESS) return err; if (isRotate) err = aceOutPrint(fo, "%f 0 translate\n", -(ps.graph->aspect)*pageHeight/fac) ; else err = aceOutPrint(fo, "0 %f translate\n", -pageHeight/fac) ; if (err != ESUCCESS) return err; } err = aceOutPrint(fo, "grestore\n" "%%%%Trailer\n"); if (err != ESUCCESS) return err; return err; } /******** Public function *************/ /***** end of file *****/