Code

pdf export from commandline
[inkscape.git] / src / main.cpp
1 #define __MAIN_C__
3 /** \file
4  * Inkscape - an ambitious vector drawing program
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *   Frank Felfe <innerspace@iname.com>
9  *   Davide Puricelli <evo@debian.org>
10  *   Mitsuru Oka <oka326@parkcity.ne.jp>
11  *   Masatake YAMATO  <jet@gyve.org>
12  *   F.J.Franklin <F.J.Franklin@sheffield.ac.uk>
13  *   Michael Meeks <michael@helixcode.com>
14  *   Chema Celorio <chema@celorio.com>
15  *   Pawel Palucha
16  *   Bryce Harrington <bryce@bryceharrington.com>
17  * ... and various people who have worked with various projects
18  *
19  * Copyright (C) 1999-2004 authors
20  * Copyright (C) 2001-2002 Ximian, Inc.
21  *
22  * Released under GNU GPL, read the file 'COPYING' for more information
23  */
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29 #include "path-prefix.h"
31 #include <gtk/gtkmessagedialog.h>
33 #ifdef HAVE_IEEEFP_H
34 #include <ieeefp.h>
35 #endif
36 #include <string.h>
37 #include <locale.h>
39 #include <popt.h>
40 #ifndef POPT_TABLEEND
41 #define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
42 #endif /* Not def: POPT_TABLEEND */
44 #include <libxml/tree.h>
45 #include <glib-object.h>
46 #include <gtk/gtkmain.h>
47 #include <gtk/gtksignal.h>
48 #include <gtk/gtkwindow.h>
49 #include <gtk/gtkbox.h>
51 #include <gtk/gtkmain.h>
53 #include "gc-core.h"
55 #include "macros.h"
56 #include "file.h"
57 #include "document.h"
58 #include "sp-object.h"
59 #include "interface.h"
60 #include "print.h"
61 #include "slideshow.h"
62 #include "color.h"
63 #include "sp-item.h"
64 #include "sp-root.h"
65 #include "unit-constants.h"
67 #include "svg/svg.h"
68 #include "svg/svg-color.h"
69 #include "svg/stringstream.h"
71 #include "inkscape-private.h"
72 #include "inkscape-stock.h"
73 #include "inkscape_version.h"
75 #include "sp-namedview.h"
76 #include "sp-guide.h"
77 #include "sp-object-repr.h"
78 #include "xml/repr.h"
80 #include "io/sys.h"
82 #include "debug/logger.h"
84 #include <extension/extension.h>
85 #include <extension/system.h>
86 #include <extension/db.h>
87 #include <extension/output.h>
89 #ifdef WIN32
90 //#define REPLACEARGS_ANSI
91 //#define REPLACEARGS_DEBUG
93 #include "registrytool.h"
95 #include "extension/internal/win32.h"
96 using Inkscape::Extension::Internal::PrintWin32;
98 #endif // WIN32
100 #include "extension/init.h"
102 #include <glibmm/i18n.h>
103 #include <gtkmm/main.h>
105 #ifndef HAVE_BIND_TEXTDOMAIN_CODESET
106 #define bind_textdomain_codeset(p,c)
107 #endif
109 #include "application/application.h"
111 enum {
112     SP_ARG_NONE,
113     SP_ARG_NOGUI,
114     SP_ARG_GUI,
115     SP_ARG_FILE,
116     SP_ARG_PRINT,
117     SP_ARG_EXPORT_PNG,
118     SP_ARG_EXPORT_DPI,
119     SP_ARG_EXPORT_AREA,
120     SP_ARG_EXPORT_AREA_DRAWING,
121     SP_ARG_EXPORT_AREA_CANVAS,
122     SP_ARG_EXPORT_AREA_SNAP,
123     SP_ARG_EXPORT_WIDTH,
124     SP_ARG_EXPORT_HEIGHT,
125     SP_ARG_EXPORT_ID,
126     SP_ARG_EXPORT_ID_ONLY,
127     SP_ARG_EXPORT_USE_HINTS,
128     SP_ARG_EXPORT_BACKGROUND,
129     SP_ARG_EXPORT_BACKGROUND_OPACITY,
130     SP_ARG_EXPORT_SVG,
131     SP_ARG_EXPORT_PS,
132     SP_ARG_EXPORT_EPS,
133     SP_ARG_EXPORT_PDF,
134     SP_ARG_EXPORT_TEXT_TO_PATH,
135     SP_ARG_EXPORT_BBOX_PAGE,
136     SP_ARG_EXTENSIONDIR,
137     SP_ARG_SLIDESHOW,
138     SP_ARG_QUERY_X,
139     SP_ARG_QUERY_Y,
140     SP_ARG_QUERY_WIDTH,
141     SP_ARG_QUERY_HEIGHT,
142     SP_ARG_QUERY_ID,
143     SP_ARG_VERSION,
144     SP_ARG_NEW_GUI,
145     SP_ARG_VACUUM_DEFS,
146     SP_ARG_LAST
147 };
149 int sp_main_gui(int argc, char const **argv);
150 int sp_main_console(int argc, char const **argv);
151 static void sp_do_export_png(SPDocument *doc);
152 static void do_export_ps(SPDocument* doc, gchar const* uri, char const *mime);
153 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const *mime);
154 static void do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id);
157 static gchar *sp_global_printer = NULL;
158 static gboolean sp_global_slideshow = FALSE;
159 static gchar *sp_export_png = NULL;
160 static gchar *sp_export_dpi = NULL;
161 static gchar *sp_export_area = NULL;
162 static gboolean sp_export_area_drawing = FALSE;
163 static gboolean sp_export_area_canvas = FALSE;
164 static gchar *sp_export_width = NULL;
165 static gchar *sp_export_height = NULL;
166 static gchar *sp_export_id = NULL;
167 static gchar *sp_export_background = NULL;
168 static gchar *sp_export_background_opacity = NULL;
169 static gboolean sp_export_area_snap = FALSE;
170 static gboolean sp_export_use_hints = FALSE;
171 static gboolean sp_export_id_only = FALSE;
172 static gchar *sp_export_svg = NULL;
173 static gchar *sp_export_ps = NULL;
174 static gchar *sp_export_eps = NULL;
175 static gchar *sp_export_pdf = NULL;
176 static gboolean sp_export_text_to_path = FALSE;
177 static gboolean sp_export_bbox_page = FALSE;
178 static gboolean sp_query_x = FALSE;
179 static gboolean sp_query_y = FALSE;
180 static gboolean sp_query_width = FALSE;
181 static gboolean sp_query_height = FALSE;
182 static gchar *sp_query_id = NULL;
183 static int sp_new_gui = FALSE;
184 static gboolean sp_vacuum_defs = FALSE;
186 static gchar *sp_export_png_utf8 = NULL;
187 static gchar *sp_export_svg_utf8 = NULL;
188 static gchar *sp_global_printer_utf8 = NULL;
190 #ifdef WIN32
191 static bool replaceArgs( int& argc, char**& argv );
192 #endif
193 static GSList *sp_process_args(poptContext ctx);
194 struct poptOption options[] = {
195     {"version", 'V',
196      POPT_ARG_NONE, NULL, SP_ARG_VERSION,
197      N_("Print the Inkscape version number"),
198      NULL},
200     {"without-gui", 'z',
201      POPT_ARG_NONE, NULL, SP_ARG_NOGUI,
202      N_("Do not use X server (only process files from console)"),
203      NULL},
205     {"with-gui", 'g',
206      POPT_ARG_NONE, NULL, SP_ARG_GUI,
207      N_("Try to use X server (even if $DISPLAY is not set)"),
208      NULL},
210     {"file", 'f',
211      POPT_ARG_STRING, NULL, SP_ARG_FILE,
212      N_("Open specified document(s) (option string may be excluded)"),
213      N_("FILENAME")},
215     {"print", 'p',
216      POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT,
217      N_("Print document(s) to specified output file (use '| program' for pipe)"),
218      N_("FILENAME")},
220     {"export-png", 'e',
221      POPT_ARG_STRING, &sp_export_png, SP_ARG_EXPORT_PNG,
222      N_("Export document to a PNG file"),
223      N_("FILENAME")},
225     {"export-dpi", 'd',
226      POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI,
227      N_("The resolution used for exporting SVG into bitmap (default 90)"),
228      N_("DPI")},
230     {"export-area", 'a',
231      POPT_ARG_STRING, &sp_export_area, SP_ARG_EXPORT_AREA,
232      N_("Exported area in SVG user units (default is the canvas; 0,0 is lower-left corner)"),
233      N_("x0:y0:x1:y1")},
235     {"export-area-drawing", 'D',
236      POPT_ARG_NONE, &sp_export_area_drawing, SP_ARG_EXPORT_AREA_DRAWING,
237      N_("Exported area is the entire drawing (not canvas)"),
238      NULL},
240     {"export-area-canvas", 'C',
241      POPT_ARG_NONE, &sp_export_area_canvas, SP_ARG_EXPORT_AREA_CANVAS,
242      N_("Exported area is the entire canvas"),
243      NULL},
245     {"export-area-snap", 0,
246      POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP,
247      N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"),
248      NULL},
250     {"export-width", 'w',
251      POPT_ARG_STRING, &sp_export_width, SP_ARG_EXPORT_WIDTH,
252      N_("The width of exported bitmap in pixels (overrides export-dpi)"),
253      N_("WIDTH")},
255     {"export-height", 'h',
256      POPT_ARG_STRING, &sp_export_height, SP_ARG_EXPORT_HEIGHT,
257      N_("The height of exported bitmap in pixels (overrides export-dpi)"),
258      N_("HEIGHT")},
260     {"export-id", 'i',
261      POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID,
262      N_("The ID of the object to export"),
263      N_("ID")},
265     {"export-id-only", 'j',
266      POPT_ARG_NONE, &sp_export_id_only, SP_ARG_EXPORT_ID_ONLY,
267      // TRANSLATORS: this means: "Only export the object whose id is given in --export-id".
268      //  See "man inkscape" for details.
269      N_("Export just the object with export-id, hide all others (only with export-id)"),
270      NULL},
272     {"export-use-hints", 't',
273      POPT_ARG_NONE, &sp_export_use_hints, SP_ARG_EXPORT_USE_HINTS,
274      N_("Use stored filename and DPI hints when exporting (only with export-id)"),
275      NULL},
277     {"export-background", 'b',
278      POPT_ARG_STRING, &sp_export_background, SP_ARG_EXPORT_BACKGROUND,
279      N_("Background color of exported bitmap (any SVG-supported color string)"),
280      N_("COLOR")},
282     {"export-background-opacity", 'y',
283      POPT_ARG_STRING, &sp_export_background_opacity, SP_ARG_EXPORT_BACKGROUND_OPACITY,
284      N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"),
285      N_("VALUE")},
287     {"export-plain-svg", 'l',
288      POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG,
289      N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"),
290      N_("FILENAME")},
292     {"export-ps", 'P',
293      POPT_ARG_STRING, &sp_export_ps, SP_ARG_EXPORT_PS,
294      N_("Export document to a PS file"),
295      N_("FILENAME")},
297     {"export-eps", 'E',
298      POPT_ARG_STRING, &sp_export_eps, SP_ARG_EXPORT_EPS,
299      N_("Export document to an EPS file"),
300      N_("FILENAME")},
302     {"export-pdf", 'A',
303      POPT_ARG_STRING, &sp_export_pdf, SP_ARG_EXPORT_PDF,
304      N_("Export document to a PDF file"),
305      N_("FILENAME")},
307     {"export-text-to-path", 'T',
308      POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH,
309      N_("Convert text object to paths on export (EPS)"),
310      NULL},
312     {"export-bbox-page", 'B',
313      POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
314      N_("Export files with the bounding box set to the page size (EPS)"),
315      NULL},
317     {"query-x", 'X',
318      POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
319      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
320      N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
321      NULL},
323     {"query-y", 'Y',
324      POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
325      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
326      N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
327      NULL},
329     {"query-width", 'W',
330      POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
331      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
332      N_("Query the width of the drawing or, if specified, of the object with --query-id"),
333      NULL},
335     {"query-height", 'H',
336      POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
337      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
338      N_("Query the height of the drawing or, if specified, of the object with --query-id"),
339      NULL},
341     {"query-id", 'I',
342      POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
343      N_("The ID of the object whose dimensions are queried"),
344      N_("ID")},
346     {"extension-directory", 'x',
347      POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
348      // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
349      N_("Print out the extension directory and exit"),
350      NULL},
352     {"slideshow", 's',
353      POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
354      N_("Show given files one-by-one, switch to next on any key/mouse event"),
355      NULL},
357     {"new-gui", 'G',
358      POPT_ARG_NONE, &sp_new_gui, SP_ARG_NEW_GUI,
359      N_("Use the new Gtkmm GUI interface"),
360      NULL},
362     {"vacuum-defs", 0,
363      POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
364      N_("Remove unused definitions from the defs section(s) of the document"),
365      NULL},
367     POPT_AUTOHELP POPT_TABLEEND
368 };
370 static bool needToRecodeParams = true;
371 gchar* blankParam = "";
373 int
374 main(int argc, char **argv)
376 #ifdef HAVE_FPSETMASK
377     /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__.  It's probably
378        safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
379        the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
380     fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
381 #endif
383 #ifdef ENABLE_NLS
384 #ifdef WIN32
385     RegistryTool rt;
386     rt.setPathInfo();
387     gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
388     bindtextdomain(GETTEXT_PACKAGE, pathBuf);
389     g_free(pathBuf);
390 #else
391 #ifdef ENABLE_BINRELOC
392     bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
393 #else
394     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
395 #endif
396 #endif
397 #endif
399     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
401 #ifdef ENABLE_NLS
402     textdomain(GETTEXT_PACKAGE);
403 #endif
405     LIBXML_TEST_VERSION
407     Inkscape::GC::init();
409     Inkscape::Debug::Logger::init();
411     gboolean use_gui;
412 #ifndef WIN32
413     use_gui = (getenv("DISPLAY") != NULL);
414 #else
415     /*
416       Set the current directory to the directory of the
417       executable.  This seems redundant, but is needed for
418       when inkscape.exe is executed from another directory.
419       We use relative paths on win32.
420       HKCR\svgfile\shell\open\command is a good example
421     */
422     /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
423     char *homedir = g_path_get_dirname(argv[0]);
424     SetCurrentDirectory(homedir);
425     g_free(homedir);
427     use_gui = TRUE;
428 #endif
429     /* Test whether with/without GUI is forced */
430     for (int i = 1; i < argc; i++) {
431         if (!strcmp(argv[i], "-z")
432             || !strcmp(argv[i], "--without-gui")
433             || !strcmp(argv[i], "-p")
434             || !strncmp(argv[i], "--print", 7)
435             || !strcmp(argv[i], "-e")
436             || !strncmp(argv[i], "--export-png", 12)
437             || !strcmp(argv[i], "-l")
438             || !strncmp(argv[i], "--export-plain-svg", 12)
439             || !strcmp(argv[i], "-i")
440             || !strncmp(argv[i], "--export-area-drawing", 21)
441             || !strcmp(argv[i], "-D")
442             || !strncmp(argv[i], "--export-area-canvas", 20)
443             || !strcmp(argv[i], "-C")
444             || !strncmp(argv[i], "--export-id", 12)
445             || !strcmp(argv[i], "-P")
446             || !strncmp(argv[i], "--export-ps", 11)
447             || !strcmp(argv[i], "-E")
448             || !strncmp(argv[i], "--export-eps", 12)
449             || !strcmp(argv[i], "-A")
450             || !strncmp(argv[i], "--export-pdf", 12)
451             || !strcmp(argv[i], "-W")
452             || !strncmp(argv[i], "--query-width", 13)
453             || !strcmp(argv[i], "-H")
454             || !strncmp(argv[i], "--query-height", 14)
455             || !strcmp(argv[i], "-X")
456             || !strncmp(argv[i], "--query-x", 13)
457             || !strcmp(argv[i], "-Y")
458             || !strncmp(argv[i], "--query-y", 14)
459             || !strcmp(argv[i], "--vacuum-defs")
460            )
461         {
462             /* main_console handles any exports -- not the gui */
463             use_gui = FALSE;
464             break;
465         } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
466             use_gui = TRUE;
467             break;
468         } else if (!strcmp(argv[i], "-G") || !strcmp(argv[i], "--new-gui")) {
469             sp_new_gui = TRUE;
470             break;
471         }
472     }
474 #ifdef WIN32
475 #ifndef REPLACEARGS_ANSI
476     if ( PrintWin32::is_os_wide() )
477 #endif // REPLACEARGS_ANSI
478     {
479         // If the call fails, we'll need to convert charsets
480         needToRecodeParams = !replaceArgs( argc, argv );
481     }
482 #endif // WIN32
484     /// \todo  Should this be a static object (see inkscape.cpp)?
485     Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
487     return app.run();
490 void fixupSingleFilename( gchar **orig, gchar **spare )
492     if ( orig && *orig && **orig ) {
493         GError *error = NULL;
494         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
495         if ( newFileName )
496         {
497             *orig = newFileName;
498             if ( spare ) {
499                 *spare = newFileName;
500             }
501 //             g_message("Set a replacement fixup");
502         }
503     }
506 GSList *fixupFilenameEncoding( GSList* fl )
508     GSList *newFl = NULL;
509     while ( fl ) {
510         gchar *fn = static_cast<gchar*>(fl->data);
511         fl = g_slist_remove( fl, fl->data );
512         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
513         if ( newFileName ) {
515             if ( 0 )
516             {
517                 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
518                 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
519                 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
520                                                        "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
521                 gtk_dialog_run (GTK_DIALOG (w));
522                 gtk_widget_destroy (w);
523                 g_free(safeNewFn);
524                 g_free(safeFn);
525             }
527             g_free( fn );
528             fn = newFileName;
529             newFileName = 0;
530         }
531         else
532             if ( 0 )
533         {
534             gchar *safeFn = Inkscape::IO::sanitizeString(fn);
535             GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
536             gtk_dialog_run (GTK_DIALOG (w));
537             gtk_widget_destroy (w);
538             g_free(safeFn);
539         }
540         newFl = g_slist_append( newFl, fn );
541     }
542     return newFl;
545 int sp_common_main( int argc, char const **argv, GSList **flDest )
547     /// \todo fixme: Move these to some centralized location (Lauris)
548     sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
549     sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
552     // temporarily switch gettext encoding to locale, so that help messages can be output properly
553     gchar const *charset;
554     g_get_charset(&charset);
556     bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
558     poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
559     poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
560     g_return_val_if_fail(ctx != NULL, 1);
562     /* Collect own arguments */
563     GSList *fl = sp_process_args(ctx);
564     poptFreeContext(ctx);
566     // now switch gettext back to UTF-8 (for GUI)
567     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
569     // Now let's see if the file list still holds up
570     if ( needToRecodeParams )
571     {
572         fl = fixupFilenameEncoding( fl );
573     }
575     // Check the globals for filename-fixup
576     if ( needToRecodeParams )
577     {
578         fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
579         fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
580         fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
581     }
582     else
583     {
584         if ( sp_export_png )
585             sp_export_png_utf8 = g_strdup( sp_export_png );
586         if ( sp_export_svg )
587             sp_export_svg_utf8 = g_strdup( sp_export_svg );
588         if ( sp_global_printer )
589             sp_global_printer_utf8 = g_strdup( sp_global_printer );
590     }
592     // Return the list if wanted, else free it up.
593     if ( flDest ) {
594         *flDest = fl;
595         fl = 0;
596     } else {
597         while ( fl ) {
598             g_free( fl->data );
599             fl = g_slist_remove( fl, fl->data );
600         }
601     }
602     return 0;
605 int
606 sp_main_gui(int argc, char const **argv)
608     Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
610     GSList *fl = NULL;
611     int retVal = sp_common_main( argc, argv, &fl );
612     g_return_val_if_fail(retVal == 0, 1);
614     inkscape_gtk_stock_init();
616     /* Set default icon */
617     gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
618     if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
619         gtk_window_set_default_icon_from_file(filename, NULL);
620     }
621     g_free (filename);
622     filename = 0;
624     if (!sp_global_slideshow) {
625         gboolean create_new = TRUE;
627         /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
628         inkscape_application_init(argv[0], true);
630         while (fl) {
631             if (sp_file_open((gchar *)fl->data,NULL)) {
632                 create_new=FALSE;
633             }
634             fl = g_slist_remove(fl, fl->data);
635         }
636         if (create_new) {
637             sp_file_new_default();
638         }
639     } else {
640         if (fl) {
641             GtkWidget *ss;
642             /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
643             inkscape_application_init(argv[0], true);
644             ss = sp_slideshow_new(fl);
645             if (ss) gtk_widget_show(ss);
646         } else {
647             g_warning ("No slides to display");
648             exit(0);
649         }
650     }
652     main_instance.run();
654 #ifdef WIN32
655     //We might not need anything here
656     //sp_win32_finish(); <-- this is a NOP func
657 #endif
659     return 0;
662 int
663 sp_main_console(int argc, char const **argv)
665     /* We are started in text mode */
667     /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
668      * in a non-Gtk environment.  Used in libnrtype's
669      * FontInstance.cpp and FontFactory.cpp.
670      * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
671      */
672     g_type_init();
673     char **argv2 = const_cast<char **>(argv);
674     gtk_init_check( &argc, &argv2 );
675     //setlocale(LC_ALL, "");
677     GSList *fl = NULL;
678     int retVal = sp_common_main( argc, argv, &fl );
679     g_return_val_if_fail(retVal == 0, 1);
681     if (fl == NULL) {
682         g_print("Nothing to do!\n");
683         exit(0);
684     }
686     inkscape_application_init(argv[0], false);
688     while (fl) {
689         SPDocument *doc;
691         doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
692         if (doc == NULL) {
693             doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
694         }
695         if (doc == NULL) {
696             g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
697         } else {
698             if (sp_vacuum_defs) {
699                 vacuum_document(doc);
700             }
701             if (sp_vacuum_defs && !sp_export_svg) {
702                 // save under the name given in the command line
703                 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
704             }
705             if (sp_global_printer) {
706                 sp_print_document_to_file(doc, sp_global_printer);
707             }
708             if (sp_export_png || sp_export_id || sp_export_area_drawing) {
709                 sp_do_export_png(doc);
710             }
711             if (sp_export_svg) {
712                 Inkscape::XML::Document *rdoc;
713                 Inkscape::XML::Node *repr;
714                 rdoc = sp_repr_document_new("svg:svg");
715                 repr = rdoc->root();
716                 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
717                 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
718             }
719             if (sp_export_ps) {
720                 do_export_ps(doc, sp_export_ps, "image/x-postscript");
721             }
722             if (sp_export_eps) {
723                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
724             }
725             if (sp_export_pdf) {
726                 do_export_pdf(doc, sp_export_pdf, "application/pdf");
727             }
728             if (sp_query_width || sp_query_height) {
729                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
730             } else if (sp_query_x || sp_query_y) {
731                 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
732             }
733         }
734         fl = g_slist_remove(fl, fl->data);
735     }
737     inkscape_unref();
739     return 0;
742 static void
743 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
745     SPObject *o = NULL;
747     if (id) {
748         o = doc->getObjectById(id);
749         if (o) {
750             if (!SP_IS_ITEM (o)) {
751                 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
752                 return;
753             }
754         } else {
755             g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
756             return;
757         }
758     } else {
759         o = SP_DOCUMENT_ROOT(doc);
760     }
762     if (o) {
763         sp_document_ensure_up_to_date (doc);
764         SPItem *item = ((SPItem *) o);
765         NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
767         Inkscape::SVGOStringStream os;
768         if (extent) {
769             os << area.extent(axis);
770         } else {
771             os << area.min()[axis];
772         }
773         g_print ("%s", os.str().c_str());
774     }
778 static void
779 sp_do_export_png(SPDocument *doc)
781     const gchar *filename = NULL;
782     gdouble dpi = 0.0;
784     if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
785         g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
786     }
788     GSList *items = NULL;
790     NRRect area;
791     if (sp_export_id || sp_export_area_drawing) {
793         SPObject *o = NULL;
794         SPObject *o_area = NULL;
795         if (sp_export_id && sp_export_area_drawing) {
796             o = doc->getObjectById(sp_export_id);
797             o_area = SP_DOCUMENT_ROOT (doc);
798         } else if (sp_export_id) {
799             o = doc->getObjectById(sp_export_id);
800             o_area = o;
801         } else if (sp_export_area_drawing) {
802             o = SP_DOCUMENT_ROOT (doc);
803             o_area = o;
804         } 
806         if (o) {
807             if (!SP_IS_ITEM (o)) {
808                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
809                 return;
810             }
812             items = g_slist_prepend (items, SP_ITEM(o));
814             if (sp_export_id_only) {
815                 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
816             }
818             if (sp_export_use_hints) {
820                 // retrieve export filename hint
821                 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
822                 if (fn_hint) {
823                     if (sp_export_png) {
824                         g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
825                         filename = sp_export_png;
826                     } else {
827                         filename = fn_hint;
828                     }
829                 } else {
830                     g_warning ("Export filename hint not found for the object.");
831                     filename = sp_export_png;
832                 }
834                 // retrieve export dpi hints
835                 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
836                 if (dpi_hint) {
837                     if (sp_export_dpi || sp_export_width || sp_export_height) {
838                         g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
839                     } else {
840                         dpi = atof(dpi_hint);
841                     }
842                 } else {
843                     g_warning ("Export DPI hint not found for the object.");
844                 }
846             }
848             // write object bbox to area
849             sp_document_ensure_up_to_date (doc);
850             sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
851         } else {
852             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
853             return;
854         }
855     }
856     
857     if (sp_export_area) {
858         /* Try to parse area (given in SVG pixels) */
859         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
860             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
861             return;
862         }
863         if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
864             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
865             return;
866         }
867     } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
868         /* Export the whole canvas */
869         sp_document_ensure_up_to_date (doc);
870         area.x0 = SP_ROOT(doc->root)->x.computed;
871         area.y0 = SP_ROOT(doc->root)->y.computed;
872         area.x1 = area.x0 + sp_document_width (doc);
873         area.y1 = area.y0 + sp_document_height (doc);
874     }
876     // set filename and dpi from options, if not yet set from the hints
877     if (!filename) {
878         if (!sp_export_png) {
879             g_warning ("No export filename given and no filename hint. Nothing exported.");
880             return;
881         }
882         filename = sp_export_png;
883     }
885     if (sp_export_dpi && dpi == 0.0) {
886         dpi = atof(sp_export_dpi);
887         if ((dpi < 0.1) || (dpi > 10000.0)) {
888             g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
889             return;
890         }
891         g_print("DPI: %g\n", dpi);
892     }
894     if (sp_export_area_snap) {
895         area.x0 = std::floor (area.x0);
896         area.y0 = std::floor (area.y0);
897         area.x1 = std::ceil (area.x1);
898         area.y1 = std::ceil (area.y1);
899     }
901     // default dpi
902     if (dpi == 0.0)
903         dpi = PX_PER_IN;
905     gint width = 0;
906     gint height = 0;
908     if (sp_export_width) {
909         width = atoi(sp_export_width);
910         if ((width < 1) || (width > 65536)) {
911             g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
912             return;
913         }
914         dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
915     }
917     if (sp_export_height) {
918         height = atoi(sp_export_height);
919         if ((height < 1) || (height > 65536)) {
920             g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
921             return;
922         }
923         dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
924     }
926     if (!sp_export_width) {
927         width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
928     }
930     if (!sp_export_height) {
931         height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
932     }
934     guint32 bgcolor = 0x00000000;
935     if (sp_export_background) {
936         // override the page color
937         bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
938         bgcolor |= 0xff; // default is no opacity
939     } else {
940         // read from namedview
941         Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
942         if (nv && nv->attribute("pagecolor"))
943             bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
944         if (nv && nv->attribute("inkscape:pageopacity"))
945             bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
946     }
948     if (sp_export_background_opacity) {
949         // override opacity
950         gfloat value;
951         if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
952             if (value > 1.0) {
953                 value = CLAMP (value, 1.0f, 255.0f);
954                 bgcolor &= (guint32) 0xffffff00;
955                 bgcolor |= (guint32) floor(value);
956             } else {
957                 value = CLAMP (value, 0.0f, 1.0f);
958                 bgcolor &= (guint32) 0xffffff00;
959                 bgcolor |= SP_COLOR_F_TO_U(value);
960             }
961         }
962     }
964     g_print("Background RRGGBBAA: %08x\n", bgcolor);
966     g_print("Area %g:%g:%g:%g exported to %d x %d pixels (%g dpi)\n", area.x0, area.y0, area.x1, area.y1, width, height, dpi);
968     g_print("Bitmap saved as: %s\n", filename);
970     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
971         sp_export_png_file(doc, filename, area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL);
972     } else {
973         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
974     }
976     g_slist_free (items);
980 /**
981  *  Perform an export of either PS or EPS.
982  *
983  *  \param doc Document to export.
984  *  \param uri URI to export to.
985  *  \param mime MIME type to export as.
986  */
988 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
990     Inkscape::Extension::DB::OutputList o;
991     Inkscape::Extension::db.get_output_list(o);
992     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
993     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
994         i++;
995     }
997     if (i == o.end())
998     {
999         g_warning ("Could not find an extension to export this file.");
1000         return;
1001     }
1003     bool old_text_to_path = false;
1004     bool old_bbox_page = false;
1006     try {
1007         old_text_to_path = (*i)->get_param_bool("textToPath");
1008         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1009     }
1010     catch (...) {
1011         g_warning ("Could not set export-text-to-path option for this export.");
1012     }
1014     try {
1015         old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1016         (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1017     }
1018     catch (...) {
1019         g_warning ("Could not set export-bbox-page option for this export.");
1020     }
1022     (*i)->save(doc, uri);
1024     try {
1025         (*i)->set_param_bool("textToPath", old_text_to_path);
1026         (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1027     }
1028     catch (...) {
1030     }
1033 /**
1034  *  Perform a PDF export
1035  *
1036  *  \param doc Document to export.
1037  *  \param uri URI to export to.
1038  *  \param mime MIME type to export as.
1039  */
1041 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1043     Inkscape::Extension::DB::OutputList o;
1044     Inkscape::Extension::db.get_output_list(o);
1045     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1046     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1047         i++;
1048     }
1050     if (i == o.end())
1051     {
1052         g_warning ("Could not find an extension to export this file.");
1053         return;
1054     }
1056     bool old_text_to_path = false;
1058     try {
1059         old_text_to_path = (*i)->get_param_bool("textToPath");
1060         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1061     }
1062     catch (...) {
1063         g_warning ("Could not set export-text-to-path option for this export.");
1064     }
1066     (*i)->save(doc, uri);
1068     try {
1069         (*i)->set_param_bool("textToPath", old_text_to_path);
1070     }
1071     catch (...) {
1073     }
1076 #ifdef WIN32
1077 bool replaceArgs( int& argc, char**& argv )
1079     bool worked = false;
1081 #ifdef REPLACEARGS_DEBUG
1082     MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1083 #endif // REPLACEARGS_DEBUG
1085     wchar_t* line = GetCommandLineW();
1086     if ( line )
1087     {
1088 #ifdef REPLACEARGS_DEBUG
1089         {
1090             gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1091             if ( utf8Line )
1092             {
1093                 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1094                 {
1095                     char tmp[strlen(safe) + 32];
1096                     snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1097                     MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1098                 }
1099             }
1100         }
1101 #endif // REPLACEARGS_DEBUG
1103         int numArgs = 0;
1104         wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1106 #ifdef REPLACEARGS_ANSI
1107 // test code for trying things on Win95/98/ME
1108         if ( !parsed )
1109         {
1110 #ifdef REPLACEARGS_DEBUG
1111             MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1112 #endif // REPLACEARGS_DEBUG
1113             int lineLen = wcslen(line) + 1;
1114             wchar_t* lineDup = new wchar_t[lineLen];
1115             wcsncpy( lineDup, line, lineLen );
1117             int pos = 0;
1118             bool inQuotes = false;
1119             bool inWhitespace = true;
1120             std::vector<int> places;
1121             while ( lineDup[pos] )
1122             {
1123                 if ( inQuotes )
1124                 {
1125                     if ( lineDup[pos] == L'"' )
1126                     {
1127                         inQuotes = false;
1128                     }
1129                 }
1130                 else if ( lineDup[pos] == L'"' )
1131                 {
1132                     inQuotes = true;
1133                     inWhitespace = false;
1134                     places.push_back(pos);
1135                 }
1136                 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1137                 {
1138                     if ( !inWhitespace )
1139                     {
1140                         inWhitespace = true;
1141                         lineDup[pos] = 0;
1142                     }
1143                 }
1144                 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1145                 {
1146                     inWhitespace = false;
1147                     places.push_back(pos);
1148                 }
1149                 else
1150                 {
1151                     // consume
1152                 }
1153                 pos++;
1154             }
1155 #ifdef REPLACEARGS_DEBUG
1156             {
1157                 char tmp[256];
1158                 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1159                 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1160             }
1161 #endif // REPLACEARGS_DEBUG
1163             wchar_t** block = new wchar_t*[places.size()];
1164             int i = 0;
1165             for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1166             {
1167                 block[i++] = &lineDup[*it];
1168             }
1169             parsed = block;
1170             numArgs = places.size();
1171         }
1172 #endif // REPLACEARGS_ANSI
1174         if ( parsed )
1175         {
1176             std::vector<wchar_t*>expandedArgs;
1177             if ( numArgs > 0 )
1178             {
1179                 expandedArgs.push_back( parsed[0] );
1180             }
1182             for ( int i1 = 1; i1 < numArgs; i1++ )
1183             {
1184                 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1185                 wildcarded &= parsed[i1][0] != L'"';
1186                 wildcarded &= parsed[i1][0] != L'-';
1187                 if ( wildcarded )
1188                 {
1189 #ifdef REPLACEARGS_ANSI
1190                     WIN32_FIND_DATAA data = {0};
1191 #else
1192                     WIN32_FIND_DATAW data = {0};
1193 #endif // REPLACEARGS_ANSI
1195                     int baseLen = wcslen(parsed[i1]) + 2;
1196                     wchar_t* base = new wchar_t[baseLen];
1197                     wcsncpy( base, parsed[i1], baseLen );
1198                     wchar_t* last = wcsrchr( base, L'\\' );
1199                     if ( last )
1200                     {
1201                         last[1] = 0;
1202                     }
1203                     else
1204                     {
1205                         base[0] = 0;
1206                     }
1207                     baseLen = wcslen( base );
1209 #ifdef REPLACEARGS_ANSI
1210                     char target[MAX_PATH];
1211                     if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1212                     {
1213                         HANDLE hf = FindFirstFileA( target, &data );
1214 #else
1215                         HANDLE hf = FindFirstFileW( parsed[i1], &data );
1216 #endif // REPLACEARGS_ANSI
1217                         if ( hf != INVALID_HANDLE_VALUE )
1218                         {
1219                             BOOL found = TRUE;
1220                             do
1221                             {
1222 #ifdef REPLACEARGS_ANSI
1223                                 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1224                                 if ( howMany > 0 )
1225                                 {
1226                                     howMany += baseLen;
1227                                     wchar_t* tmp = new wchar_t[howMany + 1];
1228                                     wcsncpy( tmp, base, howMany + 1 );
1229                                     MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1230                                     expandedArgs.push_back( tmp );
1231                                     found = FindNextFileA( hf, &data );
1232                                 }
1233 #else
1234                                 int howMany = wcslen(data.cFileName) + baseLen;
1235                                 wchar_t* tmp = new wchar_t[howMany + 1];
1236                                 wcsncpy( tmp, base, howMany + 1 );
1237                                 wcsncat( tmp, data.cFileName, howMany + 1 );
1238                                 expandedArgs.push_back( tmp );
1239                                 found = FindNextFileW( hf, &data );
1240 #endif // REPLACEARGS_ANSI
1241                             } while ( found );
1243                             FindClose( hf );
1244                         }
1245                         else
1246                         {
1247                             expandedArgs.push_back( parsed[i1] );
1248                         }
1249 #ifdef REPLACEARGS_ANSI
1250                     }
1251 #endif // REPLACEARGS_ANSI
1253                     delete[] base;
1254                 }
1255                 else
1256                 {
1257                     expandedArgs.push_back( parsed[i1] );
1258                 }
1259             }
1261             {
1262                 wchar_t** block = new wchar_t*[expandedArgs.size()];
1263                 int iz = 0;
1264                 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1265                 {
1266                     block[iz++] = *it;
1267                 }
1268                 parsed = block;
1269                 numArgs = expandedArgs.size();
1270             }
1272             std::vector<gchar*> newArgs;
1273             for ( int i = 0; i < numArgs; i++ )
1274             {
1275                 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1276                 if ( replacement )
1277                 {
1278 #ifdef REPLACEARGS_DEBUG
1279                     gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1281                     if ( safe2 )
1282                     {
1283                         {
1284                             char tmp[1024];
1285                             snprintf( tmp, sizeof(tmp), "    [%2d] = '%s'", i, safe2 );
1286                             MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1287                         }
1288                         g_free( safe2 );
1289                     }
1290 #endif // REPLACEARGS_DEBUG
1292                     newArgs.push_back( replacement );
1293                 }
1294                 else
1295                 {
1296                     newArgs.push_back( blankParam );
1297                 }
1298             }
1300             // Now push our munged params to be the new argv and argc
1301             {
1302                 char** block = new char*[newArgs.size()];
1303                 int iz = 0;
1304                 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1305                 {
1306                     block[iz++] = *it;
1307                 }
1308                 argv = block;
1309                 argc = newArgs.size();
1310                 worked = true;
1311             }
1312         }
1313 #ifdef REPLACEARGS_DEBUG
1314         else
1315         {
1316             MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1317         }
1318 #endif // REPLACEARGS_DEBUG
1319     }
1320 #ifdef REPLACEARGS_DEBUG
1321     else
1322     {
1323         {
1324             MessageBoxA( NULL,  "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1325         }
1327         char* line2 = GetCommandLineA();
1328         if ( line2 )
1329         {
1330             gchar *safe = Inkscape::IO::sanitizeString(line2);
1331             {
1332                 {
1333                     char tmp[strlen(safe) + 32];
1334                     snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1335                     MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1336                 }
1337             }
1338         }
1339         else
1340         {
1341             MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1342         }
1343     }
1344 #endif // REPLACEARGS_DEBUG
1346     return worked;
1348 #endif // WIN32
1350 static GSList *
1351 sp_process_args(poptContext ctx)
1353     GSList *fl = NULL;
1355     gint a;
1356     while ((a = poptGetNextOpt(ctx)) >= 0) {
1357         switch (a) {
1358             case SP_ARG_FILE: {
1359                 gchar const *fn = poptGetOptArg(ctx);
1360                 if (fn != NULL) {
1361                     fl = g_slist_append(fl, g_strdup(fn));
1362                 }
1363                 break;
1364             }
1365             case SP_ARG_VERSION: {
1366                 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1367                 exit(0);
1368                 break;
1369             }
1370             case SP_ARG_EXTENSIONDIR: {
1371                 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1372                 exit(0);
1373                 break;
1374             }
1375             default: {
1376                 break;
1377             }
1378         }
1379     }
1381     gchar const ** const args = poptGetArgs(ctx);
1382     if (args != NULL) {
1383         for (unsigned i = 0; args[i] != NULL; i++) {
1384             fl = g_slist_append(fl, g_strdup(args[i]));
1385         }
1386     }
1388     return fl;
1392 /*
1393   Local Variables:
1394   mode:c++
1395   c-file-style:"stroustrup"
1396   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1397   indent-tabs-mode:nil
1398   fill-column:99
1399   End:
1400 */
1401 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :