00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <stdarg.h>
00014 #include <string.h>
00015 #include <math.h>
00016 #include <stdlib.h>
00017
00018 #include "potracelib.h"
00019 #include "curve.h"
00020 #include "main.h"
00021 #include "backend_eps.h"
00022 #include "flate.h"
00023 #include "lists.h"
00024 #include "auxiliary.h"
00025
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029
00030 #define SAFE_MALLOC(var, n, typ) \
00031 if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error
00032
00033 typedef int color_t;
00034
00035 #define black 0x000000
00036 #define red 0xff0000
00037 #define green 0x008000
00038 #define blue 0x0000ff
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 static int (*xship)(FILE *f, int filter, char *s, int len);
00050 static FILE *xship_file;
00051
00052
00053 static int ship(const char *fmt, ...) {
00054 va_list args;
00055 static char buf[4096];
00056
00057
00058
00059 va_start(args, fmt);
00060 vsprintf(buf, fmt, args);
00061 buf[4095] = 0;
00062 va_end(args);
00063
00064 xship(xship_file, 1, buf, strlen(buf));
00065 return 0;
00066 }
00067
00068
00069 static int shipcom(char *fmt, ...) {
00070 static char buf[4096];
00071 va_list args;
00072
00073 va_start(args, fmt);
00074 vsprintf(buf, fmt, args);
00075 buf[4095] = 0;
00076 va_end(args);
00077
00078 xship(xship_file, 0, buf, strlen(buf));
00079 return 0;
00080 }
00081
00082
00083 static void eps_callbacks(FILE *fout) {
00084 if (info.compress && info.pslevel==2) {
00085 xship = lzw_xship;
00086 } else if (info.compress && info.pslevel==3) {
00087 xship = flate_xship;
00088 } else {
00089 xship = dummy_xship;
00090 }
00091 xship_file = fout;
00092 }
00093
00094
00095
00096
00097
00098 static inline point_t unit(dpoint_t p) {
00099 point_t q;
00100
00101 q.x = (long)(floor(p.x*info.unit+.5));
00102 q.y = (long)(floor(p.y*info.unit+.5));
00103 return q;
00104 }
00105
00106
00107 static point_t cur;
00108
00109 static void eps_coords(dpoint_t p) {
00110 cur = unit(p);
00111 ship("%ld %ld ", cur.x, cur.y);
00112 }
00113
00114 static void eps_rcoords(dpoint_t p) {
00115 point_t q;
00116
00117 q = unit(p);
00118 ship("%ld %ld ", q.x-cur.x, q.y-cur.y);
00119 cur = q;
00120 }
00121
00122 static void eps_moveto(dpoint_t p) {
00123 eps_coords(p);
00124 ship("moveto\n");
00125 }
00126
00127
00128 static void eps_moveto_offs(dpoint_t p, double xoffs, double yoffs) {
00129
00130
00131 p.x += xoffs;
00132 p.y += yoffs;
00133 eps_coords(p);
00134 ship("moveto\n");
00135 }
00136
00137 static void eps_lineto(dpoint_t p) {
00138 eps_rcoords(p);
00139 ship("rlineto\n");
00140 }
00141
00142 static void eps_curveto(dpoint_t p1, dpoint_t p2, dpoint_t p3) {
00143 point_t q1, q2, q3;
00144
00145 q1 = unit(p1);
00146 q2 = unit(p2);
00147 q3 = unit(p3);
00148
00149 ship("%ld %ld %ld %ld %ld %ld rcurveto\n", q1.x-cur.x, q1.y-cur.y, q2.x-cur.x, q2.y-cur.y, q3.x-cur.x, q3.y-cur.y);
00150
00151 cur = q3;
00152 }
00153
00154
00155 static char *eps_colorstring(const color_t col) {
00156 double r, g, b;
00157 static char buf[100];
00158
00159 r = (col & 0xff0000) >> 16;
00160 g = (col & 0x00ff00) >> 8;
00161 b = (col & 0x0000ff) >> 0;
00162
00163 if (r==0 && g==0 && b==0) {
00164 return "0 setgray";
00165 } else if (r==255 && g==255 && b==255) {
00166 return "1 setgray";
00167 } else if (r == g && g == b) {
00168 sprintf(buf, "%.3f setgray", r/255.0);
00169 return buf;
00170 } else {
00171 sprintf(buf, "%.3f %.3f %.3f setrgbcolor", r/255.0, g/255.0, b/255.0);
00172 return buf;
00173 }
00174 }
00175
00176 static color_t eps_color = -1;
00177 static double eps_width = -1;
00178
00179 static void eps_setcolor(const color_t col) {
00180 if (col == eps_color) {
00181 return;
00182 }
00183 eps_color = col;
00184
00185 ship("%s\n", eps_colorstring(col));
00186 }
00187
00188 static void eps_linewidth(double w) {
00189 if (w == eps_width) {
00190 return;
00191 }
00192 eps_width = w;
00193 ship("%f setlinewidth\n", w * info.unit);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203 static int eps_path_long(privcurve_t *curve) {
00204 int i;
00205 dpoint_t *c;
00206 int m = curve->n;
00207
00208 c = curve->c[m-1];
00209 eps_moveto(c[2]);
00210
00211 for (i=0; i<m; i++) {
00212 c = curve->c[i];
00213 switch (curve->tag[i]) {
00214 case POTRACE_CORNER:
00215 eps_lineto(c[1]);
00216 eps_lineto(c[2]);
00217 break;
00218 case POTRACE_CURVETO:
00219 eps_curveto(c[0], c[1], c[2]);
00220 break;
00221 }
00222 }
00223 return 0;
00224 }
00225
00226
00227 static int eps_path_short(privcurve_t *curve) {
00228 int i, i1;
00229 long int *bq = NULL;
00230 long int *aq = NULL;
00231 point_t *v = NULL;
00232 dpoint_t *q = NULL;
00233 double M;
00234 int m = curve->n;
00235
00236 SAFE_MALLOC(bq, m, long int);
00237 SAFE_MALLOC(aq, m, long int);
00238 SAFE_MALLOC(v, m, point_t);
00239 SAFE_MALLOC(q, m, dpoint_t);
00240
00241
00242 for (i=0; i<m; i++) {
00243 v[i] = unit(curve->vertex[i]);
00244 }
00245
00246
00247 for (i=0; i<m; i++) {
00248 i1 = mod(i+1,m);
00249 M = max(10, max(abs(v[i1].x-v[i].x), abs(v[i1].y-v[i].y)));
00250 bq[i] = (int)(M * curve->beta[i] + 0.5);
00251 if (curve->beta[i] != 0.5) {
00252 q[i1] = interval(bq[i]/M, dpoint(v[i]), dpoint(v[i1]));
00253 } else {
00254 q[i1] = interval(0.5, dpoint(v[i]), dpoint(v[i1]));
00255 }
00256 }
00257
00258
00259 for (i=0; i<m; i++) {
00260 i1 = mod(i+1,m);
00261 M = max(10, max(max(abs(q[i].x-v[i].x), abs(q[i].y-v[i].y)),
00262 max(abs(v[i].x-q[i1].x), abs(v[i].y-q[i1].y))));
00263 if (curve->tag[i] == POTRACE_CURVETO) {
00264 aq[i] = (int)(M * curve->alpha[i] + 0.5);
00265 if (aq[i] > M) {
00266 aq[i]--;
00267 }
00268 }
00269 }
00270
00271
00272 ship("%ld %ld ", v[m-1].x, v[m-1].y);
00273 ship("%ld %ld ", v[0].x - v[m-1].x, v[0].y - v[m-1].y);
00274 if (curve->beta[m-1] == 0.5) {
00275 ship("i\n");
00276 } else {
00277 ship("%ld I\n", bq[m-1]);
00278 }
00279 for (i=0; i<m; i++) {
00280 if (i<m-1) {
00281 ship("%ld %ld ", v[i+1].x - v[i].x, v[i+1].y - v[i].y);
00282 if (curve->beta[i] != 0.5) {
00283 ship("%ld ", bq[i]);
00284 }
00285 }
00286 if (curve->tag[i] == POTRACE_CURVETO) {
00287 ship(curve->beta[i] == 0.5 ? "%ld c\n" : "%ld C\n", aq[i]);
00288 } else {
00289 ship(curve->beta[i] == 0.5 ? "v\n" : "V\n");
00290 }
00291 }
00292
00293 free(bq);
00294 free(aq);
00295 free(v);
00296 free(q);
00297 return 0;
00298
00299 malloc_error:
00300 free(bq);
00301 free(aq);
00302 free(v);
00303 free(q);
00304 return 1;
00305 }
00306
00307 static int eps_path(privcurve_t *curve) {
00308 if (info.longcoding==0 && curve->alphacurve) {
00309 return eps_path_short(curve);
00310 } else {
00311 return eps_path_long(curve);
00312 }
00313 }
00314
00315
00316
00317
00318
00319
00320 static void eps_jaggy(potrace_path_t *plist) {
00321 potrace_path_t *p;
00322 int i;
00323
00324 ship(".9 setgray\n");
00325 list_forall (p, plist) {
00326 point_t *pt = p->priv->pt;
00327 point_t cur, prev;
00328
00329 if (p->sign == '+') {
00330 cur = prev = pt[p->priv->len-1];
00331 eps_moveto(dpoint(cur));
00332 for (i=0; i<p->priv->len; i++) {
00333 if (pt[i].x != cur.x && pt[i].y != cur.y) {
00334 cur = prev;
00335 eps_lineto(dpoint(cur));
00336 }
00337 prev = pt[i];
00338 }
00339 eps_lineto(dpoint(pt[p->priv->len-1]));
00340 } else {
00341 cur = prev = pt[0];
00342 eps_moveto(dpoint(cur));
00343 for (i=p->priv->len-1; i>=0; i--) {
00344 if (pt[i].x != cur.x && pt[i].y != cur.y) {
00345 cur = prev;
00346 eps_lineto(dpoint(cur));
00347 }
00348 prev = pt[i];
00349 }
00350 eps_lineto(dpoint(pt[0]));
00351 }
00352 if (p->next == NULL || p->next->sign == '+') {
00353 ship("fill\n");
00354 }
00355 }
00356 }
00357
00358
00359 static void eps_polygon(privcurve_t *curve, const color_t col) {
00360 int i;
00361 int m = curve->n;
00362
00363 eps_linewidth(.02);
00364 eps_setcolor(col);
00365 eps_moveto(curve->vertex[m-1]);
00366 for (i=0; i<m; i++) {
00367 eps_lineto(curve->vertex[i]);
00368 }
00369 ship("stroke\n");
00370 }
00371
00372
00373 static void eps_L(privcurve_t *curve, const color_t col) {
00374 int i, i1;
00375 double gamma;
00376 dpoint_t p1, p4, p1l, p4l;
00377 int m = curve->n;
00378
00379 for (i=0; i<m; i++) {
00380 i1 = mod(i+1, m);
00381 gamma = curve->alpha0[i1] * 0.75;
00382
00383 p1 = curve->c[i][2];
00384 p4 = curve->c[i1][2];
00385 p1l = interval(gamma, p1, curve->vertex[i1]);
00386 p4l = interval(gamma, p4, curve->vertex[i1]);
00387 eps_linewidth(.02);
00388 eps_setcolor(col);
00389 eps_moveto(p1l);
00390 eps_lineto(p4l);
00391 ship("stroke\n");
00392 eps_moveto_offs(curve->vertex[i1], -.4, -.4);
00393 ship("times (%.2f) show\n", curve->alpha0[i1]);
00394 }
00395 }
00396
00397
00398
00399
00400
00401 static char *optimacros =
00402 "/D{bind def}def\n"
00403 "/R{roll}D\n"
00404 "/K{copy}D\n"
00405 "/P{pop}D\n"
00406 "/p{3 2 R add 3 1 R add exch}D\n"
00407 "/t{dup 4 3 R mul 3 1 R mul}D\n"
00408 "/a{dup 1 sub neg 4 1 R t 5 2 R t p}D\n"
00409 "/m{2 K le{exch}if P}D\n"
00410 "/n{abs exch abs m}D\n"
00411 "/d{-1 t p n}D\n"
00412 "/s{[4 2 R] cvx def}D\n"
00413 "/g{7 K P 4 K P P d 5 1 R d 10 m m div 5 K 12 8 R 5 4 R a 9 4 R 3 2 R a 6 4 R curveto}D\n"
00414 "/e{4 2 R lineto lineto P P}D\n"
00415 "/q{3 K P n 10 m div}D\n"
00416 "/f{x y 7 4 R 5 1 R 4 K p /y s 7 2 R 2 K 9 7 R 7 6 R t p 2 K /x s}D\n"
00417 "/C{4 1 R q f 7 6 R g}D\n"
00418 "/V{q f e}D\n"
00419 "/c{3 1 R .5 f 7 6 R g}D\n"
00420 "/v{.5 f e}D\n"
00421 "/j{5 K P p /y s 3 K t 7 5 R p /x s x moveto P}D\n"
00422 "/i{.5 j}D\n"
00423 "/I{dup 6 1 R q j 3 2 R}D\n"
00424 "/z{closepath}D\n"
00425 "/b{%s z fill}D\n"
00426 "/w{%s z fill}D\n";
00427
00428
00429 static char *debugmacros =
00430 "/unit { %f } def\n"
00431 "/box { newpath 0 0 moveto 0 1 lineto 1 1 lineto 1 0 lineto closepath } def\n"
00432 "/circ { newpath 0 0 1 0 360 arc closepath } def\n"
00433 "/dot { gsave .15 mul dup scale circ fill grestore } def\n"
00434 "/sq { gsave unit unit scale -.5 -.5 translate box .02 setlinewidth stroke grestore } def\n"
00435 "/sq1 { gsave translate sq unit .6 mul dot grestore } def\n"
00436 "/dot2 { gsave translate unit dot grestore } def\n"
00437 "/usq { gsave unit unit scale -.5 -.5 rmoveto 0 1 rlineto 1 0 rlineto 0 -1 rlineto closepath .02 setlinewidth stroke grestore } def\n"
00438 "/dot1 { gsave translate unit .3 mul dup scale circ fill grestore } def\n"
00439 "/times { /Times-Roman findfont unit .3 mul scalefont setfont } def\n"
00440 "/times1 { /Times-Roman findfont unit 10 mul scalefont setfont 0 0 0 setrgbcolor } def\n"
00441 "/times2 { /Times-Roman findfont unit 2 mul scalefont setfont 0 0 0 setrgbcolor } def\n";
00442
00443
00444
00445
00446
00447 static int render0(potrace_path_t *plist) {
00448 potrace_path_t *p;
00449
00450 if (info.longcoding) {
00451 eps_setcolor(info.color);
00452 list_forall (p, plist) {
00453 eps_path(p->priv->fcurve);
00454 ship("closepath\n");
00455 if (p->next == NULL || p->next->sign == '+') {
00456 ship("fill\n");
00457 }
00458 }
00459 } else {
00460 list_forall (p, plist) {
00461 eps_path(p->priv->fcurve);
00462 if (p->next == NULL || p->next->sign == '+') {
00463 ship("b\n");
00464 } else {
00465 ship("z\n");
00466 }
00467 }
00468 }
00469 return 0;
00470 }
00471
00472
00473 static int render0_opaque(potrace_path_t *plist) {
00474 potrace_path_t *p;
00475
00476 if (info.longcoding) {
00477 list_forall (p, plist) {
00478 eps_path(p->priv->fcurve);
00479 ship("closepath\n");
00480 eps_setcolor(p->sign=='+' ? info.color : info.fillcolor);
00481 ship("fill\n");
00482 }
00483 } else {
00484 list_forall (p, plist) {
00485 eps_path(p->priv->fcurve);
00486 ship(p->sign=='+' ? "b\n" : "w\n");
00487 }
00488 }
00489 return 0;
00490 }
00491
00492
00493 static int render1(potrace_path_t *plist) {
00494 potrace_path_t *p;
00495 int i;
00496
00497 eps_jaggy(plist);
00498
00499 list_forall (p, plist) {
00500
00501 point_t *pt = p->priv->pt;
00502 int n = p->priv->len;
00503 int m = p->priv->m;
00504 int *po = p->priv->po;
00505
00506 eps_linewidth(.02);
00507 eps_setcolor(black);
00508
00509 for (i=1; i<n; i++) {
00510 eps_moveto(dpoint(pt[i-1]));
00511 eps_lineto(dpoint(pt[i]));
00512 ship("stroke\n");
00513 eps_coords(dpoint(pt[i]));
00514 ship("sq1\n");
00515 }
00516 eps_moveto(dpoint(pt[n-1]));
00517 eps_lineto(dpoint(pt[0]));
00518 ship("stroke\n");
00519 eps_coords(dpoint(pt[0]));
00520 ship("sq1\n");
00521
00522
00523 eps_linewidth(.1);
00524 eps_setcolor(blue);
00525 eps_moveto(dpoint(pt[po[0]]));
00526 for (i=1; i<m; i++) {
00527 eps_lineto(dpoint(pt[po[i]]));
00528 }
00529 eps_lineto(dpoint(pt[po[0]]));
00530 ship("stroke\n");
00531 for (i=0; i<m; i++) {
00532 eps_coords(dpoint(pt[po[i]]));
00533 ship("dot2\n");
00534 }
00535 }
00536 return 0;
00537 }
00538
00539
00540 static int render2(potrace_path_t *plist) {
00541 potrace_path_t *p;
00542 int i;
00543
00544
00545 eps_jaggy(plist);
00546
00547 list_forall (p, plist) {
00548
00549 eps_polygon(&p->priv->curve, black);
00550 eps_L(&p->priv->curve, black);
00551
00552
00553 for (i=0; i<p->priv->curve.n; i++) {
00554 eps_moveto(p->priv->curve.vertex[i]);
00555 ship("usq\n");
00556 }
00557
00558
00559 eps_linewidth(.1);
00560 eps_setcolor(blue);
00561 eps_path(&p->priv->curve);
00562 ship("closepath\n");
00563 ship("stroke\n");
00564
00565 if (info.param->opticurve && info.debug == 3) {
00566
00567
00568 eps_linewidth(.05);
00569 eps_setcolor(red);
00570 eps_path(&p->priv->ocurve);
00571 ship("closepath\n");
00572 ship("stroke\n");
00573
00574
00575 for (i=0; i<p->priv->ocurve.n; i++) {
00576 eps_coords(p->priv->ocurve.c[i][2]);
00577 ship("dot1\n");
00578 }
00579 }
00580 }
00581 return 0;
00582 }
00583
00584
00585 static int render_debug(potrace_path_t *plist) {
00586 potrace_path_t *p;
00587 int count;
00588 int i;
00589
00590
00591 eps_jaggy(plist);
00592
00593 count = -1;
00594 list_forall (p, plist) {
00595 count++;
00596
00597
00598 eps_moveto_offs(p->priv->curve.vertex[0], 0, 5);
00599 ship("times1 (%d) show\n", count);
00600
00601
00602 eps_polygon(&p->priv->curve, black);
00603 eps_L(&p->priv->curve, black);
00604
00605
00606 for (i=0; i<p->priv->curve.n; i++) {
00607 eps_moveto(p->priv->curve.vertex[i]);
00608 ship("usq\n");
00609 }
00610
00611
00612 for (i=0; i<p->priv->curve.n; i++) {
00613 eps_moveto_offs(p->priv->curve.vertex[i], +1, +1);
00614 ship("times2 (%d) show\n", i);
00615 }
00616
00617
00618 eps_linewidth(.1);
00619 eps_setcolor(blue);
00620 eps_path(&p->priv->curve);
00621 ship("closepath\n");
00622 ship("stroke\n");
00623
00624 if (info.param->opticurve) {
00625
00626
00627 eps_polygon(&p->priv->ocurve, green);
00628
00629
00630 eps_linewidth(.05);
00631 eps_setcolor(red);
00632 eps_path(&p->priv->ocurve);
00633 ship("closepath\n");
00634 ship("stroke\n");
00635
00636
00637 for (i=0; i<p->priv->ocurve.n; i++) {
00638 eps_coords(p->priv->ocurve.c[i][2]);
00639 ship("dot1\n");
00640 }
00641
00642
00643 for (i=0; i<p->priv->ocurve.n; i++) {
00644 eps_moveto_offs(p->priv->ocurve.c[i][2], +.4, -.4);
00645 ship("times (%.2f) show\n", p->priv->ocurve.beta[i]);
00646 }
00647 }
00648 }
00649 return 0;
00650 }
00651
00652
00653 static int eps_render(potrace_path_t *plist) {
00654 int r;
00655
00656 switch (info.debug) {
00657 case 0:
00658 if (info.opaque) {
00659 r = render0_opaque(plist);
00660 } else {
00661 r = render0(plist);
00662 }
00663 break;
00664 case 1:
00665 r = render1(plist);
00666 break;
00667 case 2: case 3:
00668 r = render2(plist);
00669 break;
00670 default:
00671 r = render_debug(plist);
00672 break;
00673 }
00674 return r;
00675 }
00676
00677
00678
00679
00680 static int eps_init(imginfo_t *imginfo) {
00681 double origx = imginfo->trans.orig[0] + imginfo->lmar;
00682 double origy = imginfo->trans.orig[1] + imginfo->bmar;
00683 double scalex = imginfo->width / imginfo->pixwidth / info.unit;
00684 double scaley = imginfo->height / imginfo->pixheight / info.unit;
00685 char *c0, *c1;
00686
00687 shipcom("%%!PS-Adobe-3.0 EPSF-3.0\n");
00688 shipcom("%%%%Creator: "POTRACE" "VERSION", written by Peter Selinger 2001-2007\n");
00689 shipcom("%%%%LanguageLevel: %d\n", info.pslevel);
00690 shipcom("%%%%BoundingBox: 0 0 %d %d\n",
00691 (int)ceil(imginfo->trans.bb[0]+imginfo->lmar+imginfo->rmar),
00692 (int)ceil(imginfo->trans.bb[1]+imginfo->tmar+imginfo->bmar));
00693 shipcom("%%%%Pages: 1\n");
00694 shipcom("%%%%EndComments\n");
00695
00696 shipcom("%%%%Page: 1 1\n");
00697 if (!info.longcoding) {
00698 c0 = strdup(eps_colorstring(info.color));
00699 c1 = strdup(eps_colorstring(info.fillcolor));
00700 ship(optimacros, c0, c1);
00701 free(c0);
00702 free(c1);
00703 }
00704 if (info.debug) {
00705 ship(debugmacros, info.unit);
00706 }
00707 ship("gsave\n");
00708 if (origx != 0 || origy != 0) {
00709 ship("%.0f %.0f translate\n", origx, origy);
00710 }
00711 if (info.angle != 0) {
00712 ship("%.2f rotate\n", info.angle);
00713 }
00714 ship("%f %f scale\n", scalex, scaley);
00715
00716 return 0;
00717 }
00718
00719 static int eps_term(void) {
00720 ship("grestore\n");
00721 shipcom("%%%%EOF\n");
00722 return 0;
00723 }
00724
00725
00726 int page_eps(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
00727 int r;
00728
00729 eps_callbacks(fout);
00730
00731 eps_init(imginfo);
00732
00733 r = eps_render(plist);
00734 if (r) {
00735 return r;
00736 }
00737
00738 eps_term();
00739
00740 return 0;
00741 }
00742
00743
00744
00745
00746 static int eps_pagenumber;
00747
00748 int init_ps(FILE *fout) {
00749 char *c0, *c1;
00750
00751
00752 eps_callbacks(fout);
00753
00754 shipcom("%%!PS-Adobe-3.0\n");
00755 shipcom("%%%%Creator: "POTRACE" "VERSION", written by Peter Selinger 2001-2007\n");
00756 shipcom("%%%%LanguageLevel: %d\n", info.pslevel);
00757 shipcom("%%%%BoundingBox: 0 0 %d %d\n", info.paperwidth, info.paperheight);
00758 shipcom("%%%%Pages: (atend)\n");
00759 shipcom("%%%%EndComments\n");
00760 if (!info.longcoding || info.debug) {
00761 shipcom("%%%%BeginSetup\n");
00762 if (!info.longcoding) {
00763 c0 = strdup(eps_colorstring(info.color));
00764 c1 = strdup(eps_colorstring(info.fillcolor));
00765 ship(optimacros, c0, c1);
00766 free(c0);
00767 free(c1);
00768 }
00769 if (info.debug) {
00770 ship(debugmacros, info.unit);
00771 }
00772 shipcom("%%%%EndSetup\n");
00773 }
00774 eps_pagenumber = 0;
00775 fflush(fout);
00776 return 0;
00777 }
00778
00779 int term_ps(FILE *fout) {
00780 eps_callbacks(fout);
00781
00782 shipcom("%%%%Trailer\n");
00783 shipcom("%%%%Pages: %d\n", eps_pagenumber);
00784 shipcom("%%%%EOF\n");
00785 fflush(fout);
00786
00787 return 0;
00788 }
00789
00790 static void eps_pageinit_ps(imginfo_t *imginfo) {
00791 double origx = imginfo->trans.orig[0] + imginfo->lmar;
00792 double origy = imginfo->trans.orig[1] + imginfo->bmar;
00793 double scalex = imginfo->width / imginfo->pixwidth / info.unit;
00794 double scaley = imginfo->height / imginfo->pixheight / info.unit;
00795
00796 eps_pagenumber++;
00797 eps_color = -1;
00798 eps_width = -1;
00799
00800 shipcom("%%%%Page: %d %d\n", eps_pagenumber, eps_pagenumber);
00801 ship("gsave\n");
00802 if (origx != 0 || origy != 0) {
00803 ship("%.0f %.0f translate\n", origx, origy);
00804 }
00805 if (info.angle != 0) {
00806 ship("%.2f rotate\n", info.angle);
00807 }
00808 ship("%f %f scale\n", scalex, scaley);
00809 }
00810
00811 static void eps_pageterm_ps(void) {
00812 ship("grestore\n");
00813 ship("showpage\n");
00814 }
00815
00816 int page_ps(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
00817 int r;
00818
00819 eps_callbacks(fout);
00820
00821 eps_pageinit_ps(imginfo);
00822
00823 r = eps_render(plist);
00824 if (r) {
00825 return r;
00826 }
00827
00828 eps_pageterm_ps();
00829
00830 shipcom("");
00831
00832 fflush(fout);
00833
00834 return 0;
00835 }