File indexing completed on 2024-12-22 04:04:09
0001 /* Copyright (C) 2001-2019 Peter Selinger. 0002 This file is part of Potrace. It is free software and it is covered 0003 by the GNU General Public License. See the file COPYING for details. */ 0004 0005 0006 /* The PGM backend of Potrace. Here we custom-render a set of Bezier 0007 curves and output the result as a greymap. This is merely a 0008 convenience, as the same could be achieved by piping the EPS output 0009 through ghostscript. */ 0010 0011 #ifdef HAVE_CONFIG_H 0012 #include <config.h> 0013 #endif 0014 0015 #include <math.h> 0016 0017 #include "backend_pgm.h" 0018 #include "potracelib.h" 0019 #include "lists.h" 0020 #include "greymap.h" 0021 #include "render.h" 0022 #include "main.h" 0023 #include "auxiliary.h" 0024 #include "trans.h" 0025 0026 #ifndef M_PI 0027 #define M_PI 3.14159265358979323846 0028 #endif 0029 0030 static void pgm_path(potrace_curve_t *curve, trans_t t, render_t *rm) { 0031 dpoint_t *c, c1[3]; 0032 int i; 0033 int m = curve->n; 0034 0035 c = curve->c[m-1]; 0036 c1[2] = trans(c[2], t); 0037 render_moveto(rm, c1[2].x, c1[2].y); 0038 0039 for (i=0; i<m; i++) { 0040 c = curve->c[i]; 0041 switch (curve->tag[i]) { 0042 case POTRACE_CORNER: 0043 c1[1] = trans(c[1], t); 0044 c1[2] = trans(c[2], t); 0045 render_lineto(rm, c1[1].x, c1[1].y); 0046 render_lineto(rm, c1[2].x, c1[2].y); 0047 break; 0048 case POTRACE_CURVETO: 0049 c1[0] = trans(c[0], t); 0050 c1[1] = trans(c[1], t); 0051 c1[2] = trans(c[2], t); 0052 render_curveto(rm, c1[0].x, c1[0].y, c1[1].x, c1[1].y, c1[2].x, c1[2].y); 0053 break; 0054 } 0055 } 0056 } 0057 0058 int page_pgm(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) { 0059 potrace_path_t *p; 0060 greymap_t *gm; 0061 render_t *rm; 0062 int w, h; 0063 trans_t t; 0064 int mode; 0065 const char *comment = "created by " POTRACE " " VERSION ", written by Peter Selinger 2001-2019"; 0066 0067 t.bb[0] = imginfo->trans.bb[0]+imginfo->lmar+imginfo->rmar; 0068 t.bb[1] = imginfo->trans.bb[1]+imginfo->tmar+imginfo->bmar; 0069 t.orig[0] = imginfo->trans.orig[0]+imginfo->lmar; 0070 t.orig[1] = imginfo->trans.orig[1]+imginfo->bmar; 0071 t.x[0] = imginfo->trans.x[0]; 0072 t.x[1] = imginfo->trans.x[1]; 0073 t.y[0] = imginfo->trans.y[0]; 0074 t.y[1] = imginfo->trans.y[1]; 0075 0076 w = (int)ceil(t.bb[0]); 0077 h = (int)ceil(t.bb[1]); 0078 0079 gm = gm_new(w, h); 0080 if (!gm) { 0081 return 1; 0082 } 0083 rm = render_new(gm); 0084 if (!rm) { 0085 return 1; 0086 } 0087 0088 gm_clear(gm, 255); /* white */ 0089 0090 list_forall(p, plist) { 0091 pgm_path(&p->curve, t, rm); 0092 } 0093 0094 render_close(rm); 0095 0096 /* if negative orientation, make sure to invert effect of rendering */ 0097 mode = imginfo->width * imginfo->height < 0 ? GM_MODE_NEGATIVE : GM_MODE_POSITIVE; 0098 0099 gm_writepgm(fout, rm->gm, comment, 1, mode, info.gamma); 0100 0101 render_free(rm); 0102 gm_free(gm); 0103 0104 return 0; 0105 } 0106