backend_xfig.c
Go to the documentation of this file.
00001 /* Copyright (C) 2001-2007 Peter Selinger.
00002    This file is part of Potrace. It is free software and it is covered
00003    by the GNU General Public License. See the file COPYING for details. */
00004 
00005 /* $Id: backend_xfig.c 147 2007-04-09 00:44:09Z selinger $ */
00006 
00007 /* The xfig backend of Potrace. */
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 /* page formats known by xfig, and their dimensions in postscript points */
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 /* path-drawing auxiliary functions */
00073 
00074 /* structure to hold an affine coordinate transformation */
00075 struct trans_s {
00076   double ox, oy;             /* origin */
00077   double dxx, dxy, dyx, dyy; /* transformation matrix */
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 /* coordinate quantization */
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 /* functions for converting a path to a xfig */
00108 
00109 /* calculate number of xfig control points in this path */
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 /* do one path. First should be 1 on the very first path, else 0. */
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 /* Backend. */
00162 
00163 /* public interface for XFIG */
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;  /* in xfig's coordinates */
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   /* find closest page format */
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   /* header */
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");  /* 1200 pixels per inch */
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); /* bounding box */
00222 
00223   /* write paths. Note: can never use "opticurve" with this backend -
00224      it just does not approximate Bezier curves closely enough.  */
00225   list_forall (p, plist) {
00226     xfig_path(fout, &p->curve, t, p->sign);
00227   }
00228 
00229   fprintf(fout, "-6\n"); /* end bounding box */
00230 
00231   fflush(fout);
00232 
00233   return 0;
00234 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


portrait_painter
Author(s): Niklas Meinzer, Ina Baumgarten
autogenerated on Wed Dec 26 2012 16:00:42