00001
00002
00003
00004
00005
00006 #include "common.h"
00007 #include "psPoly.h"
00008 #include "psGfx.h"
00009 #include "linefile.h"
00010
00011 static char const rcsid[] = "$Id: psGfx.c,v 1.30 2007/04/15 00:29:47 galt Exp $";
00012
00013 static void psFloatOut(FILE *f, double x)
00014
00015
00016 {
00017 int i = round(x);
00018 if (i == x)
00019 fprintf(f, "%d ", i);
00020 else
00021 fprintf(f, "%0.4f ", x);
00022 }
00023
00024 void psClipRect(struct psGfx *ps, double x, double y,
00025 double width, double height)
00026
00027 {
00028 FILE *f = ps->f;
00029 fprintf(f, "cliprestore ");
00030 psXyOut(ps, x, y+height);
00031 psWhOut(ps, width, height);
00032 fprintf(f, "rectclip\n");
00033 }
00034
00035 static void psWriteHeader(FILE *f, double width, double height)
00036
00037
00038
00039 {
00040 char *s =
00041 #include "common.pss"
00042 ;
00043
00044 fprintf(f, "%%!PS-Adobe-3.1 EPSF-3.0\n");
00045 fprintf(f, "%%%%BoundingBox: 0 0 %d %d\n\n", (int)ceil(width), (int)ceil(height));
00046 fprintf(f, "%s", s);
00047 }
00048
00049 struct psGfx *psOpen(char *fileName,
00050 double userWidth, double userHeight,
00051 double ptWidth, double ptHeight,
00052 double ptMargin)
00053
00054
00055 {
00056 struct psGfx *ps;
00057
00058
00059 AllocVar(ps);
00060 ps->f = mustOpen(fileName, "w");
00061
00062
00063 ps->userWidth = userWidth;
00064 ps->userHeight = userHeight;
00065 ps->ptWidth = ptWidth;
00066 ps->xScale = (ptWidth - 2*ptMargin)/userWidth;
00067 if (ptHeight != 0.0)
00068 {
00069 ps->ptHeight = ptHeight;
00070 ps->yScale = (ptHeight - 2*ptMargin) / userHeight;
00071 }
00072 else
00073 {
00074 ps->yScale = ps->xScale;
00075 ptHeight = ps->ptHeight = userHeight * ps->yScale + 2*ptMargin;
00076 }
00077
00078 ps->xOff = ptMargin;
00079 ps->yOff = ptMargin;
00080 ps->fontHeight = 10;
00081
00082
00083
00084 ps->yScale = -ps->yScale;
00085 ps->yOff = ps->ptHeight - ps->yOff;
00086
00087 psWriteHeader(ps->f, ptWidth, ptHeight);
00088
00089
00090 psClipRect(ps, 0, 0, ps->userWidth, ps->userHeight);
00091
00092
00093 fprintf(ps->f, "%f setlinewidth\n", ps->xScale);
00094
00095 return ps;
00096 }
00097
00098 void psTranslate(struct psGfx *ps, double xTrans, double yTrans)
00099
00100 {
00101 ps->xOff += xTrans*ps->xScale;
00102 ps->yOff += yTrans*ps->yScale;
00103 }
00104
00105 void psClose(struct psGfx **pPs)
00106
00107 {
00108 struct psGfx *ps = *pPs;
00109 if (ps != NULL)
00110 {
00111 carefulClose(&ps->f);
00112 freez(pPs);
00113 }
00114 }
00115
00116 void psXyOut(struct psGfx *ps, double x, double y)
00117
00118 {
00119 FILE *f = ps->f;
00120 psFloatOut(f, x * ps->xScale + ps->xOff);
00121 psFloatOut(f, y * ps->yScale + ps->yOff);
00122 }
00123
00124 void psWhOut(struct psGfx *ps, double width, double height)
00125
00126 {
00127 FILE *f = ps->f;
00128 psFloatOut(f, width * ps->xScale);
00129 psFloatOut(f, height * -ps->yScale);
00130 }
00131
00132 void psMoveTo(struct psGfx *ps, double x, double y)
00133
00134 {
00135 psXyOut(ps, x, y);
00136 fprintf(ps->f, "moveto\n");
00137 }
00138
00139 void psLineTo(struct psGfx *ps, double x, double y)
00140
00141
00142 {
00143 psXyOut(ps, x, y);
00144 fprintf(ps->f, "lineto\n");
00145 }
00146
00147 void psDrawBox(struct psGfx *ps, double x, double y,
00148 double width, double height)
00149
00150 {
00151 if (width > 0 && height > 0)
00152 {
00153 psWhOut(ps, width, height);
00154 psXyOut(ps, x, y+height);
00155 fprintf(ps->f, "fillBox\n");
00156 }
00157 }
00158
00159 void psDrawLine(struct psGfx *ps, double x1, double y1, double x2, double y2)
00160
00161 {
00162 FILE *f = ps->f;
00163 fprintf(f, "newpath\n");
00164 psMoveTo(ps, x1, y1);
00165 psXyOut(ps, x2, y2);
00166 fprintf(ps->f, "lineto\n");
00167 fprintf(f, "stroke\n");
00168 }
00169
00170 void psFillUnder(struct psGfx *ps, double x1, double y1,
00171 double x2, double y2, double bottom)
00172
00173
00174
00175
00176 {
00177 FILE *f = ps->f;
00178 fprintf(f, "newpath\n");
00179 psMoveTo(ps, x1, y1);
00180 psLineTo(ps, x2, y2);
00181 psLineTo(ps, x2, bottom);
00182 psLineTo(ps, x1, bottom);
00183 fprintf(f, "closepath\n");
00184 fprintf(f, "fill\n");
00185 }
00186
00187 void psTimesFont(struct psGfx *ps, double size)
00188
00189 {
00190 FILE *f = ps->f;
00191 fprintf(f, "/Helvetica findfont ");
00192
00193
00194
00195
00196 fprintf(f, "%f scalefont setfont\n", -size*ps->yScale*1.2);
00197 ps->fontHeight = size*0.8;
00198 }
00199
00200
00201 void psTextAt(struct psGfx *ps, double x, double y, char *text)
00202
00203 {
00204 char c;
00205 psMoveTo(ps, x, y + ps->fontHeight);
00206 fprintf(ps->f, "(");
00207 while ((c = *text++) != 0)
00208 {
00209 if (c == ')' || c == '(')
00210 fprintf(ps->f, "\\");
00211 fprintf(ps->f, "%c", c);
00212 }
00213 fprintf(ps->f, ") show\n");
00214 }
00215
00216 void psTextRight(struct psGfx *ps, double x, double y,
00217 double width, double height,
00218 char *text)
00219
00220 {
00221 y += (height - ps->fontHeight)/2;
00222 psMoveTo(ps, x+width, y + ps->fontHeight);
00223 fprintf(ps->f, "(%s) showBefore\n", text);
00224 }
00225
00226 void psTextCentered(struct psGfx *ps, double x, double y,
00227 double width, double height,
00228 char *text)
00229
00230 {
00231 char c;
00232 y += (height - ps->fontHeight)/2;
00233 psMoveTo(ps, x+width/2, y + ps->fontHeight);
00234 fprintf(ps->f, "(");
00235 while ((c = *text++) != 0)
00236 {
00237 if (c == ')' || c == '(')
00238 fprintf(ps->f, "\\");
00239 fprintf(ps->f, "%c", c);
00240 }
00241 fprintf(ps->f, ") showMiddle\n");
00242 }
00243
00244 void psTextDown(struct psGfx *ps, double x, double y, char *text)
00245
00246 {
00247 psMoveTo(ps, x, y);
00248 fprintf(ps->f, "gsave\n");
00249 fprintf(ps->f, "-90 rotate\n");
00250 fprintf(ps->f, "(%s) show\n", text);
00251 fprintf(ps->f, "grestore\n");
00252 }
00253
00254 void psSetColor(struct psGfx *ps, int r, int g, int b)
00255
00256 {
00257 FILE *f = ps->f;
00258 double scale = 1.0/255;
00259 if (r == g && g == b)
00260 {
00261 psFloatOut(f, scale * r);
00262 fprintf(f, "setgray\n");
00263 }
00264 else
00265 {
00266 psFloatOut(f, scale * r);
00267 psFloatOut(f, scale * g);
00268 psFloatOut(f, scale * b);
00269 fprintf(f, "setrgbcolor\n");
00270 }
00271 }
00272
00273 void psSetGray(struct psGfx *ps, double grayVal)
00274
00275 {
00276 FILE *f = ps->f;
00277 if (grayVal < 0) grayVal = 0;
00278 if (grayVal > 1) grayVal = 1;
00279 psFloatOut(f, grayVal);
00280 fprintf(f, "setgray\n");
00281 }
00282
00283 void psPushG(struct psGfx *ps)
00284
00285 {
00286 fprintf(ps->f, "gsave\n");
00287 }
00288
00289 void psPopG(struct psGfx *ps)
00290
00291 {
00292 fprintf(ps->f, "grestore\n");
00293 }
00294
00295 void psDrawPoly(struct psGfx *ps, struct psPoly *poly, boolean filled)
00296
00297 {
00298 FILE *f = ps->f;
00299 struct psPoint *p = poly->ptList;
00300 fprintf(f, "newpath\n");
00301 psMoveTo(ps, p->x, p->y);
00302 for (;;)
00303 {
00304 p = p->next;
00305 psLineTo(ps, p->x, p->y);
00306 if (p == poly->ptList)
00307 break;
00308 }
00309 if (filled)
00310 {
00311 fprintf(f, "fill\n");
00312 }
00313 else
00314 {
00315 fprintf(f, "closepath\n");
00316 fprintf(f, "stroke\n");
00317 }
00318 }
00319
00320
00321 void psFillEllipse(struct psGfx *ps, double x, double y, double xrad, double yrad)
00322 {
00323 FILE *f = ps->f;
00324 fprintf(f, "newpath\n");
00325 psXyOut(ps, x, y);
00326 psWhOut(ps, xrad, yrad);
00327 fprintf(f, "%d %d ellipse\n", 0, 360);
00328 fprintf(f, "closepath\n");
00329 fprintf(f, "fill\n");
00330 }
00331
00332 void psDrawEllipse(struct psGfx *ps, double x, double y, double xrad, double yrad,
00333 double startAngle, double endAngle)
00334 {
00335 FILE *f = ps->f;
00336 fprintf(f, "newpath\n");
00337 psXyOut(ps, x, y);
00338 psWhOut(ps, xrad, yrad);
00339 psFloatOut(f, startAngle);
00340 psFloatOut(f, endAngle);
00341 fprintf(f, "ellipse\n");
00342 fprintf(f, "closepath\n");
00343 fprintf(f, "stroke\n");
00344 }
00345
00346 char * convertEpsToPdf(char *epsFile)
00347
00348 {
00349 char *pdfTmpName = NULL, *pdfName=NULL;
00350 char cmdBuffer[2048];
00351 int sysVal = 0;
00352 struct lineFile *lf = NULL;
00353 char *line;
00354 int lineSize=0;
00355 float width=0, height=0;
00356 pdfTmpName = cloneString(epsFile);
00357
00358
00359 lf = lineFileOpen(epsFile, TRUE);
00360 while(lineFileNext(lf, &line, &lineSize))
00361 {
00362 if(strstr( line, "BoundingBox:"))
00363 {
00364 char *words[5];
00365 chopLine(line, words);
00366 width = atof(words[3]);
00367 height = atof(words[4]);
00368 break;
00369 }
00370 }
00371 lineFileClose(&lf);
00372
00373
00374 chopSuffix(pdfTmpName);
00375 pdfName = addSuffix(pdfTmpName, ".pdf");
00376 safef(cmdBuffer, sizeof(cmdBuffer), "ps2pdf -dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d %s %s",
00377 round(width), round(height), epsFile, pdfName);
00378 sysVal = system(cmdBuffer);
00379 if(sysVal != 0)
00380 freez(&pdfName);
00381 freez(&pdfTmpName);
00382 return pdfName;
00383 }
00384