gvsig-raster / libjni-potrace / trunk / libjni-potrace / src / main / native / jpotrace / backend_gimp.c @ 1780
History | View | Annotate | Download (3.77 KB)
1 | 1780 | nbrodin | /* 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_gimp.c 147 2007-04-09 00:44:09Z selinger $ */
|
||
6 | |||
7 | /* The gimppath backend of Potrace. Can be imported by Gimp with the
|
||
8 | "Import Path" feature (Layers -> Layers, Channels & Paths -> Paths
|
||
9 | -> Right-click -> Import Path) */
|
||
10 | |||
11 | #include <stdio.h> |
||
12 | #include <stdarg.h> |
||
13 | #include <string.h> |
||
14 | #include <math.h> |
||
15 | |||
16 | #include "main.h" |
||
17 | #include "backend_gimp.h" |
||
18 | #include "potracelib.h" |
||
19 | #include "lists.h" |
||
20 | #include "auxiliary.h" |
||
21 | |||
22 | #ifdef HAVE_CONFIG_H
|
||
23 | #include "config.h" |
||
24 | #endif
|
||
25 | |||
26 | #ifndef M_PI
|
||
27 | #define M_PI 3.14159265358979323846 |
||
28 | #endif
|
||
29 | |||
30 | /* ---------------------------------------------------------------------- */
|
||
31 | /* path-drawing auxiliary functions */
|
||
32 | |||
33 | /* structure to hold an affine coordinate transformation */
|
||
34 | struct trans_s {
|
||
35 | double ox, oy; /* origin */ |
||
36 | double dxx, dxy, dyx, dyy; /* transformation matrix */ |
||
37 | }; |
||
38 | typedef struct trans_s trans_t; |
||
39 | |||
40 | static inline dpoint_t trans(dpoint_t p, trans_t t) { |
||
41 | dpoint_t res; |
||
42 | |||
43 | res.x = t.ox + p.x * t.dxx + p.y * t.dyx; |
||
44 | res.y = t.oy + p.x * t.dxy + p.y * t.dyy; |
||
45 | return res;
|
||
46 | } |
||
47 | |||
48 | /* coordinate quantization */
|
||
49 | static inline point_t unit(dpoint_t p) { |
||
50 | point_t q; |
||
51 | |||
52 | q.x = (long)(floor(p.x*info.unit+.5)); |
||
53 | q.y = (long)(floor(p.y*info.unit+.5)); |
||
54 | return q;
|
||
55 | } |
||
56 | |||
57 | static void gimppath_point(FILE *fout, int typ, dpoint_t p, trans_t t) { |
||
58 | point_t q; |
||
59 | |||
60 | q = unit(trans(p, t)); |
||
61 | |||
62 | fprintf(fout, "TYPE: %d X: %ld Y: %ld\n", typ, q.x, q.y);
|
||
63 | } |
||
64 | |||
65 | /* ---------------------------------------------------------------------- */
|
||
66 | /* functions for converting a path to a gimppath */
|
||
67 | |||
68 | /* do one path. First should be 1 on the very first path, else 0. */
|
||
69 | static int gimppath_path(FILE *fout, potrace_curve_t *curve, int first, trans_t t) { |
||
70 | int i;
|
||
71 | dpoint_t *c, *c1; |
||
72 | int m = curve->n;
|
||
73 | |||
74 | first = first ? 1 : 3; |
||
75 | |||
76 | for (i=0; i<m; i++) { |
||
77 | c = curve->c[i]; |
||
78 | c1 = curve->c[mod(i-1,m)];
|
||
79 | switch (curve->tag[i]) {
|
||
80 | case POTRACE_CORNER:
|
||
81 | gimppath_point(fout, first, c1[2], t);
|
||
82 | gimppath_point(fout, 2, c1[2], t); |
||
83 | gimppath_point(fout, 2, c[1], t); |
||
84 | gimppath_point(fout, 1, c[1], t); |
||
85 | gimppath_point(fout, 2, c[1], t); |
||
86 | gimppath_point(fout, 2, c[2], t); |
||
87 | break;
|
||
88 | case POTRACE_CURVETO:
|
||
89 | gimppath_point(fout, first, c1[2], t);
|
||
90 | gimppath_point(fout, 2, c[0], t); |
||
91 | gimppath_point(fout, 2, c[1], t); |
||
92 | break;
|
||
93 | } |
||
94 | first = 1;
|
||
95 | } |
||
96 | return 0; |
||
97 | } |
||
98 | |||
99 | /* calculate number of Gimp control points in this path */
|
||
100 | static int npoints(potrace_curve_t *curve) { |
||
101 | int i;
|
||
102 | int n=0; |
||
103 | int m = curve->n;
|
||
104 | |||
105 | for (i=0; i<m; i++) { |
||
106 | switch (curve->tag[i]) {
|
||
107 | case POTRACE_CORNER:
|
||
108 | n += 6;
|
||
109 | break;
|
||
110 | case POTRACE_CURVETO:
|
||
111 | n += 3;
|
||
112 | break;
|
||
113 | } |
||
114 | } |
||
115 | return n;
|
||
116 | } |
||
117 | |||
118 | /* ---------------------------------------------------------------------- */
|
||
119 | /* Backend. */
|
||
120 | |||
121 | /* public interface for GIMPPATH */
|
||
122 | int page_gimp(FILE *fout, potrace_path_t *plist, imginfo_t *imginfo) {
|
||
123 | potrace_path_t *p; |
||
124 | int first = 1; |
||
125 | int n;
|
||
126 | trans_t t; |
||
127 | double si, co;
|
||
128 | |||
129 | /* determine number of points */
|
||
130 | n = 0;
|
||
131 | list_forall (p, plist) { |
||
132 | n += npoints(&p->curve); |
||
133 | } |
||
134 | |||
135 | si = sin(info.angle/180*M_PI);
|
||
136 | co = cos(info.angle/180*M_PI);
|
||
137 | |||
138 | t.ox = max(0, si*imginfo->pixheight) + max(0, -co*imginfo->pixwidth); |
||
139 | t.oy = max(0, co*imginfo->pixheight) + max(0, si*imginfo->pixwidth); |
||
140 | t.dxx = co; |
||
141 | t.dxy = -si; |
||
142 | t.dyx = -si; |
||
143 | t.dyy = -co; |
||
144 | |||
145 | /* header */
|
||
146 | fprintf(fout, "Name: Potrace Imported Path\n");
|
||
147 | fprintf(fout, "#POINTS: %d\n", n);
|
||
148 | fprintf(fout, "CLOSED: 1\n");
|
||
149 | fprintf(fout, "DRAW: 0\n");
|
||
150 | fprintf(fout, "STATE: 4\n");
|
||
151 | |||
152 | /* write paths */
|
||
153 | list_forall (p, plist) { |
||
154 | gimppath_path(fout, &p->curve, first, t); |
||
155 | first = 0;
|
||
156 | } |
||
157 | fflush(fout); |
||
158 | |||
159 | return 0; |
||
160 | } |