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