Statistics
| Revision:

gvsig-raster / libjni-potrace / trunk / libjni-potrace / resources / potrace-1.8 / src / backend_xfig.c @ 1780

History | View | Annotate | Download (5.88 KB)

1
/* Copyright (C) 2001-2007 Peter Selinger.
2
   This file is part of Potrace. It is free software and it is covered
3
   by the GNU General Public License. See the file COPYING for details. */
4

    
5
/* $Id: backend_xfig.c 147 2007-04-09 00:44:09Z selinger $ */
6

    
7
/* The xfig backend of Potrace. */
8

    
9
#include <stdio.h>
10
#include <stdarg.h>
11
#include <string.h>
12
#include <math.h>
13

    
14
#include "main.h"
15
#include "backend_xfig.h"
16
#include "potracelib.h"
17
#include "lists.h"
18
#include "auxiliary.h"
19

    
20
#ifdef HAVE_CONFIG_H
21
#include "config.h"
22
#endif
23

    
24
#ifndef M_PI
25
#define M_PI 3.14159265358979323846
26
#endif
27

    
28
struct pageformat_s {
29
  char *name;
30
  int w, h;
31
};
32
typedef struct pageformat_s pageformat_t;
33

    
34
/* page formats known by xfig, and their dimensions in postscript points */
35
static pageformat_t pageformat[] = {
36
  { "A9",        105,  149 },
37
  { "A8",        149,  211 },
38
  { "A7",        211,  298 },
39
  { "A6",        298,  421 },
40
  { "A5",        421,  595 },
41
  { "A4",        595,  842 },
42
  { "A3",        842, 1191 },
43
  { "A2",       1191, 1685 },
44
  { "A1",       1685, 2383 },
45
  { "A0",       2383, 3370 },
46

    
47
  { "B10",        91,  129 },
48
  { "B9",        129,  182 },
49
  { "B8",        182,  258 },
50
  { "B7",        258,  365 },
51
  { "B6",        365,  516 },
52
  { "B5",        516,  730 },
53
  { "B4",        730, 1032 },
54
  { "B3",       1032, 1460 },
55
  { "B2",       1460, 2064 },
56
  { "B1",       2064, 2920 },
57
  { "B0",       2920, 4127 },
58

    
59
  { "Letter",    612,  792 },
60
  { "Legal",     612, 1008 },
61
  { "Tabloid",   792, 1224 },
62
  { "A",         612,  792 },
63
  { "B",         792, 1224 },
64
  { "C",        1224, 1584 },
65
  { "D",        1584, 2448 },
66
  { "E",        2448, 3168 },
67

    
68
  { NULL, 0, 0 },
69
};
70

    
71
/* ---------------------------------------------------------------------- */
72
/* path-drawing auxiliary functions */
73

    
74
/* structure to hold an affine coordinate transformation */
75
struct trans_s {
76
  double ox, oy;             /* origin */
77
  double dxx, dxy, dyx, dyy; /* transformation matrix */
78
};
79
typedef struct trans_s trans_t;
80

    
81
static inline dpoint_t trans(dpoint_t p, trans_t t) {
82
  dpoint_t res;
83

    
84
  res.x = t.ox + p.x * t.dxx + p.y * t.dyx;
85
  res.y = t.oy + p.x * t.dxy + p.y * t.dyy;
86
  return res;
87
}
88

    
89
/* coordinate quantization */
90
static inline point_t unit(dpoint_t p) {
91
  point_t q;
92

    
93
  q.x = (long)(floor(p.x+.5));
94
  q.y = (long)(floor(p.y+.5));
95
  return q;
96
}
97

    
98
static void xfig_point(FILE *fout, dpoint_t p, trans_t t) {
99
  point_t q;
100

    
101
  q = unit(trans(p, t));
102

    
103
  fprintf(fout, "%ld %ld\n", q.x, q.y);
104
}
105

    
106
/* ---------------------------------------------------------------------- */
107
/* functions for converting a path to a xfig */
108

    
109
/* calculate number of xfig control points in this path */
110
static int npoints(potrace_curve_t *curve, int m) {
111
  int i;
112
  int n=0;
113

    
114
  for (i=0; i<m; i++) {
115
    switch (curve->tag[i]) {
116
    case POTRACE_CORNER:
117
      n += 1;
118
      break;
119
    case POTRACE_CURVETO:
120
      n += 2;
121
      break;
122
    }
123
  }
124
  return n;
125
}
126

    
127
/* do one path. First should be 1 on the very first path, else 0. */
128
static int xfig_path(FILE *fout, potrace_curve_t *curve, trans_t t, int sign) {
129
  int i;
130
  dpoint_t *c;
131
  int m = curve->n;
132

    
133
  fprintf(fout, "3 1 0 0 0 %d 50 0 20 0.000 0 0 0 %d\n", sign=='+' ? 32 : 33, npoints(curve, m));
134

    
135
  for (i=0; i<m; i++) {
136
    c = curve->c[i];
137
    switch (curve->tag[i]) {
138
    case POTRACE_CORNER:
139
      xfig_point(fout, c[1], t);
140
      break;
141
    case POTRACE_CURVETO:
142
      xfig_point(fout, c[0], t);
143
      xfig_point(fout, c[1], t);
144
      break;
145
    }
146
  }
147
  for (i=0; i<m; i++) {
148
    switch (curve->tag[i]) {
149
    case POTRACE_CORNER:
150
      fprintf(fout, "0\n");
151
      break;
152
    case POTRACE_CURVETO:
153
      fprintf(fout, "1 1\n");
154
      break;
155
    }
156
  }
157
  return 0;
158
}
159

    
160
/* ---------------------------------------------------------------------- */
161
/* Backend. */
162

    
163
/* public interface for XFIG */
164
int page_xfig(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
165
  potrace_path_t *p;
166
  trans_t t;
167
  double si, co;
168
  double origx = imginfo->trans.orig[0] + imginfo->lmar;
169
  double origy = - imginfo->trans.orig[1] - imginfo->bmar + info.paperheight;
170
  double scalex = imginfo->width / imginfo->pixwidth;
171
  double scaley = imginfo->height / imginfo->pixheight;
172
  char *formatname;
173
  int best, penalty;
174
  pageformat_t *f;
175
  int i;
176
  int x0, y0, x1, y1;  /* in xfig's coordinates */
177
  
178
  si = sin(info.angle/180*M_PI);
179
  co = cos(info.angle/180*M_PI);
180
  
181
  t.ox = 1200/72.0 * origx;
182
  t.oy = 1200/72.0 * origy;
183
  t.dxx = 1200/72.0 * scalex * co;
184
  t.dxy = 1200/72.0 * scalex * -si;
185
  t.dyx = 1200/72.0 * scaley * -si;
186
  t.dyy = 1200/72.0 * scaley * -co;
187

    
188
  x0 = (int)(1200/72.0 * (origx - imginfo->trans.orig[0]));
189
  y0 = (int)(1200/72.0 * (origy + imginfo->trans.orig[1]));
190
  x1 = x0 + (int)(1200/72.0 * imginfo->trans.bb[0]);
191
  y1 = y0 - (int)(1200/72.0 * imginfo->trans.bb[1]);
192

    
193
  best = -1;
194
  formatname = "Letter";
195

    
196
  /* find closest page format */
197
  for (i=0; pageformat[i].name; i++) {
198
    f = &pageformat[i];
199
    if (f->w >= info.paperwidth-1 && f->h >= info.paperheight-1) {
200
      penalty = f->w + f->h;
201
      if (best == -1 || penalty < best) {
202
        best = penalty;
203
        formatname = f->name;
204
      }
205
    }
206
  }
207

    
208
  /* header */
209
  fprintf(fout, "#FIG 3.2\n");
210
  fprintf(fout, "#created by "POTRACE" "VERSION", written by Peter Selinger 2001-2007\n");
211
  fprintf(fout, "Portrait\n");
212
  fprintf(fout, "Center\n");
213
  fprintf(fout, "Inches\n");
214
  fprintf(fout, "%s\n", formatname);
215
  fprintf(fout, "100.0\n");
216
  fprintf(fout, "Single\n");
217
  fprintf(fout, "-2\n");
218
  fprintf(fout, "1200 2\n");  /* 1200 pixels per inch */
219
  fprintf(fout, "0 32 #%06x\n", info.color);
220
  fprintf(fout, "0 33 #%06x\n", info.fillcolor);
221
  fprintf(fout, "6 %d %d %d %d\n", x0-75, y1-35, x1+75, y0+35); /* bounding box */
222

    
223
  /* write paths. Note: can never use "opticurve" with this backend -
224
     it just does not approximate Bezier curves closely enough.  */
225
  list_forall (p, plist) {
226
    xfig_path(fout, &p->curve, t, p->sign);
227
  }
228

    
229
  fprintf(fout, "-6\n"); /* end bounding box */
230

    
231
  fflush(fout);
232

    
233
  return 0;
234
}