1 /* libwmf (convert/wmf2gd.c): library for wmf conversion
2 Copyright (C) 2000 - various; see CREDITS, ChangeLog, and sources
3
4 The libwmf Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The libwmf Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the libwmf Library; see the file COPYING. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19
20 #ifdef HAVE_CONFIG_H
21 #include "wmfconfig.h"
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <math.h>
29
30 #include "wmfdefs.h"
31
32 #ifdef X_DISPLAY_MISSING
33
main(int argc,char ** argv)34 int main (int argc,char** argv)
35 { fprintf (stderr,"%s: no support for X, sorry.\n",argv[0]);
36 return (1);
37 }
38
39 #else /* X_DISPLAY_MISSING */ /* i.e., not */
40
41 #include "libwmf/x.h"
42
43 #include <X11/Xutil.h>
44 #include <X11/Xatom.h>
45
46 typedef struct
47 { int argc;
48 char** argv;
49
50 char* wmf_filename;
51
52 wmf_x_t options;
53 } PlotData;
54
55 int wmf2x_draw (PlotData*);
56
57 void wmf2x_init (PlotData*,int,char**);
58 void wmf2x_help (PlotData*);
59 int wmf2x_args (PlotData*);
60
61 int explicit_wmf_error (char*,wmf_error_t);
62
wmf2x_draw(PlotData * pdata)63 int wmf2x_draw (PlotData* pdata)
64 { int status = 0;
65 int redraw;
66 int setmask;
67 int length;
68
69 float wmf_width = 0;
70 float wmf_height = 0;
71
72 float ratio_wmf;
73 float ratio_bounds;
74
75 char key;
76
77 unsigned int root_width = 800; /* Unfortunately, need these before we open the display... */
78 unsigned int root_height = 600;
79 unsigned int disp_width = 0;
80 unsigned int disp_height = 0;
81
82 unsigned long flags;
83
84 wmf_error_t err;
85
86 wmf_x_t* ddata = 0;
87
88 wmfAPI* API = 0;
89
90 wmfAPI_Options api_options;
91
92 XEvent event;
93
94 XWindowAttributes attributes;
95
96 KeySym keysym;
97
98 static char* icon_name = "wmf2x";
99
100 flags = 0;
101
102 flags |= WMF_OPT_FUNCTION;
103 api_options.function = wmf_x_function;
104
105 flags |= WMF_OPT_ARGS;
106 api_options.argc = pdata->argc;
107 api_options.argv = pdata->argv;
108 #ifndef DEBUG
109 flags |= WMF_OPT_IGNORE_NONFATAL;
110 #endif
111 err = wmf_api_create (&API,flags,&api_options);
112 status = explicit_wmf_error ("wmf_api_create",err);
113
114 if (status)
115 { if (API) wmf_api_destroy (API);
116 return (status);
117 }
118
119 ddata = WMF_X_GetData (API);
120
121 ddata->flags |= WMF_X_DISPLAY_OPEN;
122
123 ddata->display_name = pdata->options.display_name;
124 ddata->window_name = pdata->wmf_filename;
125 ddata->icon_name = icon_name;
126
127 length = strlen (pdata->wmf_filename);
128 #if defined (HAVE_EXPAT) || defined (HAVE_LIBXML2)
129 if (length > 4)
130 {
131 if ((strcmp (pdata->wmf_filename + length - 4, ".xml") == 0) ||
132 (strcmp (pdata->wmf_filename + length - 4, ".XML") == 0))
133 { err = wmf_wmfxml_import (API,pdata->wmf_filename);
134 }
135 else err = wmf_file_open (API,pdata->wmf_filename);
136 }
137 else err = wmf_file_open (API,pdata->wmf_filename);
138 #else
139 err = wmf_file_open (API,pdata->wmf_filename);
140 #endif
141 status = explicit_wmf_error ("wmf_file_open",err);
142
143 if (status)
144 { wmf_api_destroy (API);
145 return (status);
146 }
147
148 err = wmf_scan (API,0,&(pdata->options.bbox));
149 status = explicit_wmf_error ("wmf_scan",err);
150
151 if (status)
152 { wmf_api_destroy (API);
153 return (status);
154 }
155
156 /* Okay, got this far, everything seems cool.
157 */
158 ddata->bbox = pdata->options.bbox;
159
160 wmf_display_size (API,&disp_width,&disp_height,72,72);
161
162 wmf_width = (float) disp_width;
163 wmf_height = (float) disp_height;
164
165 if (pdata->options.x_width > 0)
166 { wmf_width = pdata->options.x_width;
167 }
168 if (pdata->options.x_height > 0)
169 { wmf_height = pdata->options.x_height;
170 }
171
172 if ((wmf_width <= 0) || (wmf_height <= 0))
173 { fputs ("Bad image size - but this error shouldn't occur...\n",stderr);
174 status = 1;
175 wmf_api_destroy (API);
176 return (status);
177 }
178
179 if ((wmf_width > (float) root_width )
180 || (wmf_height > (float) root_height))
181 { ratio_wmf = wmf_height / wmf_width;
182 ratio_bounds = (float) root_height / (float) root_width;
183
184 if (ratio_wmf > ratio_bounds)
185 { ddata->x_height = root_height;
186 ddata->x_width = (unsigned int) ((float) ddata->x_height / ratio_wmf);
187 }
188 else
189 { ddata->x_width = root_width;
190 ddata->x_height = (unsigned int) ((float) ddata->x_width * ratio_wmf);
191 }
192 }
193 else
194 { ddata->x_width = (unsigned int) ceil ((double) wmf_width );
195 ddata->x_height = (unsigned int) ceil ((double) wmf_height);
196 }
197
198 redraw = 1;
199 setmask = 1;
200 while (status == 0)
201 { if (redraw)
202 { err = wmf_play (API,0,&(pdata->options.bbox));
203 status = explicit_wmf_error ("wmf_play",err);
204 if (status) break;
205 }
206 redraw = 0;
207
208 if (setmask)
209 { XSelectInput (ddata->display,ddata->window,KeyPressMask|StructureNotifyMask);
210 setmask = 0;
211 }
212
213 XNextEvent (ddata->display,&event);
214
215 switch (event.type)
216 {
217 case KeyPress:
218 XLookupString (&(event.xkey),&key,1,&keysym,0);
219
220 switch (key)
221 {
222 case 'q':
223 case 'Q':
224 status = -1;
225 break;
226
227 case 'r':
228 case 'R':
229 redraw = 1;
230 break;
231
232 default:
233 break;
234 }
235 break;
236
237 case ConfigureNotify: /* This is all a bit clumsy, because I'm being lazy and letting *
238 * the library ipa do most of the work that ought to be done here! */
239
240 XGetWindowAttributes (ddata->display,ddata->window,&attributes);
241
242 if ((ddata->x_width != (unsigned int)attributes.width) ||
243 (ddata->x_height != (unsigned int)attributes.height))
244 { ddata->x_width = attributes.width;
245 ddata->x_height = attributes.height;
246
247 XFreePixmap (ddata->display,ddata->pixmap);
248
249 ddata->flags &= ~WMF_X_PIXMAP_CLOSE;
250
251 ddata->pixmap = XCreatePixmap (ddata->display,ddata->root,
252 ddata->x_width,ddata->x_height,ddata->depth);
253
254 if (ddata->pixmap == None)
255 { WMF_ERROR (API,"unable to create pixmap!");
256 status = 1;
257 break;
258 }
259
260 ddata->flags |= WMF_X_PIXMAP_CLOSE;
261
262 XSetWindowBackgroundPixmap (ddata->display,ddata->window,ddata->pixmap);
263
264 redraw = 1;
265 }
266 break;
267
268 default:
269 break;
270 }
271 if (status == (-1))
272 { status = 0;
273 break;
274 }
275 }
276
277 wmf_api_destroy (API);
278
279 return (status);
280 }
281
wmf2x_init(PlotData * pdata,int argc,char ** argv)282 void wmf2x_init (PlotData* pdata,int argc,char** argv)
283 { pdata->argc = argc;
284 pdata->argv = argv;
285
286 pdata->wmf_filename = 0;
287
288 pdata->options.display_name = 0;
289
290 pdata->options.x_width = 0;
291 pdata->options.x_height = 0;
292
293 pdata->options.flags = 0;
294 }
295
wmf2x_help(PlotData * pdata)296 void wmf2x_help (PlotData* pdata)
297 { (void)pdata;
298 fputs ("\
299 Usage: wmf2x [OPTION]... <file.wmf>\n\
300 Display metafile image.\n\
301 \n\
302 -display <display> where <display> is the display name.\n\
303 --width=<w> where <w> is the width of the image.\n\
304 --height=<h> where <h> is the height of the image.\n\
305 --version display version info and exit.\n\
306 --help display this help and exit.\n\
307 --wmf-help display wmf-related help and exit.\n\
308 \n\
309 Report bugs to <http://www.wvware.com/>.\n",stdout);
310 }
311
wmf2x_args(PlotData * pdata)312 int wmf2x_args (PlotData* pdata)
313 { int status = 0;
314 int arg = 0;
315
316 int argc = pdata->argc;
317 char** argv = pdata->argv;
318
319 while ((++arg) < argc)
320 { if (strcmp (argv[arg],"--help") == 0)
321 { wmf2x_help (pdata);
322 status = argc; /* i.e., not an error but don't continue */
323 break;
324 }
325
326 if (strcmp (argv[arg],"--wmf-help") == 0)
327 { fputs (wmf_help (),stdout);
328 status = argc; /* i.e., not an error but don't continue */
329 break;
330 }
331
332 if (strcmp (argv[arg],"--version") == 0)
333 { fprintf (stdout,"%s: version %s\n",PACKAGE,VERSION);
334 status = argc; /* i.e., not an error but don't continue */
335 break;
336 }
337
338 if (strcmp (argv[arg],"-display") == 0)
339 { if ((++arg) < argc)
340 { pdata->options.display_name = argv[arg];
341 continue;
342 }
343 fprintf (stderr,"usage: `wmf2x -display <displayname> <file.wmf>'.\n");
344 fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
345 status = arg;
346 break;
347 }
348
349 if (strncmp (argv[arg],"--width=",8) == 0)
350 { if (sscanf (argv[arg]+8,"%u",&(pdata->options.x_width)) != 1)
351 { fputs ("usage: --width=<width>, where <width> is +ve integer.\n",stderr);
352 status = arg;
353 break;
354 }
355 continue;
356 }
357 if (strncmp (argv[arg],"--height=",9) == 0)
358 { if (sscanf (argv[arg]+9,"%u",&(pdata->options.x_height)) != 1)
359 { fputs ("usage: --height=<height>, where <height> is +ve integer.\n",stderr);
360 status = arg;
361 break;
362 }
363 continue;
364 }
365
366 if (strncmp (argv[arg],"--wmf-",6) == 0)
367 { continue;
368 }
369
370 if (argv[arg][0] != '-')
371 { pdata->wmf_filename = argv[arg];
372 continue;
373 }
374
375 fprintf (stderr,"option `%s' not recognized.\n",argv[arg]);
376 fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
377 status = arg;
378 break;
379 }
380
381 if (status == 0)
382 { if (pdata->wmf_filename == 0)
383 { fprintf (stderr,"No input file specified!\n");
384 fprintf (stderr,"Try `%s --help' for more information.\n",argv[0]);
385 status = argc;
386 }
387 }
388
389 return (status);
390 }
391
main(int argc,char ** argv)392 int main (int argc,char** argv)
393 { int status = 0;
394
395 PlotData PData;
396
397 wmf2x_init (&PData,argc,argv);
398
399 status = wmf2x_args (&PData);
400
401 if (status) return (status);
402
403 status = wmf2x_draw (&PData);
404
405 return (status);
406 }
407
explicit_wmf_error(char * str,wmf_error_t err)408 int explicit_wmf_error (char* str,wmf_error_t err)
409 { (void)str;
410 int status = 0;
411
412 switch (err)
413 {
414 case wmf_E_None:
415 #ifdef DEBUG
416 fprintf (stderr,"%s returned with wmf_E_None.\n",str);
417 #endif
418 status = 0;
419 break;
420
421 case wmf_E_InsMem:
422 #ifdef DEBUG
423 fprintf (stderr,"%s returned with wmf_E_InsMem.\n",str);
424 #endif
425 status = 1;
426 break;
427
428 case wmf_E_BadFile:
429 #ifdef DEBUG
430 fprintf (stderr,"%s returned with wmf_E_BadFile.\n",str);
431 #endif
432 status = 1;
433 break;
434
435 case wmf_E_BadFormat:
436 #ifdef DEBUG
437 fprintf (stderr,"%s returned with wmf_E_BadFormat.\n",str);
438 #endif
439 status = 1;
440 break;
441
442 case wmf_E_EOF:
443 #ifdef DEBUG
444 fprintf (stderr,"%s returned with wmf_E_EOF.\n",str);
445 #endif
446 status = 1;
447 break;
448
449 case wmf_E_DeviceError:
450 #ifdef DEBUG
451 fprintf (stderr,"%s returned with wmf_E_DeviceError.\n",str);
452 #endif
453 status = 1;
454 break;
455
456 case wmf_E_Glitch:
457 #ifdef DEBUG
458 fprintf (stderr,"%s returned with wmf_E_Glitch.\n",str);
459 #endif
460 status = 1;
461 break;
462
463 case wmf_E_Assert:
464 #ifdef DEBUG
465 fprintf (stderr,"%s returned with wmf_E_Assert.\n",str);
466 #endif
467 status = 1;
468 break;
469
470 default:
471 #ifdef DEBUG
472 fprintf (stderr,"%s returned unexpected value.\n",str);
473 #endif
474 status = 1;
475 break;
476 }
477
478 return (status);
479 }
480
481 #endif /* X_DISPLAY_MISSING */
482