xref: /potrace-1.14/src/backend_pgm.c (revision b3fce824)
1 /* Copyright (C) 2001-2017 Peter Selinger.
2    This file is part of Potrace. It is free software and it is covered
3    by the GNU General Public License. See the file COPYING for details. */
4 
5 
6 /* The PGM backend of Potrace. Here we custom-render a set of Bezier
7    curves and output the result as a greymap. This is merely a
8    convenience, as the same could be achieved by piping the EPS output
9    through ghostscript. */
10 
11 #ifdef HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 
15 #include <math.h>
16 
17 #include "backend_pgm.h"
18 #include "potracelib.h"
19 #include "lists.h"
20 #include "greymap.h"
21 #include "render.h"
22 #include "main.h"
23 #include "auxiliary.h"
24 #include "trans.h"
25 
26 #ifndef M_PI
27 #define M_PI 3.14159265358979323846
28 #endif
29 
pgm_path(potrace_curve_t * curve,trans_t t,render_t * rm)30 static void pgm_path(potrace_curve_t *curve, trans_t t, render_t *rm) {
31   dpoint_t *c, c1[3];
32   int i;
33   int m = curve->n;
34 
35   c = curve->c[m-1];
36   c1[2] = trans(c[2], t);
37   render_moveto(rm, c1[2].x, c1[2].y);
38 
39   for (i=0; i<m; i++) {
40     c = curve->c[i];
41     switch (curve->tag[i]) {
42     case POTRACE_CORNER:
43       c1[1] = trans(c[1], t);
44       c1[2] = trans(c[2], t);
45       render_lineto(rm, c1[1].x, c1[1].y);
46       render_lineto(rm, c1[2].x, c1[2].y);
47       break;
48     case POTRACE_CURVETO:
49       c1[0] = trans(c[0], t);
50       c1[1] = trans(c[1], t);
51       c1[2] = trans(c[2], t);
52       render_curveto(rm, c1[0].x, c1[0].y, c1[1].x, c1[1].y, c1[2].x, c1[2].y);
53       break;
54     }
55   }
56 }
57 
page_pgm(FILE * fout,potrace_path_t * plist,imginfo_t * imginfo)58 int page_pgm(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
59   potrace_path_t *p;
60   greymap_t *gm;
61   render_t *rm;
62   int w, h;
63   trans_t t;
64   int mode;
65   const char *comment = "created by " POTRACE " " VERSION ", written by Peter Selinger 2001-2017";
66 
67   t.bb[0] = imginfo->trans.bb[0]+imginfo->lmar+imginfo->rmar;
68   t.bb[1] = imginfo->trans.bb[1]+imginfo->tmar+imginfo->bmar;
69   t.orig[0] = imginfo->trans.orig[0]+imginfo->lmar;
70   t.orig[1] = imginfo->trans.orig[1]+imginfo->bmar;
71   t.x[0] = imginfo->trans.x[0];
72   t.x[1] = imginfo->trans.x[1];
73   t.y[0] = imginfo->trans.y[0];
74   t.y[1] = imginfo->trans.y[1];
75 
76   w = (int)ceil(t.bb[0]);
77   h = (int)ceil(t.bb[1]);
78 
79   gm = gm_new(w, h);
80   if (!gm) {
81     return 1;
82   }
83   rm = render_new(gm);
84   if (!rm) {
85     return 1;
86   }
87 
88   gm_clear(gm, 255); /* white */
89 
90   list_forall(p, plist) {
91     pgm_path(&p->curve, t, rm);
92   }
93 
94   render_close(rm);
95 
96   /* if negative orientation, make sure to invert effect of rendering */
97   mode = imginfo->width * imginfo->height < 0 ? GM_MODE_NEGATIVE : GM_MODE_POSITIVE;
98 
99   gm_writepgm(fout, rm->gm, comment, 1, mode, info.gamma);
100 
101   render_free(rm);
102   gm_free(gm);
103 
104   return 0;
105 }
106 
107