1 /* output.c: interface for output handlers
2
3 Copyright (C) 1999, 2000, 2001 Bernhard Herzog.
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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif /* Def: HAVE_CONFIG_H */
23
24 #include "output.h"
25 #include "xstd.h"
26 #include "filename.h"
27 #include "strgicmp.h"
28 #include <string.h>
29
30 #include "output-eps.h"
31 #include "output-er.h"
32 #include "output-p2e.h"
33 #include "output-sk.h"
34 #include "output-svg.h"
35 #include "output-fig.h"
36 #ifdef HAVE_LIBSWF
37 #include "output-swf.h"
38 #endif /* HAVE_LIBSWF */
39 #include "output-emf.h"
40 #include "output-mif.h"
41 #include "output-dxf.h"
42 #include "output-epd.h"
43 #include "output-pdf.h"
44 #include "output-cgm.h"
45 #include "output-dr2d.h"
46 #if HAVE_LIBPSTOEDIT
47 #include "output-pstoedit.h"
48 #endif /* HAVE_LIBPSTOEDIT */
49
50 struct output_format_entry {
51 const char * name;
52 const char * descr;
53 at_output_write_func writer;
54 };
55
56 #define END {NULL, NULL, NULL}
57 static struct output_format_entry output_formats[] = {
58 {"eps", "Encapsulated PostScript", output_eps_writer},
59 {"ai", "Adobe Illustrator", output_eps_writer},
60 {"p2e", "pstoedit frontend format", output_p2e_writer},
61 {"sk", "Sketch", output_sk_writer},
62 {"svg", "Scalable Vector Graphics", output_svg_writer},
63 {"fig", "XFIG 3.2", output_fig_writer},
64 #ifdef HAVE_LIBSWF
65 {"swf", "Shockwave Flash 3", output_swf_writer},
66 #endif /* HAVE_LIBSWF */
67 {"emf", "Enhanced Metafile format", output_emf_writer},
68 {"mif", "FrameMaker MIF format", output_mif_writer},
69 {"er", "Elastic Reality Shape file", output_er_writer},
70 {"dxf", "DXF format (without splines)", output_dxf12_writer},
71 {"epd", "EPD format", output_epd_writer},
72 {"pdf", "PDF format", output_pdf_writer},
73 {"cgm", "Computer Graphics Metafile", output_cgm_writer},
74 {"dr2d", "IFF DR2D format", output_dr2d_writer},
75 END
76 };
77
78 #if HAVE_LIBPSTOEDIT
79 static at_bool output_is_static_member (struct output_format_entry * entries,
80 struct DriverDescription_S* dd);
81 #endif /* HAVE_LIBPSTOEDIT */
82
83 static at_bool streq (const char * a, const char * b);
84
85 at_output_write_func
at_output_get_handler(at_string filename)86 at_output_get_handler(at_string filename)
87 {
88 char * ext = find_suffix (filename);
89 if (ext == NULL)
90 ext = "";
91
92 return at_output_get_handler_by_suffix (ext);
93 }
94
95 at_output_write_func
at_output_get_handler_by_suffix(at_string suffix)96 at_output_get_handler_by_suffix(at_string suffix)
97 {
98 struct output_format_entry * format;
99
100 if (!suffix || suffix[0] == '\0')
101 return NULL;
102
103 for (format = output_formats ; format->name; format++)
104 {
105 if (strgicmp (suffix, format->name))
106 {
107 return format->writer;
108 }
109 }
110 #if HAVE_LIBPSTOEDIT
111 return output_pstoedit_get_writer(suffix);
112 #else
113 return NULL;
114 #endif /* HAVE_LIBPSTOEDIT */
115 }
116
117 char **
at_output_list_new(void)118 at_output_list_new (void)
119 {
120 char ** list;
121 int count_out = 0, count;
122 int i;
123
124 struct output_format_entry * entry;
125 #if HAVE_LIBPSTOEDIT
126 struct DriverDescription_S* driver_description;
127 #endif /* HAVE_LIBPSTOEDIT */
128
129 for (entry = output_formats; entry->name; entry++)
130 count_out++;
131
132 count = count_out;
133 #if HAVE_LIBPSTOEDIT
134 {
135 struct DriverDescription_S* dd_tmp;
136 pstoedit_checkversion(pstoeditdllversion);
137 driver_description = getPstoeditDriverInfo_plainC();
138 if (driver_description)
139 {
140 dd_tmp = driver_description;
141 while (dd_tmp->symbolicname)
142 {
143 if (!output_is_static_member(output_formats,
144 dd_tmp)
145 && !output_pstoedit_is_unusable_writer(dd_tmp->suffix))
146 {
147 if (streq(dd_tmp->symbolicname, dd_tmp->suffix))
148 count += 1;
149 else
150 count += 2;
151 }
152 dd_tmp++;
153 }
154 }
155 }
156 #endif /* HAVE_LIBPSTOEDIT */
157
158 XMALLOC(list, sizeof(char*)*((2*count)+1));
159
160 entry = output_formats;
161 for (i = 0; i < count_out; i++)
162 {
163 list[2*i] = (char *)entry[i].name;
164 list[2*i+1] = (char *)entry[i].descr;
165 }
166 #if HAVE_LIBPSTOEDIT
167 while (driver_description->symbolicname)
168 {
169 if (!output_is_static_member(output_formats,
170 driver_description)
171 && !output_pstoedit_is_unusable_writer(driver_description->suffix))
172 {
173 list[2*i] = driver_description->suffix;
174 list[2*i+1] = driver_description->explanation;
175 i++;
176 if (!streq(driver_description->suffix,
177 driver_description->symbolicname))
178 {
179 list[2*i] = driver_description->symbolicname;
180 list[2*i+1] = driver_description->explanation;
181 i++;
182 }
183 }
184 driver_description++;
185 }
186 #endif /* HAVE_LIBPSTOEDIT */
187 list[2*i] = NULL;
188 return list;
189 }
190
191 void
at_output_list_free(char ** list)192 at_output_list_free(char ** list)
193 {
194 free(list);
195 }
196
197 char *
at_output_shortlist(void)198 at_output_shortlist (void)
199 {
200 char * list;
201 int count = 0;
202 size_t length = 0;
203 int i;
204
205 struct output_format_entry * entry;
206 #if HAVE_LIBPSTOEDIT
207 struct DriverDescription_S* driver_description;
208 struct DriverDescription_S* dd_tmp;
209 #endif /* HAVE_LIBPSTOEDIT */
210
211 for (entry = output_formats; entry->name; entry++)
212 {
213 count++;
214 length += strlen (entry->name) + 2;
215 }
216
217 #if HAVE_LIBPSTOEDIT
218 {
219 pstoedit_checkversion(pstoeditdllversion);
220 driver_description = getPstoeditDriverInfo_plainC();
221 if (driver_description)
222 {
223 dd_tmp = driver_description;
224 while (dd_tmp->symbolicname)
225 {
226 if (!output_is_static_member(output_formats,
227 dd_tmp)
228 && !output_pstoedit_is_unusable_writer(dd_tmp->suffix))
229 {
230 length += strlen (dd_tmp->suffix) + 2;
231 if (!streq(dd_tmp->suffix, dd_tmp->symbolicname))
232 length += strlen (dd_tmp->symbolicname) + 2;
233 }
234 dd_tmp++;
235 }
236 }
237 }
238 #endif /* HAVE_LIBPSTOEDIT */
239
240 XMALLOC(list, sizeof (char) * (length + 1 + 2));
241
242 entry = output_formats;
243 strcpy (list, (char *) entry[0].name);
244 for (i = 1; i < count - 1; i++)
245 {
246 strcat (list, ", ");
247 strcat (list, (char *) entry[i].name);
248 }
249 #if HAVE_LIBPSTOEDIT
250 dd_tmp = driver_description;
251 while (dd_tmp->symbolicname)
252 {
253
254 if (!output_is_static_member(output_formats,
255 dd_tmp)
256 && !output_pstoedit_is_unusable_writer(dd_tmp->suffix))
257 {
258 strcat (list, ", ");
259 strcat (list, dd_tmp->suffix);
260 if (!streq(dd_tmp->suffix,
261 dd_tmp->symbolicname))
262 {
263 strcat (list, ", ");
264 strcat (list, dd_tmp->symbolicname);
265 }
266 }
267 dd_tmp++;
268 }
269 free(driver_description);
270 #endif /* HAVE_LIBPSTOEDIT */
271 strcat (list, " or ");
272 strcat (list, (char *) entry[i].name);
273 return list;
274 }
275
276 int
at_output_add_handler(at_string suffix,at_string description,at_output_write_func func)277 at_output_add_handler (at_string suffix,
278 at_string description,
279 at_output_write_func func)
280 {
281 return 0;
282 }
283
284 void
at_spline_list_foreach(at_spline_list_type * list,AtSplineListForeachFunc func,at_address user_data)285 at_spline_list_foreach (at_spline_list_type * list,
286 AtSplineListForeachFunc func,
287 at_address user_data)
288 {
289 unsigned i;
290 for (i = 0; i < AT_SPLINE_LIST_LENGTH(list); i++)
291 {
292 func (list, AT_SPLINE_LIST_ELT(list, i), i, user_data);
293 }
294 }
295
296
297 void
at_spline_list_array_foreach(at_spline_list_array_type * list_array,AtSplineListArrayForeachFunc func,at_address user_data)298 at_spline_list_array_foreach (at_spline_list_array_type *list_array,
299 AtSplineListArrayForeachFunc func,
300 at_address user_data)
301 {
302 unsigned i;
303 for (i = 0; i < AT_SPLINE_LIST_ARRAY_LENGTH(list_array); i++)
304 {
305 func (list_array, AT_SPLINE_LIST_ARRAY_ELT(list_array, i), i, user_data);
306 }
307 }
308
309 #if HAVE_LIBPSTOEDIT
310 static at_bool
output_is_static_member(struct output_format_entry * entries,struct DriverDescription_S * dd)311 output_is_static_member (struct output_format_entry * entries,
312 struct DriverDescription_S* dd)
313 {
314 while (entries->name)
315 {
316 if (streq(dd->suffix, entries->name)
317 || streq(dd->symbolicname, entries->name))
318 return true;
319 entries++;
320 }
321 return false;
322 }
323 #endif /* HAVE_LIBPSTOEDIT */
324
325 static at_bool
streq(const char * a,const char * b)326 streq (const char * a, const char * b)
327 {
328 if (!strcmp(a, b))
329 return true;
330 else
331 return false;
332 }
333