summaryrefslogtreecommitdiff
path: root/Build/source/libs/potrace/potrace-src/src/backend_xfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/potrace/potrace-src/src/backend_xfig.c')
-rw-r--r--Build/source/libs/potrace/potrace-src/src/backend_xfig.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/Build/source/libs/potrace/potrace-src/src/backend_xfig.c b/Build/source/libs/potrace/potrace-src/src/backend_xfig.c
new file mode 100644
index 00000000000..a4d2947229b
--- /dev/null
+++ b/Build/source/libs/potrace/potrace-src/src/backend_xfig.c
@@ -0,0 +1,252 @@
+/* Copyright (C) 2001-2015 Peter Selinger.
+ This file is part of Potrace. It is free software and it is covered
+ by the GNU General Public License. See the file COPYING for details. */
+
+
+/* The xfig backend of Potrace. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+
+#include "main.h"
+#include "backend_xfig.h"
+#include "potracelib.h"
+#include "lists.h"
+#include "auxiliary.h"
+#include "trans.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+struct pageformat_s {
+ char *name;
+ int w, h;
+};
+typedef struct pageformat_s pageformat_t;
+
+/* page formats known by xfig, and their dimensions in postscript points */
+static pageformat_t pageformat[] = {
+ { "A9", 105, 149 },
+ { "A8", 149, 211 },
+ { "A7", 211, 298 },
+ { "A6", 298, 421 },
+ { "A5", 421, 595 },
+ { "A4", 595, 842 },
+ { "A3", 842, 1191 },
+ { "A2", 1191, 1685 },
+ { "A1", 1685, 2383 },
+ { "A0", 2383, 3370 },
+
+ { "B10", 91, 129 },
+ { "B9", 129, 182 },
+ { "B8", 182, 258 },
+ { "B7", 258, 365 },
+ { "B6", 365, 516 },
+ { "B5", 516, 730 },
+ { "B4", 730, 1032 },
+ { "B3", 1032, 1460 },
+ { "B2", 1460, 2064 },
+ { "B1", 2064, 2920 },
+ { "B0", 2920, 4127 },
+
+ { "Letter", 612, 792 },
+ { "Legal", 612, 1008 },
+ { "Tabloid", 792, 1224 },
+ { "A", 612, 792 },
+ { "B", 792, 1224 },
+ { "C", 1224, 1584 },
+ { "D", 1584, 2448 },
+ { "E", 2448, 3168 },
+
+ { NULL, 0, 0 },
+};
+
+/* ---------------------------------------------------------------------- */
+/* path-drawing auxiliary functions */
+
+/* coordinate quantization */
+static inline point_t unit(dpoint_t p) {
+ point_t q;
+
+ q.x = (long)(floor(p.x+.5));
+ q.y = (long)(floor(p.y+.5));
+ return q;
+}
+
+static void xfig_point(FILE *fout, dpoint_t p, trans_t t) {
+ point_t q;
+
+ q = unit(trans(p, t));
+
+ fprintf(fout, "%ld %ld\n", q.x, q.y);
+}
+
+/* ---------------------------------------------------------------------- */
+/* functions for converting a path to a xfig */
+
+/* calculate number of xfig control points in this path */
+static int npoints(potrace_curve_t *curve, int m) {
+ int i;
+ int n=0;
+
+ for (i=0; i<m; i++) {
+ switch (curve->tag[i]) {
+ case POTRACE_CORNER:
+ n += 1;
+ break;
+ case POTRACE_CURVETO:
+ n += 2;
+ break;
+ }
+ }
+ return n;
+}
+
+/* do one path. */
+static void xfig_path(FILE *fout, potrace_curve_t *curve, trans_t t, int sign, int depth) {
+ int i;
+ dpoint_t *c;
+ int m = curve->n;
+
+ fprintf(fout, "3 1 0 0 0 %d %d 0 20 0.000 0 0 0 %d\n", sign=='+' ? 32 : 33, depth, npoints(curve, m));
+
+ for (i=0; i<m; i++) {
+ c = curve->c[i];
+ switch (curve->tag[i]) {
+ case POTRACE_CORNER:
+ xfig_point(fout, c[1], t);
+ break;
+ case POTRACE_CURVETO:
+ xfig_point(fout, c[0], t);
+ xfig_point(fout, c[1], t);
+ break;
+ }
+ }
+ for (i=0; i<m; i++) {
+ switch (curve->tag[i]) {
+ case POTRACE_CORNER:
+ fprintf(fout, "0\n");
+ break;
+ case POTRACE_CURVETO:
+ fprintf(fout, "1 1\n");
+ break;
+ }
+ }
+}
+
+/* render a whole tree */
+static void xfig_write_paths(FILE *fout, potrace_path_t *plist, trans_t t, int depth) {
+ potrace_path_t *p, *q;
+
+ for (p=plist; p; p=p->sibling) {
+ xfig_path(fout, &p->curve, t, p->sign, depth);
+ for (q=p->childlist; q; q=q->sibling) {
+ xfig_path(fout, &q->curve, t, q->sign, depth >= 1 ? depth-1 : 0);
+ }
+ for (q=p->childlist; q; q=q->sibling) {
+ xfig_write_paths(fout, q->childlist, t, depth >= 2 ? depth-2 : 0);
+ }
+ }
+}
+
+/* calculate the depth of a tree. Call with d=0. */
+static int xfig_get_depth(potrace_path_t *plist) {
+ potrace_path_t *p;
+ int max =0;
+ int d;
+
+ for (p=plist; p; p=p->sibling) {
+ d = xfig_get_depth(p->childlist);
+ if (d > max) {
+ max = d;
+ }
+ }
+ return max + 1;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Backend. */
+
+/* public interface for XFIG */
+int page_xfig(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
+ trans_t t;
+ double origx = imginfo->trans.orig[0] + imginfo->lmar;
+ double origy = - imginfo->trans.orig[1] - imginfo->bmar + info.paperheight;
+ char *formatname;
+ int best, penalty;
+ pageformat_t *f;
+ int i;
+ int x0, y0, x1, y1; /* in xfig's coordinates */
+ int depth;
+
+ t.orig[0] = 1200/72.0 * origx;
+ t.orig[1] = 1200/72.0 * origy;
+ t.x[0] = 1200/72.0 * imginfo->trans.x[0];
+ t.x[1] = -1200/72.0 * imginfo->trans.x[1];
+ t.y[0] = 1200/72.0 * imginfo->trans.y[0];
+ t.y[1] = -1200/72.0 * imginfo->trans.y[1];
+
+ x0 = (int)(1200/72.0 * (origx - imginfo->trans.orig[0]));
+ y0 = (int)(1200/72.0 * (origy + imginfo->trans.orig[1]));
+ x1 = x0 + (int)(1200/72.0 * imginfo->trans.bb[0]);
+ y1 = y0 - (int)(1200/72.0 * imginfo->trans.bb[1]);
+
+ best = -1;
+ formatname = "Letter";
+
+ /* find closest page format */
+ for (i=0; pageformat[i].name; i++) {
+ f = &pageformat[i];
+ if (f->w >= info.paperwidth-1 && f->h >= info.paperheight-1) {
+ penalty = f->w + f->h;
+ if (best == -1 || penalty < best) {
+ best = penalty;
+ formatname = f->name;
+ }
+ }
+ }
+
+ /* header */
+ fprintf(fout, "#FIG 3.2\n");
+ fprintf(fout, "#created by "POTRACE" "VERSION", written by Peter Selinger 2001-2015\n");
+ fprintf(fout, "Portrait\n");
+ fprintf(fout, "Center\n");
+ fprintf(fout, "Inches\n");
+ fprintf(fout, "%s\n", formatname);
+ fprintf(fout, "100.0\n");
+ fprintf(fout, "Single\n");
+ fprintf(fout, "-2\n");
+ fprintf(fout, "1200 2\n"); /* 1200 pixels per inch */
+ fprintf(fout, "0 32 #%06x\n", info.color);
+ fprintf(fout, "0 33 #%06x\n", info.fillcolor);
+ fprintf(fout, "6 %d %d %d %d\n", x0-75, y1-35, x1+75, y0+35); /* bounding box */
+
+ /* determine depth of the tree */
+ depth = xfig_get_depth(plist);
+
+ /* figure out appropriate xfig starting depth. Note: xfig only has 1000 depths available */
+ if (depth <= 40) {
+ depth = 50;
+ } else if (depth < 990) {
+ depth += 10;
+ } else {
+ depth = 999;
+ }
+
+ /* write paths. Note: can never use "opticurve" with this backend -
+ it just does not approximate Bezier curves closely enough. */
+ xfig_write_paths(fout, plist, t, depth);
+
+ fprintf(fout, "-6\n"); /* end bounding box */
+
+ fflush(fout);
+
+ return 0;
+}