1 /* output-p2e.c: utility routines for pstoedit intermediate output
2
3 Copyright (C) 2000-2001 Wolfgang Glunz, Martin Weber
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License
7 as published by the Free Software Foundation; either version 2.1 of
8 the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 USA. */
19
20 /* Initial author: Wolfgang Glunz - wglunz@pstoedit.net
21 use the generated file to run "pstoedit -bo -f format input output"
22 Adapted to pstoedit 3.30 by Wolfgang Glunz. */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif /* Def: HAVE_CONFIG_H */
27
28 #include "types.h"
29 #include "spline.h"
30 #include "color.h"
31 #include "output-p2e.h"
32
33
34 #define SIGN(x) ((x) > 0 ? 1 : (x) < 0 ? -1 : 0)
35 #define ROUND(x) ((int) ((int) (x) + .5 * SIGN (x)))
36
37 /* Output macros. */
38
39 /* This should be used for outputting a string S on a line by itself. */
40 #define OUT_LINE(l) \
41 fprintf (ps_file, "%s\n", l)
42
43 /* These output their arguments, preceded by the indentation. */
44 #define OUT1(s, e) \
45 fprintf (ps_file, s, e)
46
47 #ifdef withrgbcolor
48 #define OUT3(s, e1, e2, e3) fprintf (ps_file, s, e1, e2, e3)
49 #else
50 #define OUT5(s, e1, e2, e3, e4, e5) fprintf (ps_file, s, e1, e2, e3, e4, e5)
51 #endif
52
53 #define OUT4(s, e1, e2, e3, e4) \
54 fprintf (ps_file, s, e1, e2, e3, e4)
55
56 /* These macros just output their arguments. */
57 #define OUT_STRING(st) fprintf (ps_file, "%s", st)
58 #define OUT_REAL(r) fprintf (ps_file, \
59 r == ROUND (r) ? "%.0f " : "%.3f ", r)
60
61 /* For a PostScript command with two real arguments, e.g., lineto. OP
62 should be a constant string. */
63 #define OUT_COMMAND2(first, second, op) \
64 do \
65 { \
66 OUT_STRING (" "); \
67 OUT_REAL (first); \
68 OUT_REAL (second); \
69 OUT_STRING (op "\n"); \
70 } \
71 while (0)
72
73 /* For a PostScript command with six real arguments, e.g., curveto.
74 Again, OP should be a constant string. */
75 #define OUT_COMMAND6(first, second, third, fourth, fifth, sixth, op) \
76 do \
77 { \
78 OUT_STRING (" "); \
79 OUT_REAL (first); \
80 OUT_REAL (second); \
81 OUT_STRING (" "); \
82 OUT_REAL (third); \
83 OUT_REAL (fourth); \
84 OUT_STRING (" "); \
85 OUT_REAL (fifth); \
86 OUT_REAL (sixth); \
87 OUT_STRING (" " op "\n"); \
88 } \
89 while (0)
90
91 /* This should be called before the others in this file. It opens the
92 output file `OUTPUT_NAME.ps', and writes some preliminary boilerplate. */
93
output_p2e_header(FILE * ps_file,at_string name,int llx,int lly,int urx,int ury,spline_list_array_type shape)94 static int output_p2e_header(FILE* ps_file, at_string name,
95 int llx, int lly, int urx, int ury, spline_list_array_type shape)
96 {
97 unsigned this_list, with_curves = 1;
98
99 for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape);
100 this_list++)
101 {
102 unsigned this_spline;
103
104 spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
105
106 for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list);
107 this_spline++)
108 {
109 spline_type s = SPLINE_LIST_ELT (list, this_spline);
110
111 if (SPLINE_DEGREE (s) != LINEARTYPE)
112 {
113 with_curves = 0;
114 this_list = SPLINE_LIST_ARRAY_LENGTH (shape);
115 break;
116 }
117 }
118
119 }
120
121 OUT_LINE ("%!PS-Adobe-3.0");
122 OUT1 ("%%%%Title: flattened PostScript generated by autotrace: %s\n",name);
123 OUT_LINE ("%%Creator: pstoedit");
124 OUT_LINE ("%%BoundingBox: (atend)");
125 OUT_LINE ("%%Pages: (atend)");
126 OUT_LINE ("%%EndComments");
127 OUT_LINE ("%%BeginProlog");
128 OUT_LINE ("/setPageSize { pop pop } def");
129 OUT_LINE ("/ntranslate { neg exch neg exch translate } def");
130 OUT_LINE ("/setshowparams { pop pop pop} def");
131 OUT_LINE ("/awidthshowhex { dup /ASCIIHexDecode filter exch length 2 div cvi string readstring pop awidthshow } def");
132 OUT_LINE ("/backendconstraints { pop pop } def");
133 OUT_LINE ("/pstoedit.newfont { 80 string cvs findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def dup 80 string cvs /FontName exch def currentdict end definefont pop } def");
134 OUT_LINE ("/imagestring 1 string def");
135 OUT_LINE ("%%EndProlog");
136 OUT_LINE ("%%BeginSetup");
137 OUT_LINE ("% textastext doflatten backendconstraints ");
138 OUT1 ("%d 0 backendconstraints\n", with_curves);
139 OUT_LINE ("%%EndSetup");
140
141 return 0;
142 }
143
144 /* This outputs the PostScript code which produces the shape in
145 SHAPE. */
146
147 static void
out_splines(FILE * ps_file,spline_list_array_type shape)148 out_splines (FILE * ps_file, spline_list_array_type shape)
149 {
150 unsigned this_list;
151 unsigned int pathnr = 1;
152 spline_list_type list;
153 color_type last_color = {0,0,0};
154
155 OUT_LINE (" 612 792 setPageSize");
156 OUT_LINE (" 0 setlinecap");
157 OUT_LINE (" 10.0 setmiterlimit");
158 OUT_LINE (" 0 setlinejoin");
159 OUT_LINE (" [ ] 0.0 setdash");
160 OUT_LINE (" 1.0 setlinewidth");
161
162 for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape);
163 this_list++)
164 {
165 unsigned this_spline;
166 spline_type first;
167
168 list = SPLINE_LIST_ARRAY_ELT (shape, this_list);
169 first = SPLINE_LIST_ELT (list, 0);
170
171
172 if (this_list == 0 || !COLOR_EQUAL(list.color, last_color))
173 {
174 int c, m, y, k;
175
176 OUT_LINE ((shape.centerline || list.open) ? "stroke" : "fill");
177 OUT1("\n\n%% %d pathnumber\n",pathnr);
178 OUT_LINE ((shape.centerline || list.open) ? "% strokedpath" : "% filledpath");
179 pathnr++;
180 #ifdef withrgbcolor
181 // in the long term this can be removed.
182 OUT3 ("%.3f %.3f %.3f setrgbcolor\n", (real)list.color.r/255.0,
183 (real)list.color.g/255.0,
184 (real)list.color.b/255.0);
185 #else
186 c = k = 255 - list.color.r;
187 m = 255 - list.color.g;
188 if (m < k)
189 k = m;
190 y = 255 - list.color.b;
191 if (y < k)
192 k = y;
193 c -= k;
194 m -= k;
195 y -= k;
196 OUT5("%.3f %.3f %.3f %.3f %s\n", (double) c/255.0, (double) m/255.0,(double) y/255.0, (double) k/255.0, "setcmykcolor");
197 #endif
198 last_color = list.color;
199 }
200
201 OUT_LINE ("newpath");
202 OUT_COMMAND2 (START_POINT (first).x, START_POINT (first).y, "moveto");
203
204 for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list);
205 this_spline++)
206 {
207 spline_type s = SPLINE_LIST_ELT (list, this_spline);
208
209 if (SPLINE_DEGREE (s) == LINEARTYPE)
210 OUT_COMMAND2 (END_POINT (s).x, END_POINT (s).y, "lineto");
211 else
212 OUT_COMMAND6 (CONTROL1 (s).x, CONTROL1 (s).y,
213 CONTROL2 (s).x, CONTROL2 (s).y,
214 END_POINT (s).x, END_POINT (s).y,
215 "curveto");
216 }
217 if (!list.open) OUT_LINE ("closepath");
218 }
219 if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0)
220 OUT_LINE ((shape.centerline || list.open) ? "stroke" : "fill");
221 }
222
223
output_p2e_writer(FILE * ps_file,at_string name,int llx,int lly,int urx,int ury,at_output_opts_type * opts,spline_list_array_type shape,at_msg_func msg_func,at_address msg_data)224 int output_p2e_writer(FILE* ps_file, at_string name,
225 int llx, int lly, int urx, int ury,
226 at_output_opts_type * opts,
227 spline_list_array_type shape,
228 at_msg_func msg_func,
229 at_address msg_data)
230 {
231 int result;
232
233 result = output_p2e_header(ps_file, name, llx, lly, urx, ury, shape);
234 if (result != 0) return result;
235
236 out_splines(ps_file, shape);
237
238 OUT_LINE ("showpage");
239 OUT4 ("%%%%BoundingBox: %d %d %d %d\n", llx, lly, urx, ury);
240 OUT_LINE ("%%Page: 1 1");
241 OUT_LINE ("% normal end reached by pstoedit.pro");
242 OUT_LINE ("%%Trailer");
243 OUT_LINE ("%%Pages: 1");
244 OUT_LINE ("%%EOF");
245
246 return 0;
247 }
248