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