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