00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdarg.h>
00011 #include <string.h>
00012 #include <math.h>
00013
00014 #include "main.h"
00015 #include "backend_xfig.h"
00016 #include "potracelib.h"
00017 #include "lists.h"
00018 #include "auxiliary.h"
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023
00024 #ifndef M_PI
00025 #define M_PI 3.14159265358979323846
00026 #endif
00027
00028 struct pageformat_s {
00029 char *name;
00030 int w, h;
00031 };
00032 typedef struct pageformat_s pageformat_t;
00033
00034
00035 static pageformat_t pageformat[] = {
00036 { "A9", 105, 149 },
00037 { "A8", 149, 211 },
00038 { "A7", 211, 298 },
00039 { "A6", 298, 421 },
00040 { "A5", 421, 595 },
00041 { "A4", 595, 842 },
00042 { "A3", 842, 1191 },
00043 { "A2", 1191, 1685 },
00044 { "A1", 1685, 2383 },
00045 { "A0", 2383, 3370 },
00046
00047 { "B10", 91, 129 },
00048 { "B9", 129, 182 },
00049 { "B8", 182, 258 },
00050 { "B7", 258, 365 },
00051 { "B6", 365, 516 },
00052 { "B5", 516, 730 },
00053 { "B4", 730, 1032 },
00054 { "B3", 1032, 1460 },
00055 { "B2", 1460, 2064 },
00056 { "B1", 2064, 2920 },
00057 { "B0", 2920, 4127 },
00058
00059 { "Letter", 612, 792 },
00060 { "Legal", 612, 1008 },
00061 { "Tabloid", 792, 1224 },
00062 { "A", 612, 792 },
00063 { "B", 792, 1224 },
00064 { "C", 1224, 1584 },
00065 { "D", 1584, 2448 },
00066 { "E", 2448, 3168 },
00067
00068 { NULL, 0, 0 },
00069 };
00070
00071
00072
00073
00074
00075 struct trans_s {
00076 double ox, oy;
00077 double dxx, dxy, dyx, dyy;
00078 };
00079 typedef struct trans_s trans_t;
00080
00081 static inline dpoint_t trans(dpoint_t p, trans_t t) {
00082 dpoint_t res;
00083
00084 res.x = t.ox + p.x * t.dxx + p.y * t.dyx;
00085 res.y = t.oy + p.x * t.dxy + p.y * t.dyy;
00086 return res;
00087 }
00088
00089
00090 static inline point_t unit(dpoint_t p) {
00091 point_t q;
00092
00093 q.x = (long)(floor(p.x+.5));
00094 q.y = (long)(floor(p.y+.5));
00095 return q;
00096 }
00097
00098 static void xfig_point(FILE *fout, dpoint_t p, trans_t t) {
00099 point_t q;
00100
00101 q = unit(trans(p, t));
00102
00103 fprintf(fout, "%ld %ld\n", q.x, q.y);
00104 }
00105
00106
00107
00108
00109
00110 static int npoints(potrace_curve_t *curve, int m) {
00111 int i;
00112 int n=0;
00113
00114 for (i=0; i<m; i++) {
00115 switch (curve->tag[i]) {
00116 case POTRACE_CORNER:
00117 n += 1;
00118 break;
00119 case POTRACE_CURVETO:
00120 n += 2;
00121 break;
00122 }
00123 }
00124 return n;
00125 }
00126
00127
00128 static int xfig_path(FILE *fout, potrace_curve_t *curve, trans_t t, int sign) {
00129 int i;
00130 dpoint_t *c;
00131 int m = curve->n;
00132
00133 fprintf(fout, "3 1 0 0 0 %d 50 0 20 0.000 0 0 0 %d\n", sign=='+' ? 32 : 33, npoints(curve, m));
00134
00135 for (i=0; i<m; i++) {
00136 c = curve->c[i];
00137 switch (curve->tag[i]) {
00138 case POTRACE_CORNER:
00139 xfig_point(fout, c[1], t);
00140 break;
00141 case POTRACE_CURVETO:
00142 xfig_point(fout, c[0], t);
00143 xfig_point(fout, c[1], t);
00144 break;
00145 }
00146 }
00147 for (i=0; i<m; i++) {
00148 switch (curve->tag[i]) {
00149 case POTRACE_CORNER:
00150 fprintf(fout, "0\n");
00151 break;
00152 case POTRACE_CURVETO:
00153 fprintf(fout, "1 1\n");
00154 break;
00155 }
00156 }
00157 return 0;
00158 }
00159
00160
00161
00162
00163
00164 int page_xfig(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
00165 potrace_path_t *p;
00166 trans_t t;
00167 double si, co;
00168 double origx = imginfo->trans.orig[0] + imginfo->lmar;
00169 double origy = - imginfo->trans.orig[1] - imginfo->bmar + info.paperheight;
00170 double scalex = imginfo->width / imginfo->pixwidth;
00171 double scaley = imginfo->height / imginfo->pixheight;
00172 char *formatname;
00173 int best, penalty;
00174 pageformat_t *f;
00175 int i;
00176 int x0, y0, x1, y1;
00177
00178 si = sin(info.angle/180*M_PI);
00179 co = cos(info.angle/180*M_PI);
00180
00181 t.ox = 1200/72.0 * origx;
00182 t.oy = 1200/72.0 * origy;
00183 t.dxx = 1200/72.0 * scalex * co;
00184 t.dxy = 1200/72.0 * scalex * -si;
00185 t.dyx = 1200/72.0 * scaley * -si;
00186 t.dyy = 1200/72.0 * scaley * -co;
00187
00188 x0 = (int)(1200/72.0 * (origx - imginfo->trans.orig[0]));
00189 y0 = (int)(1200/72.0 * (origy + imginfo->trans.orig[1]));
00190 x1 = x0 + (int)(1200/72.0 * imginfo->trans.bb[0]);
00191 y1 = y0 - (int)(1200/72.0 * imginfo->trans.bb[1]);
00192
00193 best = -1;
00194 formatname = "Letter";
00195
00196
00197 for (i=0; pageformat[i].name; i++) {
00198 f = &pageformat[i];
00199 if (f->w >= info.paperwidth-1 && f->h >= info.paperheight-1) {
00200 penalty = f->w + f->h;
00201 if (best == -1 || penalty < best) {
00202 best = penalty;
00203 formatname = f->name;
00204 }
00205 }
00206 }
00207
00208
00209 fprintf(fout, "#FIG 3.2\n");
00210 fprintf(fout, "#created by "POTRACE" "VERSION", written by Peter Selinger 2001-2007\n");
00211 fprintf(fout, "Portrait\n");
00212 fprintf(fout, "Center\n");
00213 fprintf(fout, "Inches\n");
00214 fprintf(fout, "%s\n", formatname);
00215 fprintf(fout, "100.0\n");
00216 fprintf(fout, "Single\n");
00217 fprintf(fout, "-2\n");
00218 fprintf(fout, "1200 2\n");
00219 fprintf(fout, "0 32 #%06x\n", info.color);
00220 fprintf(fout, "0 33 #%06x\n", info.fillcolor);
00221 fprintf(fout, "6 %d %d %d %d\n", x0-75, y1-35, x1+75, y0+35);
00222
00223
00224
00225 list_forall (p, plist) {
00226 xfig_path(fout, &p->curve, t, p->sign);
00227 }
00228
00229 fprintf(fout, "-6\n");
00230
00231 fflush(fout);
00232
00233 return 0;
00234 }